1 /*
  2  * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_JVMCI_JVMCIENV_HPP
 26 #define SHARE_JVMCI_JVMCIENV_HPP
 27 
 28 #include "classfile/javaClasses.hpp"
 29 #include "jvmci/jvmciJavaClasses.hpp"
 30 #include "oops/klass.hpp"
 31 #include "runtime/javaThread.hpp"
 32 #include "runtime/jniHandles.hpp"
 33 
 34 class CompileTask;
 35 class JVMCIObject;
 36 class JVMCIObjectArray;
 37 class JVMCIPrimitiveArray;
 38 class JVMCICompiler;
 39 class JVMCIRuntime;
 40 
 41 #define JVMCI_EXCEPTION_CONTEXT \
 42   JavaThread* thread = JavaThread::current(); \
 43   JavaThread* THREAD = thread; // For exception macros.
 44 
 45 // Helper to log more context on a JNI exception
 46 #define JVMCI_EXCEPTION_CHECK(env, ...) \
 47   do { \
 48     if (env->ExceptionCheck()) { \
 49       if (env != JavaThread::current()->jni_environment()) { \
 50         char* sl_path; \
 51         if (::JVMCI::get_shared_library(sl_path, false) != nullptr) { \
 52           tty->print_cr("In JVMCI shared library (%s):", sl_path); \
 53         } \
 54       } \
 55       tty->print_cr(__VA_ARGS__); \
 56       return; \
 57     } \
 58   } while(0)
 59 
 60 // Helper class to ensure that references to Klass* are kept alive for G1
 61 class JVMCIKlassHandle : public StackObj {
 62  private:
 63   Klass*     _klass;
 64   Handle     _holder;
 65   Thread*    _thread;
 66 
 67   Klass*        klass() const                     { return _klass; }
 68   Klass*        non_null_klass() const            { assert(_klass != nullptr, "resolving null _klass"); return _klass; }
 69 
 70  public:
 71   /* Constructors */
 72   JVMCIKlassHandle (Thread* thread) : _klass(nullptr), _thread(thread) {}
 73   JVMCIKlassHandle (Thread* thread, Klass* klass);
 74 
 75   JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}
 76   JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);
 77   JVMCIKlassHandle& operator=(Klass* klass);
 78 
 79   /* Operators for ease of use */
 80   Klass*        operator () () const            { return klass(); }
 81   Klass*        operator -> () const            { return non_null_klass(); }
 82 
 83   bool    operator == (Klass* o) const          { return klass() == o; }
 84   bool    operator == (const JVMCIKlassHandle& h) const  { return klass() == h.klass(); }
 85 
 86   /* Null checks */
 87   bool    is_null() const                      { return _klass == nullptr; }
 88   bool    not_null() const                     { return _klass != nullptr; }
 89 };
 90 
 91 // A helper class to main a strong link to an nmethod that might not otherwise be referenced.  Only
 92 // one nmethod can be kept alive in this manner.
 93 class JVMCINMethodHandle : public StackObj {
 94   JavaThread* _thread;
 95 
 96  public:
 97   JVMCINMethodHandle(JavaThread* thread): _thread(thread) {}
 98 
 99   void set_nmethod(nmethod* nm);
100 
101   ~JVMCINMethodHandle() {
102     _thread->clear_live_nmethod();
103   }
104 };
105 
106 // A class that maintains the state needed for compilations requested
107 // by the CompileBroker.  It is created in the broker and passed through
108 // into the code installation step.
109 class JVMCICompileState : public ResourceObj {
110   friend class JVMCIVMStructs;
111  private:
112   CompileTask*     _task;
113   JVMCICompiler*   _compiler;
114 
115   // Cache JVMTI state. Defined as bytes so that reading them from Java
116   // via Unsafe is well defined (the C++ type for bool is implementation
117   // defined and may not be the same as a Java boolean).
118   uint64_t _jvmti_redefinition_count;
119   jbyte  _jvmti_can_hotswap_or_post_breakpoint;
120   jbyte  _jvmti_can_access_local_variables;
121   jbyte  _jvmti_can_post_on_exceptions;
122   jbyte  _jvmti_can_pop_frame;
123   bool   _target_method_is_old;
124 
125   // Compilation result values.
126   bool             _retryable;
127   const char*      _failure_reason;
128 
129   // Specifies if _failure_reason is on the C heap. If so, it is allocated
130   // with the mtJVMCI NMT flag.
131   bool             _failure_reason_on_C_heap;
132 
133   // A value indicating compilation activity during the compilation.
134   // If successive calls to this method return a different value, then
135   // some degree of JVMCI compilation occurred between the calls.
136   jint             _compilation_ticks;
137 
138  public:
139   JVMCICompileState(CompileTask* task, JVMCICompiler* compiler);
140 
141   CompileTask* task() { return _task; }
142 
143   bool  jvmti_state_changed() const;
144   uint64_t jvmti_redefinition_count() const          { return  _jvmti_redefinition_count; }
145   bool  jvmti_can_hotswap_or_post_breakpoint() const { return  _jvmti_can_hotswap_or_post_breakpoint != 0; }
146   bool  jvmti_can_access_local_variables() const     { return  _jvmti_can_access_local_variables != 0; }
147   bool  jvmti_can_post_on_exceptions() const         { return  _jvmti_can_post_on_exceptions != 0; }
148   bool  jvmti_can_pop_frame() const                  { return  _jvmti_can_pop_frame != 0; }
149   bool  target_method_is_old() const                 { return  _target_method_is_old; }
150 
151   const char* failure_reason() { return _failure_reason; }
152   bool failure_reason_on_C_heap() { return _failure_reason_on_C_heap; }
153   bool retryable() { return _retryable; }
154 
155   void set_failure(bool retryable, const char* reason, bool reason_on_C_heap = false);
156 
157   // Called when creating or attaching to a libjvmci isolate failed
158   // due to an out of memory condition.
159   void notify_libjvmci_oome();
160 
161   jint compilation_ticks() const { return _compilation_ticks; }
162   void inc_compilation_ticks();
163 };
164 
165 // This class is a top level wrapper around interactions between HotSpot
166 // and the JVMCI Java code.  It supports both a HotSpot heap based
167 // runtime with HotSpot oop based accessors as well as a shared library
168 // based runtime that is accessed through JNI. It abstracts away all
169 // interactions with JVMCI objects so that a single version of the
170 // HotSpot C++ code can can work with either runtime.
171 class JVMCIEnv : public ResourceObj {
172   friend class JNIAccessMark;
173 
174   // Initializes the _env, _mode and _runtime fields.
175   void init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env);
176 
177   void init(JavaThread* thread, bool is_hotspot, const char* file, int line);
178 
179   JNIEnv*                 _env;  // JNI env for calling into shared library
180   bool     _pop_frame_on_close;  // Must pop frame on close?
181   bool        _detach_on_close;  // Must detach on close?
182   JVMCIRuntime*       _runtime;  // Access to a HotSpotJVMCIRuntime
183   bool             _is_hotspot;  // Which heap is the HotSpotJVMCIRuntime in
184   bool        _throw_to_caller;  // Propagate an exception raised in this env to the caller?
185   const char*            _file;  // The file and ...
186   int                    _line;  // ... line where this JNIEnv was created
187   int              _init_error;  // JNI code returned when creating or attaching to a libjvmci isolate.
188                                  // If not JNI_OK, the JVMCIEnv is invalid and should not be used apart from
189                                  // calling init_error().
190   const char*  _init_error_msg;  // Message for _init_error if available. C heap allocated.
191 
192   // Translates an exception on the HotSpot heap (i.e., hotspot_env) to an exception on
193   // the shared library heap (i.e., jni_env). The translation includes the stack and cause(s) of `throwable`.
194   // The translated exception is pending in jni_env upon returning.
195   static void translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);
196 
197   // Translates an exception on the shared library heap (i.e., jni_env) to an exception on
198   // the HotSpot heap (i.e., hotspot_env). The translation includes the stack and cause(s) of `throwable`.
199   // The translated exception is pending in hotspot_env upon returning.
200   static void translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);
201 
202 public:
203   // Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).
204   // The `parent_env` argument must not be null.
205   // An exception occurring within the scope is left pending when the
206   // scope closes so that it will be propagated back to Java.
207   // The JVMCIEnv destructor translates the exception object for the
208   // Java runtime if necessary.
209   JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line);
210 
211   // Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker.
212   // An exception occurring within the scope must not be propagated back to
213   // the CompileBroker.
214   JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line);
215 
216   // Opens a JNIEnv scope for a call from within the VM. An exception occurring
217   // within the scope must not be propagated back to the caller.
218   JVMCIEnv(JavaThread* env, const char* file, int line);
219 
220   // Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true
221   // otherwise for the shared library runtime. An exception occurring
222   // within the scope must not be propagated back to the caller.
223   JVMCIEnv(JavaThread* thread, bool is_hotspot, const char* file, int line) {
224     init(thread, is_hotspot, file, line);
225   }
226 
227   ~JVMCIEnv();
228 
229   // Gets the JNI result code returned when creating or attaching to a libjvmci isolate.
230   // If not JNI_OK, the JVMCIEnv is invalid and the caller must abort the operation
231   // this JVMCIEnv context was created for.
232   int init_error() {
233     return _init_error;
234   }
235 
236   // Gets a message describing a non-zero init_error().
237   // Valid as long as this JVMCIEnv is valid.
238   const char* init_error_msg() {
239     return _init_error_msg;
240   }
241 
242   // Checks the value of init_error() and throws an exception in `JVMCI_TRAPS`
243   // (which must not be this) if it is not JNI_OK.
244   void check_init(JVMCI_TRAPS);
245 
246   // Checks the value of init_error() and throws an exception in `TRAPS`
247   // if it is not JNI_OK.
248   void check_init(TRAPS);
249 
250   JVMCIRuntime* runtime() {
251     guarantee(_init_error == 0, "invalid JVMCIEnv: %d", _init_error);
252     return _runtime;
253   }
254 
255   jboolean has_pending_exception();
256   void clear_pending_exception();
257 
258   // If this env has a pending exception, it is translated to be a pending
259   // exception in `peer_env` and is cleared from this env. Returns true
260   // if a pending exception was transferred, false otherwise.
261   jboolean transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env);
262 
263   // If there is a pending HotSpot exception, clears it and translates it to the shared library heap.
264   // The translated exception is pending in the shared library upon returning.
265   // Returns true if a pending exception was transferred, false otherwise.
266   static jboolean transfer_pending_exception_to_jni(JavaThread* THREAD, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);
267 
268   // Prints the stack trace of a pending exception to `st` and clears the exception.
269   // If there is no pending exception, this is a nop.
270   void describe_pending_exception(outputStream* st);
271 
272   // Gets the output of calling toString and/or printStactTrace on the pending exception.
273   // If to_string is not null, the output of toString is returned in it.
274   // If stack_trace is not null, the output of printStackTrace is returned in it.
275   // Returns false if there is no pending exception otherwise clears the pending
276   // exception and returns true.
277   bool pending_exception_as_string(const char** to_string, const char** stack_trace);
278 
279   int get_length(JVMCIArray array);
280 
281   JVMCIObject get_object_at(JVMCIObjectArray array, int index);
282   void put_object_at(JVMCIObjectArray array, int index, JVMCIObject value);
283 
284   jboolean get_bool_at(JVMCIPrimitiveArray array, int index);
285   void put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value);
286 
287   jbyte get_byte_at(JVMCIPrimitiveArray array, int index);
288   void put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value);
289 
290   jint get_int_at(JVMCIPrimitiveArray array, int index);
291   void put_int_at(JVMCIPrimitiveArray array, int index, jint value);
292 
293   jlong get_long_at(JVMCIPrimitiveArray array, int index);
294   void put_long_at(JVMCIPrimitiveArray array, int index, jlong value);
295 
296   void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length);
297   void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length);
298 
299   void copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length);
300 
301   JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);
302 
303   jboolean is_boxing_object(BasicType type, JVMCIObject object);
304 
305   // Get the primitive value from a Java boxing object.  It's hard error to
306   // pass a non-primitive BasicType.
307   jvalue get_boxed_value(BasicType type, JVMCIObject object);
308 
309   // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
310   BasicType get_box_type(JVMCIObject object);
311 
312   // Create a boxing object of the appropriate primitive type.
313   JVMCIObject create_box(BasicType type, jvalue* value, JVMCI_TRAPS);
314 
315   const char* as_utf8_string(JVMCIObject str);
316 
317   JVMCIObject create_string(Symbol* str, JVMCI_TRAPS) {
318     JVMCIObject s = create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject()));
319     return s;
320   }
321 
322   JVMCIObject create_string(const char* str, JVMCI_TRAPS);
323 
324   bool equals(JVMCIObject a, JVMCIObject b);
325 
326   // Convert into a JNI handle for the appropriate runtime
327   jobject get_jobject(JVMCIObject object)                       { assert(object.as_jobject() == nullptr || is_hotspot() == object.is_hotspot(), "mismatch"); return object.as_jobject(); }
328   jarray get_jarray(JVMCIArray array)                           { assert(array.as_jobject() == nullptr || is_hotspot() == array.is_hotspot(), "mismatch"); return array.as_jobject(); }
329   jobjectArray get_jobjectArray(JVMCIObjectArray objectArray)   { assert(objectArray.as_jobject() == nullptr || is_hotspot() == objectArray.is_hotspot(), "mismatch"); return objectArray.as_jobject(); }
330   jbyteArray get_jbyteArray(JVMCIPrimitiveArray primitiveArray) { assert(primitiveArray.as_jobject() == nullptr || is_hotspot() == primitiveArray.is_hotspot(), "mismatch"); return primitiveArray.as_jbyteArray(); }
331 
332   JVMCIObject         wrap(jobject obj);
333   JVMCIObjectArray    wrap(jobjectArray obj)  { return (JVMCIObjectArray)    wrap((jobject) obj); }
334   JVMCIPrimitiveArray wrap(jintArray obj)     { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
335   JVMCIPrimitiveArray wrap(jbooleanArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
336   JVMCIPrimitiveArray wrap(jbyteArray obj)    { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
337   JVMCIPrimitiveArray wrap(jlongArray obj)    { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
338 
339   nmethod* lookup_nmethod(address code, jlong compile_id_snapshot);
340 
341  private:
342   JVMCIObject wrap(oop obj)                  { assert(is_hotspot(), "must be"); return wrap(JNIHandles::make_local(obj)); }
343   JVMCIObjectArray wrap(objArrayOop obj)     { assert(is_hotspot(), "must be"); return (JVMCIObjectArray) wrap(JNIHandles::make_local(obj)); }
344   JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }
345 
346  public:
347   // Compiles a method with the JVMCI compiler.
348   // Caller must handle pending exception.
349   JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,
350                                                      jlong compile_state, int id);
351 
352   void call_HotSpotJVMCIRuntime_bootstrapFinished(JVMCIObject runtime, JVMCI_TRAPS);
353   void call_HotSpotJVMCIRuntime_shutdown(JVMCIObject runtime);
354   JVMCIObject call_HotSpotJVMCIRuntime_runtime(JVMCI_TRAPS);
355   JVMCIObject call_JVMCI_getRuntime(JVMCI_TRAPS);
356   JVMCIObject call_HotSpotJVMCIRuntime_getCompiler(JVMCIObject runtime, JVMCI_TRAPS);
357 
358   JVMCIObject call_JavaConstant_forPrimitive(jchar type_char, jlong value, JVMCI_TRAPS);
359 
360   jboolean call_HotSpotJVMCIRuntime_isGCSupported(JVMCIObject runtime, jint gcIdentifier);
361 
362   jboolean call_HotSpotJVMCIRuntime_isIntrinsicSupported(JVMCIObject runtime, jint intrinsicIdentifier);
363 
364   void call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCI_TRAPS);
365 
366   // Converts the JavaKind.typeChar value in `ch` to a BasicType
367   BasicType typeCharToBasicType(jchar ch, JVMCI_TRAPS);
368 
369   // Converts the JavaKind value in `kind` to a BasicType
370   BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS);
371 
372 #define DO_THROW(name) \
373   void throw_##name(const char* msg = nullptr);
374 
375   DO_THROW(InternalError)
376   DO_THROW(ArrayIndexOutOfBoundsException)
377   DO_THROW(IllegalStateException)
378   DO_THROW(NullPointerException)
379   DO_THROW(IllegalArgumentException)
380   DO_THROW(InvalidInstalledCodeException)
381   DO_THROW(UnsatisfiedLinkError)
382   DO_THROW(UnsupportedOperationException)
383   DO_THROW(OutOfMemoryError)
384   DO_THROW(NoClassDefFoundError)
385 
386 #undef DO_THROW
387 
388   void fthrow_error(const char* file, int line, const char* format, ...) ATTRIBUTE_PRINTF(4, 5);
389 
390   // Given an instance of HotSpotInstalledCode, return the corresponding CodeBlob*.
391   CodeBlob* get_code_blob(JVMCIObject code);
392 
393   // Given an instance of HotSpotInstalledCode, return the corresponding nmethod.
394   nmethod* get_nmethod(JVMCIObject code, JVMCINMethodHandle& nmethod_handle);
395 
396   const char* klass_name(JVMCIObject object);
397 
398   // Unpack an instance of HotSpotResolvedJavaMethodImpl into the original Method*
399   Method* asMethod(JVMCIObject jvmci_method);
400 
401   // Unpack an instance of HotSpotResolvedObjectTypeImpl into the original Klass*
402   Klass* asKlass(JVMCIObject jvmci_type);
403 
404   // Unpack an instance of HotSpotMethodData into the original MethodData*
405   MethodData* asMethodData(JVMCIObject jvmci_method_data);
406 
407   JVMCIObject get_jvmci_method(const methodHandle& method, JVMCI_TRAPS);
408 
409   JVMCIObject get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS);
410 
411   // Unpack an instance of HotSpotConstantPool into the original ConstantPool*
412   ConstantPool* asConstantPool(JVMCIObject constant_pool);
413   ConstantPool* asConstantPool(jobject constant_pool)  { return asConstantPool(wrap(constant_pool)); }
414 
415   JVMCIObject get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS);
416   JVMCIObject get_jvmci_primitive_type(BasicType type);
417 
418   Handle asConstant(JVMCIObject object, JVMCI_TRAPS);
419   JVMCIObject get_object_constant(oop objOop, bool compressed = false, bool dont_register = false);
420 
421   JVMCIPrimitiveArray new_booleanArray(int length, JVMCI_TRAPS);
422   JVMCIPrimitiveArray new_byteArray(int length, JVMCI_TRAPS);
423   JVMCIPrimitiveArray new_intArray(int length, JVMCI_TRAPS);
424   JVMCIPrimitiveArray new_longArray(int length, JVMCI_TRAPS);
425 
426   JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS);
427 
428   JVMCIObject new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS);
429   JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);
430   JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);
431   JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);
432   JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS);
433   JVMCIObject new_HotSpotStackFrameReference(JVMCI_TRAPS);
434   JVMCIObject new_JVMCIError(JVMCI_TRAPS);
435   JVMCIObject new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS);
436 
437   // Makes a handle to a HotSpot heap object. These handles are
438   // individually reclaimed by JVMCIRuntime::destroy_oop_handle and
439   // bulk reclaimed by JVMCIRuntime::release_and_clear_globals.
440   jlong make_oop_handle(const Handle& obj);
441   oop resolve_oop_handle(jlong oopHandle);
442 
443   // These are analogous to the JNI routines
444   JVMCIObject make_local(JVMCIObject object);
445   void destroy_local(JVMCIObject object);
446 
447   // Makes a JNI global handle that is not scoped by the
448   // lifetime of a JVMCIRuntime (cf JVMCIRuntime::make_global).
449   // These JNI handles are used when translating an object
450   // between the HotSpot and JVMCI shared library heap via
451   // HotSpotJVMCIRuntime.translate(Object) and
452   // HotSpotJVMCIRuntime.unhand(Class<T>, long). Translation
453   // can happen in either direction so the referenced object
454   // can reside in either heap which is why JVMCIRuntime scoped
455   // handles cannot be used (they are specific to HotSpot heap objects).
456   JVMCIObject make_global(JVMCIObject object);
457 
458   // Destroys a JNI global handle created by JVMCIEnv::make_global.
459   void destroy_global(JVMCIObject object);
460 
461   // Updates the nmethod (if any) in the HotSpotNmethod.address
462   // field of `mirror` to prevent it from being called.
463   // If `deoptimize` is true, the nmethod is immediately deoptimized.
464   // The HotSpotNmethod.address field is zero upon returning.
465   void invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimze, nmethod::InvalidationReason invalidation_reason, JVMCI_TRAPS);
466 
467   void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS);
468 
469  private:
470   JVMCICompileState* _compile_state;
471 
472  public:
473 
474   // Determines if this is for the JVMCI runtime in the HotSpot
475   // heap (true) or the shared library heap (false).
476   bool is_hotspot() { return _is_hotspot; }
477 
478   JVMCICompileState* compile_state() { return _compile_state; }
479   void set_compile_state(JVMCICompileState* compile_state) {
480     assert(_compile_state == nullptr, "set only once");
481     _compile_state = compile_state;
482   }
483   // Generate declarations for the initialize, new, isa, get and set methods for all the types and
484   // fields declared in the JVMCI_CLASSES_DO macro.
485 
486 #define START_CLASS(className, fullClassName)                           \
487   void className##_initialize(JVMCI_TRAPS); \
488   JVMCIObjectArray new_##className##_array(int length, JVMCI_TRAPS); \
489   bool isa_##className(JVMCIObject object);
490 
491 #define END_CLASS
492 
493 #define FIELD(className, name, type, accessor)                                                                                                                         \
494   type get_ ## className ## _ ## name(JVMCIObject obj); \
495   void set_ ## className ## _ ## name(JVMCIObject obj, type x);
496 
497 #define OOPISH_FIELD(className, name, type, hstype, accessor) \
498   FIELD(className, name, type, accessor)
499 
500 #define STATIC_FIELD(className, name, type) \
501   type get_ ## className ## _ ## name(); \
502   void set_ ## className ## _ ## name(type x);
503 
504 #define STATIC_OOPISH_FIELD(className, name, type, hstype) \
505   STATIC_FIELD(className, name, type)
506 
507 #define EMPTY_CAST
508 #define CHAR_FIELD(className,  name) FIELD(className, name, jchar, char_field)
509 #define INT_FIELD(className,  name) FIELD(className, name, jint, int_field)
510 #define BOOLEAN_FIELD(className,  name) FIELD(className, name, jboolean, bool_field)
511 #define LONG_FIELD(className,  name) FIELD(className, name, jlong, long_field)
512 #define FLOAT_FIELD(className,  name) FIELD(className, name, jfloat, float_field)
513 #define OBJECT_FIELD(className,  name, signature) OOPISH_FIELD(className, name, JVMCIObject, oop, obj_field)
514 #define OBJECTARRAY_FIELD(className,  name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop, obj_field)
515 #define PRIMARRAY_FIELD(className,  name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, typeArrayOop, obj_field)
516 
517 #define STATIC_INT_FIELD(className, name) STATIC_FIELD(className, name, jint)
518 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean)
519 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop)
520 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop)
521 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
522 #define CONSTRUCTOR(className, signature)
523 
524   JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
525 
526 #undef JNI_START_CLASS
527 #undef START_CLASS
528 #undef END_CLASS
529 #undef METHOD
530 #undef CONSTRUCTOR
531 #undef FIELD
532 #undef CHAR_FIELD
533 #undef INT_FIELD
534 #undef BOOLEAN_FIELD
535 #undef LONG_FIELD
536 #undef FLOAT_FIELD
537 #undef OBJECT_FIELD
538 #undef PRIMARRAY_FIELD
539 #undef OBJECTARRAY_FIELD
540 #undef FIELD
541 #undef OOPISH_FIELD
542 #undef STATIC_FIELD
543 #undef STATIC_OOPISH_FIELD
544 #undef STATIC_FIELD
545 #undef STATIC_OBJECT_FIELD
546 #undef STATIC_OBJECTARRAY_FIELD
547 #undef STATIC_INT_FIELD
548 #undef STATIC_BOOLEAN_FIELD
549 #undef EMPTY_CAST
550 
551   // End of JVMCIEnv
552 };
553 
554 #endif // SHARE_JVMCI_JVMCIENV_HPP