Path: blob/master/src/hotspot/share/jvmci/jvmciEnv.hpp
64441 views
/*1* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_JVMCI_JVMCIENV_HPP25#define SHARE_JVMCI_JVMCIENV_HPP2627#include "classfile/javaClasses.hpp"28#include "jvmci/jvmciJavaClasses.hpp"29#include "runtime/jniHandles.hpp"30#include "runtime/thread.hpp"3132class CompileTask;33class JVMCIObject;34class JVMCIObjectArray;35class JVMCIPrimitiveArray;36class JVMCICompiler;37class JVMCIRuntime;38class nmethodLocker;3940#define JVMCI_EXCEPTION_CONTEXT \41JavaThread* thread = JavaThread::current(); \42JavaThread* THREAD = thread; // For exception macros.4344// Helper to log more context on a JNI exception45#define JVMCI_EXCEPTION_CHECK(env, ...) \46do { \47if (env->ExceptionCheck()) { \48if (env != JavaThread::current()->jni_environment()) { \49char* sl_path; \50if (::JVMCI::get_shared_library(sl_path, false) != NULL) { \51tty->print_cr("In JVMCI shared library (%s):", sl_path); \52} \53} \54tty->print_cr(__VA_ARGS__); \55return; \56} \57} while(0)5859// Helper class to ensure that references to Klass* are kept alive for G160class JVMCIKlassHandle : public StackObj {61private:62Klass* _klass;63Handle _holder;64Thread* _thread;6566Klass* klass() const { return _klass; }67Klass* non_null_klass() const { assert(_klass != NULL, "resolving NULL _klass"); return _klass; }6869public:70/* Constructors */71JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {}72JVMCIKlassHandle (Thread* thread, Klass* klass);7374JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}75JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);76JVMCIKlassHandle& operator=(Klass* klass);7778/* Operators for ease of use */79Klass* operator () () const { return klass(); }80Klass* operator -> () const { return non_null_klass(); }8182bool operator == (Klass* o) const { return klass() == o; }83bool operator == (const JVMCIKlassHandle& h) const { return klass() == h.klass(); }8485/* Null checks */86bool is_null() const { return _klass == NULL; }87bool not_null() const { return _klass != NULL; }88};8990// A class that maintains the state needed for compilations requested91// by the CompileBroker. It is created in the broker and passed through92// into the code installation step.93class JVMCICompileState : public ResourceObj {94friend class JVMCIVMStructs;95private:96CompileTask* _task;97JVMCICompiler* _compiler;9899// Cache JVMTI state. Defined as bytes so that reading them from Java100// via Unsafe is well defined (the C++ type for bool is implementation101// defined and may not be the same as a Java boolean).102uint64_t _jvmti_redefinition_count;103jbyte _jvmti_can_hotswap_or_post_breakpoint;104jbyte _jvmti_can_access_local_variables;105jbyte _jvmti_can_post_on_exceptions;106jbyte _jvmti_can_pop_frame;107bool _target_method_is_old;108109// Compilation result values.110bool _retryable;111const char* _failure_reason;112113// Specifies if _failure_reason is on the C heap. If so, it is allocated114// with the mtJVMCI NMT flag.115bool _failure_reason_on_C_heap;116117// A value indicating compilation activity during the compilation.118// If successive calls to this method return a different value, then119// some degree of JVMCI compilation occurred between the calls.120jint _compilation_ticks;121122public:123JVMCICompileState(CompileTask* task, JVMCICompiler* compiler);124125CompileTask* task() { return _task; }126127bool jvmti_state_changed() const;128uint64_t jvmti_redefinition_count() const { return _jvmti_redefinition_count; }129bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; }130bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; }131bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions != 0; }132bool jvmti_can_pop_frame() const { return _jvmti_can_pop_frame != 0; }133bool target_method_is_old() const { return _target_method_is_old; }134135const char* failure_reason() { return _failure_reason; }136bool failure_reason_on_C_heap() { return _failure_reason_on_C_heap; }137bool retryable() { return _retryable; }138139void set_failure(bool retryable, const char* reason, bool reason_on_C_heap = false) {140_failure_reason = reason;141_failure_reason_on_C_heap = reason_on_C_heap;142_retryable = retryable;143}144145jint compilation_ticks() const { return _compilation_ticks; }146void inc_compilation_ticks();147};148149150// This class is a top level wrapper around interactions between HotSpot151// and the JVMCI Java code. It supports both a HotSpot heap based152// runtime with HotSpot oop based accessors as well as a shared library153// based runtime that is accessed through JNI. It abstracts away all154// interactions with JVMCI objects so that a single version of the155// HotSpot C++ code can can work with either runtime.156class JVMCIEnv : public ResourceObj {157friend class JNIAccessMark;158159// Initializes the _env, _mode and _runtime fields.160void init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env);161162void init(JavaThread* thread, bool is_hotspot, const char* file, int line);163164JNIEnv* _env; // JNI env for calling into shared library165bool _pop_frame_on_close; // Must pop frame on close?166bool _detach_on_close; // Must detach on close?167JVMCIRuntime* _runtime; // Access to a HotSpotJVMCIRuntime168bool _is_hotspot; // Which heap is the HotSpotJVMCIRuntime in169bool _throw_to_caller; // Propagate an exception raised in this env to the caller?170const char* _file; // The file and ...171int _line; // ... line where this JNIEnv was created172173// Translates an exception on the HotSpot heap (i.e., hotspot_env) to an exception on174// the shared library heap (i.e., jni_env). The translation includes the stack and cause(s) of `throwable`.175// The translated exception is pending in jni_env upon returning.176static void translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);177178// Translates an exception on the shared library heap (i.e., jni_env) to an exception on179// the HotSpot heap (i.e., hotspot_env). The translation includes the stack and cause(s) of `throwable`.180// The translated exception is pending in hotspot_env upon returning.181static void translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env);182183public:184// Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).185// An exception occurring within the scope is left pending when the186// scope closes so that it will be propagated back to Java.187// The JVMCIEnv destructor translates the exception object for the188// Java runtime if necessary.189JVMCIEnv(JavaThread* thread, JNIEnv* env, const char* file, int line);190191// Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker.192// An exception occurring within the scope must not be propagated back to193// the CompileBroker.194JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line);195196// Opens a JNIEnv scope for a call from within the VM. An exception occurring197// within the scope must not be propagated back to the caller.198JVMCIEnv(JavaThread* env, const char* file, int line);199200// Opens a JNIEnv scope for accessing `for_object`. An exception occurring201// within the scope must not be propagated back to the caller.202JVMCIEnv(JavaThread* thread, JVMCIObject for_object, const char* file, int line) {203// A JNI call to access an object in the shared library heap204// can block or take a long time so do not allow such access205// on the VM thread.206assert(for_object.is_hotspot() || !Thread::current()->is_VM_thread(),207"cannot open JVMCIEnv scope when in the VM thread for accessing a shared library heap object");208init(thread, for_object.is_hotspot(), file, line);209}210211// Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true212// otherwise for the shared library runtime. An exception occurring213// within the scope must not be propagated back to the caller.214JVMCIEnv(JavaThread* thread, bool is_hotspot, const char* file, int line) {215init(thread, is_hotspot, file, line);216}217218~JVMCIEnv();219220JVMCIRuntime* runtime() {221return _runtime;222}223224// Initializes Services.savedProperties in the shared library by copying225// the values from the same field in the HotSpot heap.226void copy_saved_properties();227228jboolean has_pending_exception();229void clear_pending_exception();230231// If this env has a pending exception, it is translated to be a pending232// exception in `peer_env` and is cleared from this env. Returns true233// if a pending exception was transferred, false otherwise.234jboolean transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env);235236// Prints an exception and stack trace of a pending exception.237void describe_pending_exception(bool clear);238239int get_length(JVMCIArray array);240241JVMCIObject get_object_at(JVMCIObjectArray array, int index);242void put_object_at(JVMCIObjectArray array, int index, JVMCIObject value);243244jboolean get_bool_at(JVMCIPrimitiveArray array, int index);245void put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value);246247jbyte get_byte_at(JVMCIPrimitiveArray array, int index);248void put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value);249250jint get_int_at(JVMCIPrimitiveArray array, int index);251void put_int_at(JVMCIPrimitiveArray array, int index, jint value);252253long get_long_at(JVMCIPrimitiveArray array, int index);254void put_long_at(JVMCIPrimitiveArray array, int index, jlong value);255256void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length);257void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length);258259void copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length);260261JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);262263jboolean is_boxing_object(BasicType type, JVMCIObject object);264265// Get the primitive value from a Java boxing object. It's hard error to266// pass a non-primitive BasicType.267jvalue get_boxed_value(BasicType type, JVMCIObject object);268269// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.270BasicType get_box_type(JVMCIObject object);271272// Create a boxing object of the appropriate primitive type.273JVMCIObject create_box(BasicType type, jvalue* value, JVMCI_TRAPS);274275const char* as_utf8_string(JVMCIObject str);276277JVMCIObject create_string(Symbol* str, JVMCI_TRAPS) {278JVMCIObject s = create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject()));279return s;280}281282JVMCIObject create_string(const char* str, JVMCI_TRAPS);283284bool equals(JVMCIObject a, JVMCIObject b);285286// Convert into a JNI handle for the appropriate runtime287jobject get_jobject(JVMCIObject object) { assert(object.as_jobject() == NULL || is_hotspot() == object.is_hotspot(), "mismatch"); return object.as_jobject(); }288jarray get_jarray(JVMCIArray array) { assert(array.as_jobject() == NULL || is_hotspot() == array.is_hotspot(), "mismatch"); return array.as_jobject(); }289jobjectArray get_jobjectArray(JVMCIObjectArray objectArray) { assert(objectArray.as_jobject() == NULL || is_hotspot() == objectArray.is_hotspot(), "mismatch"); return objectArray.as_jobject(); }290jbyteArray get_jbyteArray(JVMCIPrimitiveArray primitiveArray) { assert(primitiveArray.as_jobject() == NULL || is_hotspot() == primitiveArray.is_hotspot(), "mismatch"); return primitiveArray.as_jbyteArray(); }291292JVMCIObject wrap(jobject obj);293JVMCIObjectArray wrap(jobjectArray obj) { return (JVMCIObjectArray) wrap((jobject) obj); }294JVMCIPrimitiveArray wrap(jintArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }295JVMCIPrimitiveArray wrap(jbooleanArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }296JVMCIPrimitiveArray wrap(jbyteArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }297JVMCIPrimitiveArray wrap(jlongArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }298299private:300JVMCIObject wrap(oop obj) { assert(is_hotspot(), "must be"); return wrap(JNIHandles::make_local(obj)); }301JVMCIObjectArray wrap(objArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIObjectArray) wrap(JNIHandles::make_local(obj)); }302JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }303304public:305// Compiles a method with the JVMCI compiler.306// Caller must handle pending exception.307JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,308jlong compile_state, int id);309310void call_HotSpotJVMCIRuntime_bootstrapFinished(JVMCIObject runtime, JVMCI_TRAPS);311void call_HotSpotJVMCIRuntime_shutdown(JVMCIObject runtime);312JVMCIObject call_HotSpotJVMCIRuntime_runtime(JVMCI_TRAPS);313JVMCIObject call_JVMCI_getRuntime(JVMCI_TRAPS);314JVMCIObject call_HotSpotJVMCIRuntime_getCompiler(JVMCIObject runtime, JVMCI_TRAPS);315316JVMCIObject call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCI_TRAPS);317318JVMCIObject call_JavaConstant_forPrimitive(JVMCIObject kind, jlong value, JVMCI_TRAPS);319320jboolean call_HotSpotJVMCIRuntime_isGCSupported(JVMCIObject runtime, jint gcIdentifier);321322void call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCI_TRAPS);323324BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS);325326#define DO_THROW(name) \327void throw_##name(const char* msg = NULL);328329DO_THROW(InternalError)330DO_THROW(ArrayIndexOutOfBoundsException)331DO_THROW(IllegalStateException)332DO_THROW(NullPointerException)333DO_THROW(IllegalArgumentException)334DO_THROW(InvalidInstalledCodeException)335DO_THROW(UnsatisfiedLinkError)336DO_THROW(UnsupportedOperationException)337DO_THROW(ClassNotFoundException)338339#undef DO_THROW340341void fthrow_error(const char* file, int line, const char* format, ...) ATTRIBUTE_PRINTF(4, 5);342343// Given an instance of HotSpotInstalledCode return the corresponding CodeBlob*. The344// nmethodLocker is required to keep the CodeBlob alive in the case where it's an nmethod.345CodeBlob* get_code_blob(JVMCIObject code, nmethodLocker& locker);346347// Given an instance of HotSpotInstalledCode return the corresponding nmethod. The348// nmethodLocker is required to keep the nmethod alive.349nmethod* get_nmethod(JVMCIObject code, nmethodLocker& locker);350351MethodData* asMethodData(jlong metaspaceMethodData) {352return (MethodData*) (address) metaspaceMethodData;353}354355const char* klass_name(JVMCIObject object);356357// Unpack an instance of HotSpotResolvedJavaMethodImpl into the original Method*358Method* asMethod(JVMCIObject jvmci_method);359Method* asMethod(jobject jvmci_method) { return asMethod(wrap(jvmci_method)); }360361// Unpack an instance of HotSpotResolvedObjectTypeImpl into the original Klass*362Klass* asKlass(JVMCIObject jvmci_type);363Klass* asKlass(jobject jvmci_type) { return asKlass(wrap(jvmci_type)); }364365JVMCIObject get_jvmci_method(const methodHandle& method, JVMCI_TRAPS);366367JVMCIObject get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS);368369// Unpack an instance of HotSpotConstantPool into the original ConstantPool*370ConstantPool* asConstantPool(JVMCIObject constant_pool);371ConstantPool* asConstantPool(jobject constant_pool) { return asConstantPool(wrap(constant_pool)); }372373JVMCIObject get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS);374JVMCIObject get_jvmci_primitive_type(BasicType type);375376Handle asConstant(JVMCIObject object, JVMCI_TRAPS);377JVMCIObject get_object_constant(oop objOop, bool compressed = false, bool dont_register = false);378379JVMCIPrimitiveArray new_booleanArray(int length, JVMCI_TRAPS);380JVMCIPrimitiveArray new_byteArray(int length, JVMCI_TRAPS);381JVMCIPrimitiveArray new_intArray(int length, JVMCI_TRAPS);382JVMCIPrimitiveArray new_longArray(int length, JVMCI_TRAPS);383384JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS);385386JVMCIObject new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS);387JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);388JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);389JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);390JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS);391JVMCIObject new_HotSpotStackFrameReference(JVMCI_TRAPS);392JVMCIObject new_JVMCIError(JVMCI_TRAPS);393394jlong make_handle(const Handle& obj);395oop resolve_handle(jlong objectHandle);396397// These are analagous to the JNI routines398JVMCIObject make_local(JVMCIObject object);399void destroy_local(JVMCIObject object);400401// Makes a JNI global handle that is not scoped by the402// lifetime of a JVMCIRuntime (cf JVMCIRuntime::make_global).403// These JNI handles are used when translating an object404// between the HotSpot and JVMCI shared library heap via405// HotSpotJVMCIRuntime.translate(Object) and406// HotSpotJVMCIRuntime.unhand(Class<T>, long). Translation407// can happen in either direction so the referenced object408// can reside in either heap which is why JVMCIRuntime scoped409// handles cannot be used (they are specific to HotSpot heap objects).410JVMCIObject make_global(JVMCIObject object);411412// Destroys a JNI global handle created by JVMCIEnv::make_global.413void destroy_global(JVMCIObject object);414415// Deoptimizes the nmethod (if any) in the HotSpotNmethod.address416// field of mirror. The field is subsequently zeroed.417void invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS);418419void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS);420421private:422JVMCICompileState* _compile_state;423424public:425426// Determines if this is for the JVMCI runtime in the HotSpot427// heap (true) or the shared library heap (false).428bool is_hotspot() { return _is_hotspot; }429430JVMCICompileState* compile_state() { return _compile_state; }431void set_compile_state(JVMCICompileState* compile_state) {432assert(_compile_state == NULL, "set only once");433_compile_state = compile_state;434}435// Generate declarations for the initialize, new, isa, get and set methods for all the types and436// fields declared in the JVMCI_CLASSES_DO macro.437438#define START_CLASS(className, fullClassName) \439void className##_initialize(JVMCI_TRAPS); \440JVMCIObjectArray new_##className##_array(int length, JVMCI_TRAPS); \441bool isa_##className(JVMCIObject object);442443#define END_CLASS444445#define FIELD(className, name, type, accessor) \446type get_ ## className ## _ ## name(JVMCIObject obj); \447void set_ ## className ## _ ## name(JVMCIObject obj, type x);448449#define OOPISH_FIELD(className, name, type, hstype, accessor) \450FIELD(className, name, type, accessor)451452#define STATIC_FIELD(className, name, type) \453type get_ ## className ## _ ## name(); \454void set_ ## className ## _ ## name(type x);455456#define STATIC_OOPISH_FIELD(className, name, type, hstype) \457STATIC_FIELD(className, name, type)458459#define EMPTY_CAST460#define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field)461#define INT_FIELD(className, name) FIELD(className, name, jint, int_field)462#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field)463#define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field)464#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field)465#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, oop, obj_field)466#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop, obj_field)467#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, typeArrayOop, obj_field)468469#define STATIC_INT_FIELD(className, name) STATIC_FIELD(className, name, jint)470#define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean)471#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop)472#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop)473#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)474#define CONSTRUCTOR(className, signature)475476JVMCI_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)477478#undef JNI_START_CLASS479#undef START_CLASS480#undef END_CLASS481#undef METHOD482#undef CONSTRUCTOR483#undef FIELD484#undef CHAR_FIELD485#undef INT_FIELD486#undef BOOLEAN_FIELD487#undef LONG_FIELD488#undef FLOAT_FIELD489#undef OBJECT_FIELD490#undef PRIMARRAY_FIELD491#undef OBJECTARRAY_FIELD492#undef FIELD493#undef OOPISH_FIELD494#undef STATIC_FIELD495#undef STATIC_OOPISH_FIELD496#undef STATIC_FIELD497#undef STATIC_OBJECT_FIELD498#undef STATIC_OBJECTARRAY_FIELD499#undef STATIC_INT_FIELD500#undef STATIC_BOOLEAN_FIELD501#undef EMPTY_CAST502503// End of JVMCIEnv504};505506#endif // SHARE_JVMCI_JVMCIENV_HPP507508509