--- a/src/hotspot/share/jvmci/jvmciEnv.cpp Tue May 07 10:21:04 2019 +0800
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Mon May 06 20:05:19 2019 -0700
@@ -129,11 +129,10 @@
}
}
-JNIEnv* JVMCIEnv::attach_shared_library() {
+JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
if (_shared_library_javavm == NULL) {
MutexLocker locker(JVMCI_lock);
if (_shared_library_javavm == NULL) {
-
char path[JVM_MAXPATHLEN];
char ebuf[1024];
if (JVMCILibPath != NULL) {
@@ -179,85 +178,107 @@
}
}
}
- JNIEnv* env;
- if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) {
- guarantee(env != NULL, "missing env");
- return env;
- }
- fatal("Error attaching current thread to JVMCI shared library JNI interface");
return NULL;
}
-void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) {
+void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
+ assert(thread != NULL, "npe");
// By default there is only one runtime which is the compiler runtime.
_runtime = JVMCI::compiler_runtime();
+ _env = NULL;
+ _pop_frame_on_close = false;
+ _detach_on_close = false;
if (!UseJVMCINativeLibrary) {
// In HotSpot mode, JNI isn't used at all.
_is_hotspot = true;
- _env = NULL;
return;
}
if (parent_env != NULL) {
// If the parent JNI environment is non-null then figure out whether it
// is a HotSpot or shared library JNIEnv and set the state appropriately.
- JavaThread* thread = JavaThread::current();
- if (thread->jni_environment() == parent_env) {
+ _is_hotspot = thread->jni_environment() == parent_env;
+ if (_is_hotspot) {
// Select the Java runtime
_runtime = JVMCI::java_runtime();
- _is_hotspot = true;
- _env = NULL;
return;
}
+ _env = parent_env;
+ return;
+ }
+
+ // Running in JVMCI shared library mode so ensure the shared library
+ // is loaded and initialized and get a shared library JNIEnv
+ _is_hotspot = false;
+ _env = init_shared_library(thread);
+
+ if (_env != NULL) {
+ // Creating the JVMCI shared library VM also attaches the current thread
+ _detach_on_close = true;
+ } else {
+ _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2);
+ if (parent_env != NULL) {
+ // Even though there's a parent JNI env, there's no guarantee
+ // it was opened by a JVMCIEnv scope and thus may not have
+ // pushed a local JNI frame. As such, we use a new JNI local
+ // frame in this scope to ensure local JNI refs are collected
+ // in a timely manner after leaving this scope.
+ _env = parent_env;
+ } else {
+ ResourceMark rm; // Thread name is resource allocated
+ JavaVMAttachArgs attach_args;
+ attach_args.version = JNI_VERSION_1_2;
+ attach_args.name = thread->name();
+ attach_args.group = NULL;
+ if (_shared_library_javavm->AttachCurrentThread((void**)&_env, &attach_args) != JNI_OK) {
+ fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
+ }
+ _detach_on_close = true;
+ }
}
- // Running in JVMCI shared library mode so get a shared library JNIEnv
- _is_hotspot = false;
- _env = attach_shared_library();
- assert(parent_env == NULL || _env == parent_env, "must be");
+ assert(_env != NULL, "missing env");
+ assert(_throw_to_caller == false, "must be");
- if (parent_env == NULL) {
- // There is no parent shared library JNI env so push
- // a JNI local frame to release all local handles in
- // this JVMCIEnv scope when it's closed.
- assert(_throw_to_caller == false, "must be");
- JNIAccessMark jni(this);
- jint result = _env->PushLocalFrame(32);
- if (result != JNI_OK) {
- char message[256];
- jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
- JVMCIRuntime::exit_on_pending_exception(this, message);
- }
+ JNIAccessMark jni(this);
+ jint result = _env->PushLocalFrame(32);
+ if (result != JNI_OK) {
+ char message[256];
+ jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
+ JVMCIRuntime::exit_on_pending_exception(this, message);
}
+ _pop_frame_on_close = true;
}
-JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line):
+JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
-JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line):
+JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
_throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
- init_env_mode_runtime(parent_env);
+ init_env_mode_runtime(thread, parent_env);
assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
}
-void JVMCIEnv::init(bool is_hotspot, const char* file, int line) {
+void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
_compile_state = NULL;
_throw_to_caller = false;
_file = file;
_line = line;
if (is_hotspot) {
_env = NULL;
+ _pop_frame_on_close = false;
+ _detach_on_close = false;
_is_hotspot = true;
_runtime = JVMCI::java_runtime();
} else {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
}
@@ -324,7 +345,7 @@
}
}
} else {
- if (!is_hotspot()) {
+ if (_pop_frame_on_close) {
// Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
JNIAccessMark jni(this);
jni()->PopLocalFrame(NULL);
@@ -335,6 +356,10 @@
jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
JVMCIRuntime::exit_on_pending_exception(this, message);
}
+
+ if (_detach_on_close) {
+ get_shared_library_javavm()->DetachCurrentThread();
+ }
}
}
@@ -463,26 +488,38 @@
}
}
-void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) {
- if (size_in_bytes == 0) {
+void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
+ if (length == 0) {
+ return;
+ }
+ if (is_hotspot()) {
+ memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
+ } else {
+ JNIAccessMark jni(this);
+ jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
+ }
+}
+void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
+ if (length == 0) {
return;
}
if (is_hotspot()) {
- memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes);
+ memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
} else {
JNIAccessMark jni(this);
- jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest);
+ jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
}
}
-void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) {
- if (size_in_bytes == 0) {
+
+void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
+ if (length == 0) {
return;
}
if (is_hotspot()) {
- memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes);
+ memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
} else {
JNIAccessMark jni(this);
- jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src);
+ jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
}
}
@@ -612,6 +649,8 @@
DO_THROW(IllegalArgumentException)
DO_THROW(InvalidInstalledCodeException)
DO_THROW(UnsatisfiedLinkError)
+DO_THROW(UnsupportedOperationException)
+DO_THROW(ClassNotFoundException)
#undef DO_THROW
@@ -888,7 +927,7 @@
return JVMCIObject();
}
jobject file_name = NULL;
- if (file_name != NULL) {
+ if (file_name_sym != NULL) {
file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
if (jni()->ExceptionCheck()) {
return JVMCIObject();
@@ -1323,14 +1362,15 @@
assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
return Handle(THREAD, obj);
- } else {
- assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type");
+ } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
oop result = resolve_handle(object_handle);
if (result == NULL) {
JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
}
return Handle(THREAD, result);
+ } else {
+ JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
}
}