< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page
rev 60137 : 8227745: Enable Escape Analysis for Better Performance in the Presence of JVMTI Agents
Reviewed-by: mdoerr, goetz
rev 60138 : 8227745: delta webrev.5 -> webrev.6

*** 2382,2392 **** // so check for other async requests. if (check_asyncs) { check_and_handle_async_exceptions(); } ! if (is_ea_obj_deopt_suspend()) { frame_anchor()->make_walkable(this); wait_for_object_deoptimization(); } JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);) --- 2382,2392 ---- // so check for other async requests. if (check_asyncs) { check_and_handle_async_exceptions(); } ! if (is_obj_deopt_suspend()) { frame_anchor()->make_walkable(this); wait_for_object_deoptimization(); } JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);)
*** 2584,2613 **** void JavaThread::wait_for_object_deoptimization() { assert(!has_last_Java_frame() || frame_anchor()->walkable(), "should have walkable stack"); assert(this == Thread::current(), "invariant"); JavaThreadState state = thread_state(); do { set_thread_state(_thread_blocked); set_suspend_equivalent(); MonitorLocker ml(this, EscapeBarrier_lock, Monitor::_no_safepoint_check_flag); ! if (is_ea_obj_deopt_suspend()) { ml.wait(); } ! if (handle_special_suspend_equivalent_condition()) { ! MutexUnlocker mu(EscapeBarrier_lock, Monitor::_no_safepoint_check_flag); ! java_suspend_self(); } set_thread_state_fence(state); ! } while (is_ea_obj_deopt_suspend()); // Since we are not using a regular thread-state transition helper here, // we must manually emit the instruction barrier after leaving a safe state. OrderAccess::cross_modify_fence(); if (state != _thread_in_native) { SafepointMechanism::block_if_requested(this); } } #ifdef ASSERT // Verify the JavaThread has not yet been published in the Threads::list, and // hence doesn't need protection from concurrent access at this stage. --- 2584,2639 ---- void JavaThread::wait_for_object_deoptimization() { assert(!has_last_Java_frame() || frame_anchor()->walkable(), "should have walkable stack"); assert(this == Thread::current(), "invariant"); JavaThreadState state = thread_state(); + bool should_spin_wait = true; do { set_thread_state(_thread_blocked); set_suspend_equivalent(); + { MonitorLocker ml(this, EscapeBarrier_lock, Monitor::_no_safepoint_check_flag); ! if (EscapeBarrier::deoptimizing_objects_for_all_threads() || ! (is_obj_deopt_suspend() && !should_spin_wait)) { ml.wait(); } ! should_spin_wait = should_spin_wait && is_obj_deopt_suspend(); ! } ! // Single deoptimization is typically very short. Microbenchmarks ! // showed 5% better performance when spinning ! if (should_spin_wait) { ! // Inspired by HandshakeSpinYield ! const jlong max_spin_time_ns = 100 /* us */ * (NANOUNITS / MICROUNITS); ! const int free_cpus = os::active_processor_count() - 1; ! jlong spin_time_ns = (5 /* us */ * (NANOUNITS / MICROUNITS)) * free_cpus; // zero on UP ! spin_time_ns = spin_time_ns > max_spin_time_ns ? max_spin_time_ns : spin_time_ns; ! jlong spin_start = os::javaTimeNanos(); ! while (is_obj_deopt_suspend()) { ! os::naked_yield(); ! if ((os::javaTimeNanos() - spin_start) > spin_time_ns) { ! should_spin_wait = false; ! break; ! } ! } } set_thread_state_fence(state); ! ! if (handle_special_suspend_equivalent_condition()) { ! java_suspend_self_with_safepoint_check(); ! } // Since we are not using a regular thread-state transition helper here, // we must manually emit the instruction barrier after leaving a safe state. OrderAccess::cross_modify_fence(); if (state != _thread_in_native) { SafepointMechanism::block_if_requested(this); } + + // Check for another deopt suspend _after_ checking for safepont/handshake, + // or otherwise a stale value can be seen if the flag was changed with a + // handshake while the current thread was _thread_blocked above. + } while (is_obj_deopt_suspend()); } #ifdef ASSERT // Verify the JavaThread has not yet been published in the Threads::list, and // hence doesn't need protection from concurrent access at this stage.
*** 2635,2645 **** thread->java_suspend_self_with_safepoint_check(); } else { SafepointMechanism::block_if_requested(thread); } ! if (thread->is_ea_obj_deopt_suspend()) { thread->wait_for_object_deoptimization(); } JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(thread);) } --- 2661,2671 ---- thread->java_suspend_self_with_safepoint_check(); } else { SafepointMechanism::block_if_requested(thread); } ! if (thread->is_obj_deopt_suspend()) { thread->wait_for_object_deoptimization(); } JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(thread);) }
*** 4614,4623 **** --- 4640,4652 ---- // Make sure that safepoint code disregard this thread. This is needed since // the thread might mess around with locks after this point. This can cause it // to do callbacks into the safepoint code. However, the safepoint code is not aware // of this thread since it is removed from the queue. p->set_terminated_value(); + + // Notify threads waiting in EscapeBarriers + EscapeBarrier::thread_removed(p); } // unlock Threads_lock // Since Events::log uses a lock, we grab it outside the Threads_lock Events::log(p, "Thread exited: " INTPTR_FORMAT, p2i(p)); }
< prev index next >