--- 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;
}