src/hotspot/share/jvmci/jvmciEnv.hpp
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File open Cdiff src/hotspot/share/jvmci/jvmciEnv.hpp

src/hotspot/share/jvmci/jvmciEnv.hpp

Print this page

        

*** 28,40 **** --- 28,50 ---- #include "classfile/systemDictionary.hpp" #include "code/debugInfoRec.hpp" #include "code/dependencies.hpp" #include "code/exceptionHandlerTable.hpp" #include "compiler/oopMap.hpp" + #include "jvmci/jvmciJavaClasses.hpp" + #include "jvmci/jvmciExceptions.hpp" + #include "oops/typeArrayOop.inline.hpp" + #include "runtime/interfaceSupport.inline.hpp" #include "runtime/thread.hpp" + #include "memory/oopFactory.hpp" class CompileTask; + class JVMCIObject; + class JVMCIObjectArray; + class JVMCIPrimitiveArray; + class JVMCICompiler; + class JVMCIRuntime; // Bring the JVMCI compiler thread into the VM state. #define JVMCI_VM_ENTRY_MARK \ JavaThread* thread = JavaThread::current(); \ ThreadInVMfromNative __tiv(thread); \
*** 45,157 **** #define JVMCI_EXCEPTION_CONTEXT \ JavaThread* thread=JavaThread::current(); \ Thread* THREAD = thread; ! // ! // This class is the top level broker for requests from the compiler ! // to the VM. ! class JVMCIEnv : StackObj { ! CI_PACKAGE_ACCESS_TO ! ! friend class JVMCIVMStructs; ! friend class CompileBroker; ! friend class Dependencies; // for get_object, during logging public: ! enum CodeInstallResult { ! ok, ! dependencies_failed, ! dependencies_invalid, ! cache_full, ! code_too_large ! }; ! ! // Look up a klass by name from a particular class loader (the accessor's). ! // If require_local, result must be defined in that class loader, or NULL. ! // If !require_local, a result from remote class loader may be reported, ! // if sufficient class loader constraints exist such that initiating ! // a class loading request from the given loader is bound to return ! // the class defined in the remote loader (or throw an error). ! // ! // Return an unloaded klass if !require_local and no class at all is found. ! // ! // The CI treats a klass as loaded if it is consistently defined in ! // another loader, even if it hasn't yet been loaded in all loaders ! // that could potentially see it via delegation. ! static Klass* get_klass_by_name(Klass* accessing_klass, Symbol* klass_name, bool require_local); ! ! // Constant pool access. ! static Klass* get_klass_by_index(const constantPoolHandle& cpool, ! int klass_index, ! bool& is_accessible, ! Klass* loading_klass); ! static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd, ! int field_index); ! static methodHandle get_method_by_index(const constantPoolHandle& cpool, ! int method_index, Bytecodes::Code bc, ! InstanceKlass* loading_klass); ! JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter); ! private: ! CompileTask* _task; ! int _system_dictionary_modification_counter; ! // Compilation result values ! bool _retryable; ! const char* _failure_reason; ! // Specifies if _failure_reason is on the C heap. ! bool _failure_reason_on_C_heap; // Cache JVMTI state. Defined as bytes so that reading them from Java // via Unsafe is well defined (the C++ type for bool is implementation // defined and may not be the same as a Java boolean). jbyte _jvmti_can_hotswap_or_post_breakpoint; jbyte _jvmti_can_access_local_variables; jbyte _jvmti_can_post_on_exceptions; jbyte _jvmti_can_pop_frame; ! // Implementation methods for loading and constant pool access. ! static Klass* get_klass_by_name_impl(Klass* accessing_klass, ! const constantPoolHandle& cpool, ! Symbol* klass_name, ! bool require_local); ! static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool, ! int klass_index, ! bool& is_accessible, ! Klass* loading_klass); ! static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd, ! int field_index); ! static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool, ! int method_index, Bytecodes::Code bc, ! InstanceKlass* loading_klass); ! ! // Helper methods ! static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass); ! static methodHandle lookup_method(InstanceKlass* accessor, ! Klass* holder, ! Symbol* name, ! Symbol* sig, ! Bytecodes::Code bc, ! constantTag tag); ! ! private: ! // Is this thread currently in the VM state? ! static bool is_in_vm(); ! // Helper routine for determining the validity of a compilation ! // with respect to concurrent class loading. ! static JVMCIEnv::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, Handle compiled_code, ! JVMCIEnv* env, char** failure_detail); - public: CompileTask* task() { return _task; } bool jvmti_state_changed() const; bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; } bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; } bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions != 0; } bool jvmti_can_pop_frame() const { return _jvmti_can_pop_frame != 0; } --- 55,752 ---- #define JVMCI_EXCEPTION_CONTEXT \ JavaThread* thread=JavaThread::current(); \ Thread* THREAD = thread; ! ! class JVMCICompileState; ! ! // Helper to log more context on a JNI exception ! #define JVMCI_EXCEPTION_CHECK(env, ...) \ ! do { \ ! if (env->ExceptionCheck()) { \ ! if (env != JavaThread::current()->jni_environment() && JVMCIEnv::get_shared_library_path() != NULL) { \ ! tty->print_cr("In JVMCI shared library (%s):", JVMCIEnv::get_shared_library_path()); \ ! } \ ! tty->print_cr(__VA_ARGS__); \ ! return; \ ! } \ ! } while(0) ! ! // Helper class to ensure that references to Klass* are kept alive for G1 ! class JVMCIKlassHandle : public StackObj { ! private: ! Klass* _klass; ! Handle _holder; ! Thread* _thread; ! ! Klass* klass() const { return _klass; } ! Klass* non_null_klass() const { assert(_klass != NULL, "resolving NULL _klass"); return _klass; } ! ! public: ! /* Constructors */ ! JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {} ! JVMCIKlassHandle (Thread* thread, Klass* klass); ! ! JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {} ! JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s); ! JVMCIKlassHandle& operator=(Klass* klass); ! ! /* Operators for ease of use */ ! Klass* operator () () const { return klass(); } ! Klass* operator -> () const { return non_null_klass(); } ! ! bool operator == (Klass* o) const { return klass() == o; } ! bool operator == (const JVMCIKlassHandle& h) const { return klass() == h.klass(); } ! ! /* Null checks */ ! bool is_null() const { return _klass == NULL; } ! bool not_null() const { return _klass != NULL; } ! }; ! ! // Wrapper for a JNI call into the JVMCI shared library. ! // This performs a ThreadToNativeFromVM transition so that the VM ! // will not be blocked if the call takes a long time (e.g., due ! // to a GC in the shared library). ! class JNIAccessMark : private ThreadToNativeFromVM, private HandleMark { ! private: ! JNIEnv* _env; ! public: ! JNIAccessMark(JVMCIEnv* jvmci_env); ! JNIEnv* env() const { return _env; } ! JNIEnv* operator () () const { return _env; } ! }; ! ! // This class is a top level wrapper around interactions between HotSpot ! // and the JVMCI Java code. It supports both a HotSpot heap based ! // runtime with HotSpot oop based accessors as well as a shared library ! // based runtime that is accessed through JNI. It abstracts away all ! // interactions with JVMCI objects so that a single version of the ! // HotSpot C++ code can can work with either runtime. ! class JVMCIEnv : public ResourceObj { ! friend class JNIAccessMark; ! ! static char* _shared_library_path; // argument to os:dll_load ! static void* _shared_library_handle; // result of os::dll_load ! static JavaVM* _shared_library_javavm; // result of calling JNI_CreateJavaVM in shared library ! ! // Attaches the current thread to the JavaVM in the shared library, ! // initializing the shared library VM first if necessary. ! // Returns the JNI interface pointer of the current thread. ! // The _shared_library_* fields are initialized by the first ! // call to this method. ! static JNIEnv* attach_shared_library(); ! ! // Initializes the _env, _mode and _runtime fields. ! void init_env_mode_runtime(JNIEnv* parent_env); ! ! void init(bool is_hotspot, const char* file, int line); ! ! JNIEnv* _env; // JNI env for calling into shared library ! JVMCIRuntime* _runtime; // Access to a HotSpotJVMCIRuntime ! bool _is_hotspot; // Which heap is the HotSpotJVMCIRuntime in ! bool _throw_to_caller; // Propagate an exception raised in this env to the caller? ! const char* _file; // The file and ... ! int _line; // ... line where this JNIEnv was created ! ! // Translates an exception on the HotSpot heap to an exception on ! // the shared library heap. The translation includes the stack and ! // causes of `throwable`. The translated exception is pending in the ! // shared library thread upon returning. ! void translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, Handle throwable); public: + // Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM). + // An exception occurring within the scope is left pending when the + // scope closes so that it will be propagated back to Java. + // The JVMCIEnv destructor translates the exception object for the + // Java runtime if necessary. + JVMCIEnv(JNIEnv* env, const char* file, int line); + + // Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker. + // An exception occurring within the scope must not be propagated back to + // the CompileBroker. + JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line); + + // Opens a JNIEnv scope for a call from within the VM. An exception occurring + // within the scope must not be propagated back to the caller. + JVMCIEnv(JavaThread* env, const char* file, int line); + + // Opens a JNIEnv scope for accessing `for_object`. An exception occurring + // within the scope must not be propagated back to the caller. + JVMCIEnv(JVMCIObject for_object, const char* file, int line) { + // A JNI call to access an object in the shared library heap + // can block or take a long time so do not allow such access + // on the VM thread. + assert(for_object.is_hotspot() || !Thread::current()->is_VM_thread(), + "cannot open JVMCIEnv scope when in the VM thread for accessing a shared library heap object"); + init(for_object.is_hotspot(), file, line); + } ! // Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true ! // otherwise for the shared library runtime. An exception occurring ! // within the scope must not be propagated back to the caller. ! JVMCIEnv(bool is_hotspot, const char* file, int line) { ! init(is_hotspot, file, line); ! } ! ~JVMCIEnv(); ! JVMCIRuntime* runtime() { ! return _runtime; ! } ! // Initializes Services.savedProperties in the shared library by copying ! // the values from the same field in the HotSpot heap. ! void copy_saved_properties(); ! ! jboolean has_pending_exception() { ! if (!is_hotspot()) { ! JNIAccessMark jni(this); ! return jni()->ExceptionCheck(); ! } else { ! Thread* THREAD = Thread::current(); ! return HAS_PENDING_EXCEPTION; ! } ! } ! void clear_pending_exception() { ! if (!is_hotspot()) { ! JNIAccessMark jni(this); ! jni()->ExceptionClear(); ! } else { ! Thread* THREAD = Thread::current(); ! CLEAR_PENDING_EXCEPTION; ! } ! } ! ! // Prints an exception and stack trace of a pending exception. ! void describe_pending_exception(bool clear); ! ! int get_length(JVMCIArray array) { ! if (is_hotspot()) { ! return HotSpotJVMCI::resolve(array)->length(); ! } else { ! JNIAccessMark jni(this); ! return jni()->GetArrayLength(get_jarray(array)); ! } ! } ! JVMCIObject get_object_at(JVMCIObjectArray array, int index) { ! if (is_hotspot()) { ! oop result = HotSpotJVMCI::resolve(array)->obj_at(index); ! return wrap(result); ! } else { ! JNIAccessMark jni(this); ! jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index); ! return wrap(result); ! } ! } ! ! void put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) { ! if (is_hotspot()) { ! HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value)); ! } else { ! JNIAccessMark jni(this); ! jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value)); ! } ! } ! ! jboolean get_bool_at(JVMCIPrimitiveArray array, int index) { ! if (is_hotspot()) { ! return HotSpotJVMCI::resolve(array)->bool_at(index); ! } else { ! JNIAccessMark jni(this); ! jboolean result; ! jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result); ! return result; ! } ! } ! void put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) { ! if (is_hotspot()) { ! HotSpotJVMCI::resolve(array)->bool_at_put(index, value); ! } else { ! JNIAccessMark jni(this); ! jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value); ! } ! } ! ! jbyte get_byte_at(JVMCIPrimitiveArray array, int index) { ! if (is_hotspot()) { ! return HotSpotJVMCI::resolve(array)->byte_at(index); ! } else { ! JNIAccessMark jni(this); ! jbyte result; ! jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result); ! return result; ! } ! } ! void put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) { ! if (is_hotspot()) { ! HotSpotJVMCI::resolve(array)->byte_at_put(index, value); ! } else { ! JNIAccessMark jni(this); ! jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value); ! } ! } ! ! jint get_int_at(JVMCIPrimitiveArray array, int index) { ! if (is_hotspot()) { ! return HotSpotJVMCI::resolve(array)->int_at(index); ! } else { ! JNIAccessMark jni(this); ! jint result; ! jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result); ! return result; ! } ! } ! void put_int_at(JVMCIPrimitiveArray array, int index, jint value) { ! if (is_hotspot()) { ! HotSpotJVMCI::resolve(array)->int_at_put(index, value); ! } else { ! JNIAccessMark jni(this); ! jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value); ! } ! } ! ! long get_long_at(JVMCIPrimitiveArray array, int index) { ! if (is_hotspot()) { ! return HotSpotJVMCI::resolve(array)->long_at(index); ! } else { ! JNIAccessMark jni(this); ! jlong result; ! jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result); ! return result; ! } ! } ! void put_long_at(JVMCIPrimitiveArray array, int index, jlong value) { ! if (is_hotspot()) { ! HotSpotJVMCI::resolve(array)->long_at_put(index, value); ! } else { ! JNIAccessMark jni(this); ! jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); ! } ! } ! ! void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) { ! if (size_in_bytes == 0) { ! return; ! } ! if (is_hotspot()) { ! memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes); ! } else { ! JNIAccessMark jni(this); ! jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest); ! } ! } ! void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) { ! if (size_in_bytes == 0) { ! return; ! } ! if (is_hotspot()) { ! memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes); ! } else { ! JNIAccessMark jni(this); ! jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src); ! } ! } ! ! JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS); ! ! jboolean is_boxing_object(BasicType type, JVMCIObject object) { ! if (is_hotspot()) { ! return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type); ! } else { ! JNIAccessMark jni(this); ! return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type)); ! } ! } ! ! // Get the primitive value from a Java boxing object. It's hard error to ! // pass a non-primitive BasicType. ! jvalue get_boxed_value(BasicType type, JVMCIObject object) { ! jvalue result; ! if (is_hotspot()) { ! if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) { ! ShouldNotReachHere(); ! } ! } else { ! JNIAccessMark jni(this); ! jfieldID field = JNIJVMCI::box_field(type); ! switch (type) { ! case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break; ! case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break; ! case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break; ! case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break; ! case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break; ! case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break; ! case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break; ! case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break; ! default: ! ShouldNotReachHere(); ! } ! } ! return result; ! } ! ! // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL. ! BasicType get_box_type(JVMCIObject object) { ! if (is_hotspot()) { ! return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object)); ! } else { ! JNIAccessMark jni(this); ! jclass clazz = jni()->GetObjectClass(get_jobject(object)); ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT; ! if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE; ! return T_ILLEGAL; ! } ! } ! ! // Create a boxing object of the appropriate primitive type. ! JVMCIObject create_box(BasicType type, jvalue* value, JVMCI_TRAPS) { ! switch (type) { ! case T_BOOLEAN: ! case T_BYTE: ! case T_CHAR: ! case T_SHORT: ! case T_INT: ! case T_LONG: ! case T_FLOAT: ! case T_DOUBLE: ! break; ! default: ! JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject()); ! } ! if (is_hotspot()) { ! JavaThread* THREAD = JavaThread::current(); ! oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject())); ! return HotSpotJVMCI::wrap(box); ! } else { ! JNIAccessMark jni(this); ! jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value); ! assert(box != NULL, ""); ! return wrap(box); ! } ! } ! ! const char* as_utf8_string(JVMCIObject str) { ! if (is_hotspot()) { ! return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str)); ! } else { ! JNIAccessMark jni(this); ! int length = jni()->GetStringLength(str.as_jstring()); ! char* result = NEW_RESOURCE_ARRAY(char, length + 1); ! jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result); ! return result; ! } ! } ! ! char* as_utf8_string(JVMCIObject str, char* buf, int buflen) { ! if (is_hotspot()) { ! return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen); ! } else { ! JNIAccessMark jni(this); ! int length = jni()->GetStringLength(str.as_jstring()); ! if (length >= buflen) { ! length = buflen; ! } ! jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf); ! return buf; ! } ! } ! ! JVMCIObject create_string(Symbol* str, JVMCI_TRAPS) { ! return create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject())); ! } ! ! JVMCIObject create_string(const char* str, JVMCI_TRAPS); ! ! bool equals(JVMCIObject a, JVMCIObject b); ! ! // Convert into a JNI handle for the appropriate runtime ! jobject get_jobject(JVMCIObject object) { assert(object.as_jobject() == NULL || is_hotspot() == object.is_hotspot(), "mismatch"); return object.as_jobject(); } ! jarray get_jarray(JVMCIArray array) { assert(array.as_jobject() == NULL || is_hotspot() == array.is_hotspot(), "mismatch"); return array.as_jobject(); } ! jobjectArray get_jobjectArray(JVMCIObjectArray objectArray) { assert(objectArray.as_jobject() == NULL || is_hotspot() == objectArray.is_hotspot(), "mismatch"); return objectArray.as_jobject(); } ! jbyteArray get_jbyteArray(JVMCIPrimitiveArray primitiveArray) { assert(primitiveArray.as_jobject() == NULL || is_hotspot() == primitiveArray.is_hotspot(), "mismatch"); return primitiveArray.as_jbyteArray(); } ! ! JVMCIObject wrap(jobject obj); ! JVMCIObjectArray wrap(jobjectArray obj) { return (JVMCIObjectArray) wrap((jobject) obj); } ! JVMCIPrimitiveArray wrap(jintArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); } ! JVMCIPrimitiveArray wrap(jbooleanArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); } ! JVMCIPrimitiveArray wrap(jbyteArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); } ! JVMCIPrimitiveArray wrap(jlongArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); } ! ! private: ! JVMCIObject wrap(oop obj) { assert(is_hotspot(), "must be"); return wrap(JNIHandles::make_local(obj)); } ! JVMCIObjectArray wrap(objArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIObjectArray) wrap(JNIHandles::make_local(obj)); } ! JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); } ! ! public: ! // Compiles a method with the JVMIC compiler. ! // Caller must handle pending exception. ! JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci, ! jlong compile_state, int id); ! ! int call_HotSpotJVMCIRuntime_adjustCompilationLevel(JVMCIObject runtime, InstanceKlass* declaringClass, ! JVMCIObject name, JVMCIObject signature, bool is_osr, int level, JVMCI_TRAPS); ! void call_HotSpotJVMCIRuntime_bootstrapFinished(JVMCIObject runtime, JVMCI_TRAPS); ! void call_HotSpotJVMCIRuntime_shutdown(JVMCIObject runtime); ! JVMCIObject call_HotSpotJVMCIRuntime_runtime(JVMCI_TRAPS); ! JVMCIObject call_JVMCI_getRuntime(JVMCI_TRAPS); ! JVMCIObject call_HotSpotJVMCIRuntime_getCompiler(JVMCIObject runtime, JVMCI_TRAPS); ! ! JVMCIObject call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCI_TRAPS); ! ! JVMCIObject call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS); ! JVMCIObject call_JavaConstant_forFloat(float value, JVMCI_TRAPS); ! JVMCIObject call_JavaConstant_forDouble(double value, JVMCI_TRAPS); ! ! BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS); ! ! #define DO_THROW(name) \ ! void throw_##name(const char* msg = NULL) { \ ! if (is_hotspot()) { \ ! JavaThread* THREAD = JavaThread::current(); \ ! THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \ ! } else { \ ! JNIAccessMark jni(this); \ ! jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \ ! } \ ! } ! ! DO_THROW(InternalError) ! DO_THROW(ArrayIndexOutOfBoundsException) ! DO_THROW(IllegalStateException) ! DO_THROW(NullPointerException) ! DO_THROW(IllegalArgumentException) ! DO_THROW(InvalidInstalledCodeException) ! DO_THROW(UnsatisfiedLinkError) ! ! #undef DO_THROW ! ! void fthrow_error(const char* file, int line, const char* format, ...) ATTRIBUTE_PRINTF(4, 5) { ! const int max_msg_size = 1024; ! va_list ap; ! va_start(ap, format); ! char msg[max_msg_size]; ! vsnprintf(msg, max_msg_size, format, ap); ! msg[max_msg_size-1] = '\0'; ! va_end(ap); ! if (is_hotspot()) { ! JavaThread* THREAD = JavaThread::current(); ! Handle h_loader = Handle(); ! Handle h_protection_domain = Handle(); ! Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain); ! } else { ! JNIAccessMark jni(this); ! jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); ! } ! } ! ! // Given an instance of HotSpotInstalledCode return the corresponding CodeBlob* ! CodeBlob* asCodeBlob(JVMCIObject code); ! ! nmethod* asNmethod(JVMCIObject code) { ! CodeBlob* cb = asCodeBlob(code); ! if (cb == NULL) { ! return NULL; ! } ! nmethod* nm = cb->as_nmethod_or_null(); ! guarantee(nm != NULL, "not an nmethod"); ! return nm; ! } ! ! MethodData* asMethodData(jlong metaspaceMethodData) { ! return (MethodData*) (address) metaspaceMethodData; ! } ! ! const char* klass_name(JVMCIObject object); ! ! // Unpack an instance of HotSpotResolvedJavaMethodImpl into the original Method* ! Method* asMethod(JVMCIObject jvmci_method); ! Method* asMethod(jobject jvmci_method) { return asMethod(wrap(jvmci_method)); } ! ! // Unpack an instance of HotSpotResolvedObjectTypeImpl into the original Klass* ! Klass* asKlass(JVMCIObject jvmci_type); ! Klass* asKlass(jobject jvmci_type) { return asKlass(wrap(jvmci_type)); } ! ! JVMCIObject get_jvmci_method(const methodHandle& method, JVMCI_TRAPS); ! ! JVMCIObject get_jvmci_type(JVMCIKlassHandle& klass, JVMCI_TRAPS); ! ! // Unpack an instance of HotSpotConstantPool into the original ConstantPool* ! ConstantPool* asConstantPool(JVMCIObject constant_pool); ! ConstantPool* asConstantPool(jobject constant_pool) { return asConstantPool(wrap(constant_pool)); } ! ! JVMCIObject get_jvmci_constant_pool(constantPoolHandle cp, JVMCI_TRAPS); ! JVMCIObject get_jvmci_primitive_type(BasicType type); ! ! Handle asConstant(JVMCIObject object, JVMCI_TRAPS); ! JVMCIObject get_object_constant(oop objOop, bool compressed = false, bool dont_register = false); ! ! JVMCIPrimitiveArray new_booleanArray(int length, JVMCI_TRAPS); ! JVMCIPrimitiveArray new_byteArray(int length, JVMCI_TRAPS); ! JVMCIPrimitiveArray new_intArray(int length, JVMCI_TRAPS); ! JVMCIPrimitiveArray new_longArray(int length, JVMCI_TRAPS); ! ! JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS); ! ! JVMCIObject new_StackTraceElement(methodHandle method, int bci, JVMCI_TRAPS); ! JVMCIObject new_HotSpotNmethod(methodHandle method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS); ! JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS); ! JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS); ! JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS); ! JVMCIObject new_HotSpotStackFrameReference(JVMCI_TRAPS); ! JVMCIObject new_JVMCIError(JVMCI_TRAPS); ! ! jlong make_handle(Handle obj); ! oop resolve_handle(jlong objectHandle); ! ! // These are analagous to the JNI routines ! JVMCIObject make_local(JVMCIObject object); ! JVMCIObject make_global(JVMCIObject object); ! JVMCIObject make_weak(JVMCIObject object); ! void destroy_local(JVMCIObject object); ! void destroy_global(JVMCIObject object); ! void destroy_weak(JVMCIObject object); ! ! // Deoptimizes the nmethod (if any) in the HotSpotNmethod.address ! // field of mirror. The field is subsequently zeroed. ! void invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS); ! ! void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS); ! ! private: ! JVMCICompileState* _compile_state; ! ! public: ! static JavaVM* get_shared_library_javavm() { return _shared_library_javavm; } ! static void* get_shared_library_handle() { return _shared_library_handle; } ! static char* get_shared_library_path() { return _shared_library_path; } ! ! // Determines if this is for the JVMCI runtime in the HotSpot ! // heap (true) or the shared library heap (false). ! bool is_hotspot() { return _is_hotspot; } ! ! JVMCICompileState* compile_state() { return _compile_state; } ! void set_compile_state(JVMCICompileState* compile_state) { ! assert(_compile_state == NULL, "set only once"); ! _compile_state = compile_state; ! } ! // Generate declarations for the initialize, new, isa, get and set methods for all the types and ! // fields declared in the JVMCI_CLASSES_DO macro. ! ! #define START_CLASS(className, fullClassName) \ ! void className##_initialize(JVMCI_TRAPS); \ ! JVMCIObjectArray new_##className##_array(int length, JVMCI_TRAPS); \ ! bool isa_##className(JVMCIObject object); ! ! #define END_CLASS ! ! #define FIELD(className, name, type, accessor) \ ! type get_ ## className ## _ ## name(JVMCIObject obj); \ ! void set_ ## className ## _ ## name(JVMCIObject obj, type x); ! ! #define OOPISH_FIELD(className, name, type, hstype, accessor) \ ! FIELD(className, name, type, accessor) ! ! #define STATIC_FIELD(className, name, type) \ ! type get_ ## className ## _ ## name(); \ ! void set_ ## className ## _ ## name(type x); ! ! #define STATIC_OOPISH_FIELD(className, name, type, hstype) \ ! STATIC_FIELD(className, name, type) ! ! #define EMPTY_CAST ! #define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field) ! #define INT_FIELD(className, name) FIELD(className, name, jint, int_field) ! #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field) ! #define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field) ! #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field) ! #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, oop, obj_field) ! #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop, obj_field) ! #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, typeArrayOop, obj_field) ! ! #define STATIC_INT_FIELD(className, name) STATIC_FIELD(className, name, jint) ! #define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean) ! #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop) ! #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop) ! #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) ! #define CONSTRUCTOR(className, signature) ! ! 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) ! ! #undef JNI_START_CLASS ! #undef START_CLASS ! #undef END_CLASS ! #undef METHOD ! #undef CONSTRUCTOR ! #undef FIELD ! #undef CHAR_FIELD ! #undef INT_FIELD ! #undef BOOLEAN_FIELD ! #undef LONG_FIELD ! #undef FLOAT_FIELD ! #undef OBJECT_FIELD ! #undef PRIMARRAY_FIELD ! #undef OBJECTARRAY_FIELD ! #undef FIELD ! #undef OOPISH_FIELD ! #undef STATIC_FIELD ! #undef STATIC_OOPISH_FIELD ! #undef STATIC_FIELD ! #undef STATIC_OBJECT_FIELD ! #undef STATIC_OBJECTARRAY_FIELD ! #undef STATIC_INT_FIELD ! #undef STATIC_BOOLEAN_FIELD ! #undef EMPTY_CAST ! ! // End of JVMCIEnv ! }; ! ! ! inline JNIAccessMark::JNIAccessMark(JVMCIEnv* jvmci_env): ThreadToNativeFromVM(JavaThread::current()), HandleMark(JavaThread::current()) { ! _env = jvmci_env->_env; ! } ! ! ! // A class that maintains the state needed for compilations requested ! // by the CompileBroker. It is created in the broker and passed through ! // into the code installation step. ! class JVMCICompileState : public ResourceObj { ! friend class VMStructs; ! private: ! CompileTask* _task; ! int _system_dictionary_modification_counter; // Cache JVMTI state. Defined as bytes so that reading them from Java // via Unsafe is well defined (the C++ type for bool is implementation // defined and may not be the same as a Java boolean). jbyte _jvmti_can_hotswap_or_post_breakpoint; jbyte _jvmti_can_access_local_variables; jbyte _jvmti_can_post_on_exceptions; jbyte _jvmti_can_pop_frame; ! // Compilation result values. ! bool _retryable; ! const char* _failure_reason; ! // Specifies if _failure_reason is on the C heap. If so, it is allocated ! // with the mtCompiler NMT flag. ! bool _failure_reason_on_C_heap; ! public: ! JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter); CompileTask* task() { return _task; } + int system_dictionary_modification_counter() { return _system_dictionary_modification_counter; } bool jvmti_state_changed() const; bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; } bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; } bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions != 0; } bool jvmti_can_pop_frame() const { return _jvmti_can_pop_frame != 0; }
*** 163,198 **** void set_failure(bool retryable, const char* reason, bool reason_on_C_heap = false) { _failure_reason = reason; _failure_reason_on_C_heap = reason_on_C_heap; _retryable = retryable; } - - // Register the result of a compilation. - static JVMCIEnv::CodeInstallResult register_method( - const methodHandle& target, - nmethod*& nm, - int entry_bci, - CodeOffsets* offsets, - int orig_pc_offset, - CodeBuffer* code_buffer, - int frame_words, - OopMapSet* oop_map_set, - ExceptionHandlerTable* handler_table, - AbstractCompiler* compiler, - DebugInformationRecorder* debug_info, - Dependencies* dependencies, - JVMCIEnv* env, - int compile_id, - bool has_unsafe_access, - bool has_wide_vector, - Handle installed_code, - Handle compiled_code, - Handle speculation_log); - - // converts the Klass* representing the holder of a method into a - // InstanceKlass*. This is needed since the holder of a method in - // the bytecodes could be an array type. Basically this converts - // array types into java/lang/Object and other types stay as they are. - static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass); }; #endif // SHARE_JVMCI_JVMCIENV_HPP --- 758,765 ----
src/hotspot/share/jvmci/jvmciEnv.hpp
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File