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