diff -r 13588c901957 -r 9cf78a70fa4f src/hotspot/share/jvmci/jvmciRuntime.cpp --- 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; }