< prev index next >

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Print this page

        

@@ -95,18 +95,14 @@
 class JVMCITraceMark : public StackObj {
   const char* _msg;
  public:
   JVMCITraceMark(const char* msg) {
     _msg = msg;
-    if (JVMCITraceLevel >= 1) {
-      tty->print_cr(PTR_FORMAT " JVMCITrace-1: Enter %s", p2i(JavaThread::current()), _msg);
-    }
+    TRACE_jvmci_2("Enter %s", _msg);
   }
   ~JVMCITraceMark() {
-    if (JVMCITraceLevel >= 1) {
-      tty->print_cr(PTR_FORMAT " JVMCITrace-1: Exit %s", p2i(JavaThread::current()), _msg);
-    }
+    TRACE_jvmci_2(" Exit %s", _msg);
   }
 };
 
 
 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {

@@ -129,50 +125,52 @@
   TRACE_CALL(result_type, jvmci_ ## name signature)  \
   JVMCI_VM_ENTRY_MARK;                               \
   ResourceMark rm;                                   \
   JNI_JVMCIENV(thread, env);
 
-static Thread* get_current_thread() {
-  return Thread::current_or_null_safe();
+static JavaThread* get_current_thread(bool allow_null=true) {
+  Thread* thread = Thread::current_or_null_safe();
+  if (thread == NULL) {
+    assert(allow_null, "npe");
+    return NULL;
+  }
+  assert(thread->is_Java_thread(), "must be");
+  return (JavaThread*) thread;
 }
 
 // Entry to native method implementation that transitions
 // current thread to '_thread_in_vm'.
 #define C2V_VMENTRY(result_type, name, signature)        \
   JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  Thread* base_thread = get_current_thread();            \
-  if (base_thread == NULL) {                             \
+  JavaThread* thread = get_current_thread();             \
+  if (thread == NULL) {                                  \
     env->ThrowNew(JNIJVMCI::InternalError::clazz(),      \
         err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
     return;                                              \
   }                                                      \
-  assert(base_thread->is_Java_thread(), "just checking");\
-  JavaThread* thread = (JavaThread*) base_thread;        \
   JVMCITraceMark jtm("CompilerToVM::" #name);            \
   C2V_BLOCK(result_type, name, signature)
 
 #define C2V_VMENTRY_(result_type, name, signature, result) \
   JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  Thread* base_thread = get_current_thread();            \
-  if (base_thread == NULL) {                             \
+          JavaThread* thread = get_current_thread();             \
+          if (thread == NULL) {                                  \
     env->ThrowNew(JNIJVMCI::InternalError::clazz(),      \
         err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
     return result;                                       \
   }                                                      \
-  assert(base_thread->is_Java_thread(), "just checking");\
-  JavaThread* thread = (JavaThread*) base_thread;        \
   JVMCITraceMark jtm("CompilerToVM::" #name);            \
   C2V_BLOCK(result_type, name, signature)
 
 #define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)
 #define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)
 
 // Entry to native method implementation that does not transition
 // current thread to '_thread_in_vm'.
 #define C2V_VMENTRY_PREFIX(result_type, name, signature) \
   JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  Thread* base_thread = get_current_thread();
+  JavaThread* thread = get_current_thread();
 
 #define C2V_END }
 
 #define JNI_THROW(caller, name, msg) do {                                         \
     jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg);               \

@@ -1572,11 +1570,11 @@
 // from HotSpot if it wasn't already attached when entering the scope.
 extern "C" void jio_printf(const char *fmt, ...);
 class AttachDetach : public StackObj {
  public:
   bool _attached;
-  AttachDetach(JNIEnv* env, Thread* current_thread) {
+  AttachDetach(JNIEnv* env, JavaThread* current_thread) {
     if (current_thread == NULL) {
       extern struct JavaVM_ main_vm;
       JNIEnv* hotspotEnv;
       jint res = main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
       _attached = res == JNI_OK;

@@ -1601,22 +1599,21 @@
     }
   }
 };
 
 C2V_VMENTRY_PREFIX(jint, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length, bool flush, bool can_throw))
-  AttachDetach ad(env, base_thread);
+  AttachDetach ad(env, thread);
   bool use_tty = true;
-  if (base_thread == NULL) {
+  if (thread == NULL) {
     if (!ad._attached) {
       // Can only use tty if the current thread is attached
+      TRACE_jvmci_1("Cannot write to tty on unattached thread");
       return 0;
     }
-    base_thread = get_current_thread();
+    thread = get_current_thread();
   }
   JVMCITraceMark jtm("writeDebugOutput");
-  assert(base_thread->is_Java_thread(), "just checking");
-  JavaThread* thread = (JavaThread*) base_thread;
   C2V_BLOCK(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
   if (bytes == NULL) {
     if (can_throw) {
       JVMCI_THROW_0(NullPointerException);
     }

@@ -2208,45 +2205,38 @@
 }
 
 C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong h))
   jobject handle = (jobject)(address)h;
   if (handle != NULL) {
-    JVMCI::destroy_global(handle);
+    JVMCIENV->runtime()->destroy_global(handle);
   }
 }
 
 static void requireJVMCINativeLibrary(JVMCI_TRAPS) {
   if (!UseJVMCINativeLibrary) {
     JVMCI_THROW_MSG(UnsupportedOperationException, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
   }
 }
 
-static JavaVM* requireNativeLibraryJavaVM(const char* caller, JVMCI_TRAPS) {
-  JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
-  if (javaVM == NULL) {
-    JVMCI_THROW_MSG_NULL(IllegalStateException, err_msg("Require JVMCI shared library to be initialized in %s", caller));
-  }
-  return javaVM;
-}
-
 C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
   requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
   requireInHotSpot("registerNativeMethods", JVMCI_CHECK_NULL);
-  void* shared_library = JVMCIEnv::get_shared_library_handle();
-  if (shared_library == NULL) {
+  char* sl_path;
+  void* sl_handle;
+  JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+  {
     // Ensure the JVMCI shared library runtime is initialized.
     JVMCIEnv __peer_jvmci_env__(thread, false, __FILE__, __LINE__);
     JVMCIEnv* peerEnv = &__peer_jvmci_env__;
     HandleMark hm;
-    JVMCIRuntime* runtime = JVMCI::compiler_runtime();
     JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
     if (peerEnv->has_pending_exception()) {
       peerEnv->describe_pending_exception(true);
     }
-    shared_library = JVMCIEnv::get_shared_library_handle();
-    if (shared_library == NULL) {
-      JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
+    sl_handle = JVMCI::get_shared_library(sl_path, false);
+    if (sl_handle == NULL) {
+      JVMCI_THROW_MSG_0(InternalError, err_msg("Error initializing JVMCI runtime %d", runtime->id()));
     }
   }
 
   if (mirror == NULL) {
     JVMCI_THROW_0(NullPointerException);

@@ -2272,146 +2262,148 @@
       os::print_jni_name_prefix_on(&st, args_size);
       st.print_raw(pure_name);
       os::print_jni_name_suffix_on(&st, args_size);
       char* jni_name = st.as_string();
 
-      address entry = (address) os::dll_lookup(shared_library, jni_name);
+      address entry = (address) os::dll_lookup(sl_handle, jni_name);
       if (entry == NULL) {
         // 2) Try JNI long style
         st.reset();
         char* long_name = NativeLookup::long_jni_name(method);
         os::print_jni_name_prefix_on(&st, args_size);
         st.print_raw(pure_name);
         st.print_raw(long_name);
         os::print_jni_name_suffix_on(&st, args_size);
         char* jni_long_name = st.as_string();
-        entry = (address) os::dll_lookup(shared_library, jni_long_name);
+        entry = (address) os::dll_lookup(sl_handle, jni_long_name);
         if (entry == NULL) {
           JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [neither %s nor %s exist in %s]",
               method->name_and_sig_as_C_string(),
-              jni_name, jni_long_name, JVMCIEnv::get_shared_library_path()));
+              jni_name, jni_long_name, sl_path));
         }
       }
 
       if (method->has_native_function() && entry != method->native_function()) {
         JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT "]",
             method->name_and_sig_as_C_string(), p2i(method->native_function()), p2i(entry)));
       }
       method->set_native_function(entry, Method::native_bind_event_is_interesting);
       if (PrintJNIResolving) {
-        tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
+        tty->print_cr("[Dynamic-linking native method %s.%s ... JNI] @ " PTR_FORMAT,
           method->method_holder()->external_name(),
-          method->name()->as_C_string());
+          method->name()->as_C_string(), p2i((void*) entry));
       }
     }
   }
 
-  JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
-  JVMCIPrimitiveArray result = JVMCIENV->new_longArray(4, JVMCI_CHECK_NULL);
-  JVMCIENV->put_long_at(result, 0, (jlong) (address) javaVM);
-  JVMCIENV->put_long_at(result, 1, (jlong) (address) javaVM->functions->reserved0);
-  JVMCIENV->put_long_at(result, 2, (jlong) (address) javaVM->functions->reserved1);
-  JVMCIENV->put_long_at(result, 3, (jlong) (address) javaVM->functions->reserved2);
-  return (jlongArray) JVMCIENV->get_jobject(result);
+  typeArrayOop info_oop = oopFactory::new_longArray(4, CHECK_0);
+  jlongArray info = (jlongArray) JNIHandles::make_local(info_oop);
+  runtime->init_JavaVM_info(info, JVMCI_CHECK_0);
+  return info;
 }
 
 C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))
-  if (base_thread == NULL) {
+  if (thread == NULL) {
     // Called from unattached JVMCI shared library thread
     return false;
   }
   JVMCITraceMark jtm("isCurrentThreadAttached");
-  assert(base_thread->is_Java_thread(), "just checking");
-  JavaThread* thread = (JavaThread*) base_thread;
   if (thread->jni_environment() == env) {
     C2V_BLOCK(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject))
     requireJVMCINativeLibrary(JVMCI_CHECK_0);
-    JavaVM* javaVM = requireNativeLibraryJavaVM("isCurrentThreadAttached", JVMCI_CHECK_0);
+    JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+    if (runtime == NULL || !runtime->has_shared_library_javavm()) {
+      JVMCI_THROW_MSG_0(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in isCurrentThreadAttached");
+    }
     JNIEnv* peerEnv;
-    return javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK;
+    return runtime->GetEnv(thread, (void**) &peerEnv, JNI_VERSION_1_2) == JNI_OK;
   }
   return true;
 C2V_END
 
 C2V_VMENTRY_PREFIX(jlong, getCurrentJavaThread, (JNIEnv* env, jobject c2vm))
-  if (base_thread == NULL) {
+  if (thread == NULL) {
     // Called from unattached JVMCI shared library thread
     return 0L;
   }
   JVMCITraceMark jtm("getCurrentJavaThread");
-  assert(base_thread->is_Java_thread(), "just checking");
-  return (jlong) p2i(base_thread);
+  return (jlong) p2i(thread);
 C2V_END
 
 C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
-  if (base_thread == NULL) {
+  if (thread == NULL) {
     // Called from unattached JVMCI shared library thread
     extern struct JavaVM_ main_vm;
     JNIEnv* hotspotEnv;
-    jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**)&hotspotEnv, NULL) :
-                           main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
+    jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**) &hotspotEnv, NULL) :
+                           main_vm.AttachCurrentThread((void**) &hotspotEnv, NULL);
     if (res != JNI_OK) {
       JNI_THROW_("attachCurrentThread", InternalError, err_msg("Trying to attach thread returned %d", res), false);
     }
     return true;
   }
   JVMCITraceMark jtm("attachCurrentThread");
-  assert(base_thread->is_Java_thread(), "just checking");\
-  JavaThread* thread = (JavaThread*) base_thread;
   if (thread->jni_environment() == env) {
     // Called from HotSpot
     C2V_BLOCK(jboolean, attachCurrentThread, (JNIEnv* env, jobject, jboolean))
     requireJVMCINativeLibrary(JVMCI_CHECK_0);
-    JavaVM* javaVM = requireNativeLibraryJavaVM("attachCurrentThread", JVMCI_CHECK_0);
+    JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+    if (runtime == NULL || !runtime->has_shared_library_javavm()) {
+        JVMCI_THROW_MSG_0(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in attachCurrentThread");
+    }
+
     JavaVMAttachArgs attach_args;
     attach_args.version = JNI_VERSION_1_2;
     attach_args.name = thread->name();
     attach_args.group = NULL;
-    JNIEnv* peerEnv;
-    if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK) {
+    JNIEnv* peerJNIEnv;
+    if (runtime->GetEnv(thread, (void**) &peerJNIEnv, JNI_VERSION_1_2) == JNI_OK) {
       return false;
     }
-    jint res = as_daemon ? javaVM->AttachCurrentThreadAsDaemon((void**)&peerEnv, &attach_args) :
-                           javaVM->AttachCurrentThread((void**)&peerEnv, &attach_args);
+    jint res = as_daemon ? runtime->AttachCurrentThreadAsDaemon(thread, (void**) &peerJNIEnv, &attach_args) :
+                           runtime->AttachCurrentThread(thread, (void**) &peerJNIEnv, &attach_args);
+
     if (res == JNI_OK) {
-      guarantee(peerEnv != NULL, "must be");
+      guarantee(peerJNIEnv != NULL, "must be");
+      TRACE_jvmci_1("attached to JavaVM for JVMCI runtime %d", runtime->id());
       return true;
     }
     JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name));
   }
   // Called from JVMCI shared library
   return false;
 C2V_END
 
 C2V_VMENTRY_PREFIX(void, detachCurrentThread, (JNIEnv* env, jobject c2vm))
-  if (base_thread == NULL) {
+  if (thread == NULL) {
     // Called from unattached JVMCI shared library thread
-    JNI_THROW("detachCurrentThread", IllegalStateException, err_msg("Cannot detach non-attached thread"));
+    JNI_THROW("detachCurrentThread", IllegalStateException, "Cannot detach non-attached thread");
   }
   JVMCITraceMark jtm("detachCurrentThread");
-  assert(base_thread->is_Java_thread(), "just checking");\
-  JavaThread* thread = (JavaThread*) base_thread;
   if (thread->jni_environment() == env) {
     // Called from HotSpot
     C2V_BLOCK(void, detachCurrentThread, (JNIEnv* env, jobject))
     requireJVMCINativeLibrary(JVMCI_CHECK);
     requireInHotSpot("detachCurrentThread", JVMCI_CHECK);
-    JavaVM* javaVM = requireNativeLibraryJavaVM("detachCurrentThread", JVMCI_CHECK);
-    JNIEnv* peerEnv;
-    if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) != JNI_OK) {
+    JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+    if (runtime == NULL || !runtime->has_shared_library_javavm()) {
+      JVMCI_THROW_MSG(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in detachCurrentThread");
+    }
+    JNIEnv* peerJNIEnv;
+    if (runtime->GetEnv(thread, (void**) &peerJNIEnv, JNI_VERSION_1_2) != JNI_OK) {
       JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot detach non-attached thread: %s", thread->name()));
     }
-    jint res = javaVM->DetachCurrentThread();
+    jint res = runtime->DetachCurrentThread(thread);
     if (res != JNI_OK) {
       JVMCI_THROW_MSG(InternalError, err_msg("Error %d while attaching %s", res, thread->name()));
     }
   } else {
     // Called from attached JVMCI shared library thread
     extern struct JavaVM_ main_vm;
     jint res = main_vm.DetachCurrentThread();
     if (res != JNI_OK) {
-      JNI_THROW("detachCurrentThread", InternalError, err_msg("Cannot detach non-attached thread"));
+      JNI_THROW("detachCurrentThread", InternalError, "Cannot detach non-attached thread");
     }
   }
 C2V_END
 
 C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
< prev index next >