src/hotspot/share/jvmci/jvmciRuntime.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54973 0927d8c7296f
child 58679 9c3209ff7550
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Oct 17 20:53:35 2019 +0100
@@ -385,8 +385,8 @@
   IF_TRACE_jvmci_3 {
     char type[O_BUFLEN];
     obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    markOop mark = obj->mark();
-    TRACE_jvmci_3("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, p2i(mark), p2i(lock));
+    markWord mark = obj->mark();
+    TRACE_jvmci_3("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, mark.value(), p2i(lock));
     tty->flush();
   }
   if (PrintBiasedLockingStatistics) {
@@ -394,17 +394,7 @@
   }
   Handle h_obj(thread, obj);
   assert(oopDesc::is_oop(h_obj()), "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    if (JVMCIUseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
-    } else {
-      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
-    }
-  }
+  ObjectSynchronizer::enter(h_obj, lock, THREAD);
   TRACE_jvmci_3("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), p2i(obj));
 JRT_END
 
@@ -426,16 +416,11 @@
   }
 #endif
 
-  if (JVMCIUseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
-  }
+  ObjectSynchronizer::exit(obj, lock, THREAD);
   IF_TRACE_jvmci_3 {
     char type[O_BUFLEN];
     obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    TRACE_jvmci_3("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, p2i(obj->mark()), p2i(lock));
+    TRACE_jvmci_3("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, obj->mark().value(), p2i(lock));
     tty->flush();
   }
 JRT_END
@@ -646,7 +631,7 @@
     // The other thread may exit during this process, which is ok so return false.
     return JNI_FALSE;
   } else {
-    return (jint) Thread::is_interrupted(receiverThread, clear_interrupted != 0);
+    return (jint) receiverThread->is_interrupted(clear_interrupted != 0);
   }
 JRT_END
 
@@ -700,11 +685,15 @@
   FailedSpeculation::add_failed_speculation(nm, _failed_speculations, data, length);
 }
 
-oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm) {
+oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm, bool phantom_ref) {
   if (_nmethod_mirror_index == -1) {
     return NULL;
   }
-  return nm->oop_at(_nmethod_mirror_index);
+  if (phantom_ref) {
+    return nm->oop_at_phantom(_nmethod_mirror_index);
+  } else {
+    return nm->oop_at(_nmethod_mirror_index);
+  }
 }
 
 void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) {
@@ -728,7 +717,7 @@
 }
 
 void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) {
-  oop nmethod_mirror = get_nmethod_mirror(nm);
+  oop nmethod_mirror = get_nmethod_mirror(nm, /* phantom_ref */ true);
   if (nmethod_mirror == NULL) {
     return;
   }
@@ -869,17 +858,6 @@
 
 // private void CompilerToVM.registerNatives()
 JVM_ENTRY_NO_ENV(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
-
-#ifdef _LP64
-#ifndef TARGET_ARCH_sparc
-  uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
-  uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
-  guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
-#endif // TARGET_ARCH_sparc
-#else
-  fatal("check TLAB allocation code for address space conflicts");
-#endif
-
   JNI_JVMCIENV(thread, env);
 
   if (!EnableJVMCI) {
@@ -938,8 +916,6 @@
     if (exception->is_a(SystemDictionary::ThreadDeath_klass())) {
       // Don't print anything if we are being killed.
     } else {
-      java_lang_Throwable::print(exception(), tty);
-      tty->cr();
       java_lang_Throwable::print_stack_trace(exception, tty);
 
       // Clear and ignore any exceptions raised during printing
@@ -965,10 +941,8 @@
       describe_pending_hotspot_exception(THREAD, true);
     }
   } else {
-    // Allow error reporting thread to print the stack trace.  Windows
-    // doesn't allow uninterruptible wait for JavaThreads
-    const bool interruptible = true;
-    os::sleep(THREAD, 200, interruptible);
+    // Allow error reporting thread to print the stack trace.
+    THREAD->sleep(200);
   }
 
   before_exit(THREAD);
@@ -1323,24 +1297,27 @@
     return JVMCI::dependencies_failed;
   }
 
-  // Dependencies must be checked when the system dictionary changes
-  // or if we don't know whether it has changed (i.e., compile_state == NULL).
-  bool counter_changed = compile_state == NULL || compile_state->system_dictionary_modification_counter() != SystemDictionary::number_of_modifications();
   CompileTask* task = compile_state == NULL ? NULL : compile_state->task();
-  Dependencies::DepType result = dependencies->validate_dependencies(task, counter_changed, failure_detail);
+  Dependencies::DepType result = dependencies->validate_dependencies(task, failure_detail);
   if (result == Dependencies::end_marker) {
     return JVMCI::ok;
   }
 
-  if (!Dependencies::is_klass_type(result) || counter_changed) {
-    return JVMCI::dependencies_failed;
-  }
-  // The dependencies were invalid at the time of installation
-  // without any intervening modification of the system
-  // dictionary.  That means they were invalidly constructed.
-  return JVMCI::dependencies_invalid;
+  return JVMCI::dependencies_failed;
 }
 
+// Reports a pending exception and exits the VM.
+static void fatal_exception_in_compile(JVMCIEnv* JVMCIENV, JavaThread* thread, const char* msg) {
+  // Only report a fatal JVMCI compilation exception once
+  static volatile int report_init_failure = 0;
+  if (!report_init_failure && Atomic::cmpxchg(1, &report_init_failure, 0) == 0) {
+      tty->print_cr("%s:", msg);
+      JVMCIENV->describe_pending_exception(true);
+  }
+  JVMCIENV->clear_pending_exception();
+  before_exit(thread);
+  vm_exit(-1);
+}
 
 void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& method, int entry_bci) {
   JVMCI_EXCEPTION_CONTEXT
@@ -1362,9 +1339,7 @@
   HandleMark hm;
   JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
   if (JVMCIENV->has_pending_exception()) {
-    JVMCIENV->describe_pending_exception(true);
-    compile_state->set_failure(false, "exception getting HotSpotJVMCIRuntime object");
-    return;
+    fatal_exception_in_compile(JVMCIENV, thread, "Exception during HotSpotJVMCIRuntime initialization");
   }
   JVMCIObject jvmci_method = JVMCIENV->get_jvmci_method(method, JVMCIENV);
   if (JVMCIENV->has_pending_exception()) {
@@ -1397,11 +1372,9 @@
       assert(false, "JVMCICompiler.compileMethod should always return non-null");
     }
   } else {
-    // An uncaught exception was thrown during compilation. Generally these
-    // should be handled by the Java code in some useful way but if they leak
-    // through to here report them instead of dying or silently ignoring them.
-    JVMCIENV->describe_pending_exception(true);
-    compile_state->set_failure(false, "unexpected exception thrown");
+    // An uncaught exception here implies failure during compiler initialization.
+    // The only sensible thing to do here is to exit the VM.
+    fatal_exception_in_compile(JVMCIENV, thread, "Exception during JVMCI compiler initialization");
   }
   if (compiler->is_bootstrapping()) {
     compiler->set_bootstrap_compilation_request_handled();
@@ -1420,6 +1393,7 @@
                                 int frame_words,
                                 OopMapSet* oop_map_set,
                                 ExceptionHandlerTable* handler_table,
+                                ImplicitExceptionTable* implicit_exception_table,
                                 AbstractCompiler* compiler,
                                 DebugInformationRecorder* debug_info,
                                 Dependencies* dependencies,
@@ -1489,7 +1463,6 @@
       // as in C2, then it must be freed.
       //code_buffer->free_blob();
     } else {
-      ImplicitExceptionTable implicit_tbl;
       nm =  nmethod::new_nmethod(method,
                                  compile_id,
                                  entry_bci,
@@ -1497,7 +1470,7 @@
                                  orig_pc_offset,
                                  debug_info, dependencies, code_buffer,
                                  frame_words, oop_map_set,
-                                 handler_table, &implicit_tbl,
+                                 handler_table, implicit_exception_table,
                                  compiler, comp_level,
                                  speculations, speculations_len,
                                  nmethod_mirror_index, nmethod_mirror_name, failed_speculations);
@@ -1524,7 +1497,7 @@
         JVMCINMethodData* data = nm->jvmci_nmethod_data();
         assert(data != NULL, "must be");
         if (install_default) {
-          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == NULL, "must be");
+          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == NULL, "must be");
           if (entry_bci == InvocationEntryBci) {
             if (TieredCompilation) {
               // If there is an old version we're done with it
@@ -1538,32 +1511,35 @@
                 old->make_not_entrant();
               }
             }
-            if (TraceNMethodInstalls) {
+
+            LogTarget(Info, nmethod, install) lt;
+            if (lt.is_enabled()) {
               ResourceMark rm;
               char *method_name = method->name_and_sig_as_C_string();
-              ttyLocker ttyl;
-              tty->print_cr("Installing method (%d) %s [entry point: %p]",
-                            comp_level,
-                            method_name, nm->entry_point());
+              lt.print("Installing method (%d) %s [entry point: %p]",
+                        comp_level, method_name, nm->entry_point());
             }
             // Allow the code to be executed
-            method->set_code(method, nm);
+            MutexLocker ml(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+            if (nm->make_in_use()) {
+              method->set_code(method, nm);
+            }
           } else {
-            if (TraceNMethodInstalls ) {
+            LogTarget(Info, nmethod, install) lt;
+            if (lt.is_enabled()) {
               ResourceMark rm;
               char *method_name = method->name_and_sig_as_C_string();
-              ttyLocker ttyl;
-              tty->print_cr("Installing osr method (%d) %s @ %d",
-                            comp_level,
-                            method_name,
-                            entry_bci);
+              lt.print("Installing osr method (%d) %s @ %d",
+                        comp_level, method_name, entry_bci);
             }
-            InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
+            MutexLocker ml(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+            if (nm->make_in_use()) {
+              InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
+            }
           }
         } else {
-          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == HotSpotJVMCI::resolve(nmethod_mirror), "must be");
+          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == HotSpotJVMCI::resolve(nmethod_mirror), "must be");
         }
-        nm->make_in_use();
       }
       result = nm != NULL ? JVMCI::ok :JVMCI::cache_full;
     }