8295214: Generational ZGC: Guard nmethods from cross modifying code
Reviewed-by: dholmes, rehn
This commit is contained in:
parent
d4d183edfe
commit
e7c2a8e60e
src/hotspot/share
@ -195,5 +195,6 @@ bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) {
|
||||
|
||||
assert(nm->is_osr_method(), "Should not reach here");
|
||||
log_trace(nmethod, barrier)("Running osr nmethod entry barrier: " PTR_FORMAT, p2i(nm));
|
||||
OrderAccess::cross_modify_fence();
|
||||
return nmethod_entry_barrier(nm);
|
||||
}
|
||||
|
@ -94,12 +94,31 @@ void SafepointMechanism::update_poll_values(JavaThread* thread) {
|
||||
assert(thread == Thread::current(), "Must be");
|
||||
assert(thread->thread_state() != _thread_blocked, "Must not be");
|
||||
assert(thread->thread_state() != _thread_in_native, "Must not be");
|
||||
|
||||
for (;;) {
|
||||
bool armed = global_poll() || thread->handshake_state()->has_operation();
|
||||
uintptr_t stack_watermark = StackWatermarkSet::lowest_watermark(thread);
|
||||
uintptr_t poll_page = armed ? _poll_page_armed_value
|
||||
: _poll_page_disarmed_value;
|
||||
uintptr_t poll_word = compute_poll_word(armed, stack_watermark);
|
||||
uintptr_t prev_poll_word = thread->poll_data()->get_polling_word();
|
||||
|
||||
if (prev_poll_word != poll_word ||
|
||||
prev_poll_word == _poll_word_armed_value) {
|
||||
// While updating the poll value, we allow entering new nmethods
|
||||
// through stack unwinding. The nmethods might have been processed in
|
||||
// a concurrent thread by the GC. So we need to run a cross modify
|
||||
// fence to ensure patching becomes visible. We may also wake up from
|
||||
// a safepoint that has patched code. This cross modify fence will
|
||||
// ensure such paths can observe patched code.
|
||||
// Note that while other threads may arm the thread-local poll of
|
||||
// a thread, only the thread itself has permission to disarm its own
|
||||
// poll value, in any way making it less restrictive. Therefore, whenever
|
||||
// the frontier of what the mutator allows itself to do is increased,
|
||||
// we will catch that here, and ensure a cross modifying fence is used.
|
||||
OrderAccess::cross_modify_fence();
|
||||
}
|
||||
|
||||
thread->poll_data()->set_polling_page(poll_page);
|
||||
thread->poll_data()->set_polling_word(poll_word);
|
||||
OrderAccess::fence();
|
||||
@ -141,7 +160,6 @@ void SafepointMechanism::process(JavaThread *thread, bool allow_suspend, bool ch
|
||||
} while (need_rechecking);
|
||||
|
||||
update_poll_values(thread);
|
||||
OrderAccess::cross_modify_fence();
|
||||
assert(sp_before == thread->last_Java_sp(), "Anchor has changed");
|
||||
}
|
||||
|
||||
|
@ -78,10 +78,6 @@ bool SafepointMechanism::should_process(JavaThread* thread, bool allow_suspend)
|
||||
// 2: We have a suspend or async exception handshake, which cannot be processed.
|
||||
// We update the poll value in case of a disarm, to reduce false positives.
|
||||
update_poll_values(thread);
|
||||
|
||||
// We are now about to avoid processing and thus no cross modify fence will be executed.
|
||||
// In case a safepoint happened, while being blocked, we execute it here.
|
||||
OrderAccess::cross_modify_fence();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user