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