Skip to content

Commit db950ca

Browse files
Daniel D. Daughertypchilano
Daniel D. Daugherty
andcommittedAug 2, 2021
8271348: Add stronger sanity check of thread state when polling for safepoint/handshakes
Co-authored-by: Patricio Chilano Mateo <pchilanomate@openjdk.org> Reviewed-by: dholmes, pchilanomate
1 parent 3e3051e commit db950ca

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed
 

‎src/hotspot/share/runtime/safepoint.cpp

+17-28
Original file line numberDiff line numberDiff line change
@@ -705,45 +705,34 @@ void SafepointSynchronize::block(JavaThread *thread) {
705705
}
706706

707707
JavaThreadState state = thread->thread_state();
708+
assert(is_a_block_safe_state(state), "Illegal threadstate encountered: %d", state);
708709
thread->frame_anchor()->make_walkable(thread);
709710

710711
uint64_t safepoint_id = SafepointSynchronize::safepoint_counter();
711-
// Check that we have a valid thread_state at this point
712-
switch(state) {
713-
case _thread_in_vm_trans:
714-
case _thread_in_Java: // From compiled code
715-
case _thread_in_native_trans:
716-
case _thread_blocked_trans:
717-
case _thread_new_trans:
718-
719-
// We have no idea where the VMThread is, it might even be at next safepoint.
720-
// So we can miss this poll, but stop at next.
721712

722-
// Load dependent store, it must not pass loading of safepoint_id.
723-
thread->safepoint_state()->set_safepoint_id(safepoint_id); // Release store
713+
// We have no idea where the VMThread is, it might even be at next safepoint.
714+
// So we can miss this poll, but stop at next.
724715

725-
// This part we can skip if we notice we miss or are in a future safepoint.
726-
OrderAccess::storestore();
727-
// Load in wait barrier should not float up
728-
thread->set_thread_state_fence(_thread_blocked);
716+
// Load dependent store, it must not pass loading of safepoint_id.
717+
thread->safepoint_state()->set_safepoint_id(safepoint_id); // Release store
729718

730-
_wait_barrier->wait(static_cast<int>(safepoint_id));
731-
assert(_state != _synchronized, "Can't be");
719+
// This part we can skip if we notice we miss or are in a future safepoint.
720+
OrderAccess::storestore();
721+
// Load in wait barrier should not float up
722+
thread->set_thread_state_fence(_thread_blocked);
732723

733-
// If barrier is disarmed stop store from floating above loads in barrier.
734-
OrderAccess::loadstore();
735-
thread->set_thread_state(state);
724+
_wait_barrier->wait(static_cast<int>(safepoint_id));
725+
assert(_state != _synchronized, "Can't be");
736726

737-
// Then we reset the safepoint id to inactive.
738-
thread->safepoint_state()->reset_safepoint_id(); // Release store
727+
// If barrier is disarmed stop store from floating above loads in barrier.
728+
OrderAccess::loadstore();
729+
thread->set_thread_state(state);
739730

740-
OrderAccess::fence();
731+
// Then we reset the safepoint id to inactive.
732+
thread->safepoint_state()->reset_safepoint_id(); // Release store
741733

742-
break;
734+
OrderAccess::fence();
743735

744-
default:
745-
fatal("Illegal threadstate encountered: %d", state);
746-
}
747736
guarantee(thread->safepoint_state()->get_safepoint_id() == InactiveSafepointCounter,
748737
"The safepoint id should be set only in block path");
749738

‎src/hotspot/share/runtime/safepoint.hpp

+13
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,19 @@ class SafepointSynchronize : AllStatic {
126126
JavaThread *thread,
127127
uint64_t safepoint_count);
128128

129+
static bool is_a_block_safe_state(JavaThreadState state) {
130+
// Check that we have a valid thread_state before blocking for safepoints
131+
switch(state) {
132+
case _thread_in_vm_trans:
133+
case _thread_in_Java: // From compiled code
134+
case _thread_in_native_trans:
135+
case _thread_blocked_trans:
136+
case _thread_new_trans:
137+
return true;
138+
default:
139+
return false;
140+
}
141+
}
129142
// Called when a thread voluntarily blocks
130143
static void block(JavaThread *thread);
131144

‎src/hotspot/share/runtime/safepointMechanism.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ void SafepointMechanism::process(JavaThread *thread, bool allow_suspend) {
118118
// local poll already checked, if used.
119119
bool need_rechecking;
120120
do {
121+
JavaThreadState state = thread->thread_state();
122+
guarantee(SafepointSynchronize::is_a_block_safe_state(state), "Illegal threadstate encountered: %d", state);
121123
if (global_poll()) {
122124
// Any load in ::block() must not pass the global poll load.
123125
// Otherwise we might load an old safepoint counter (for example).

0 commit comments

Comments
 (0)
Please sign in to comment.