8254263: Remove special_runtime_exit_condition() check from ~ThreadInVMForHandshake()

Reviewed-by: rrich, dholmes, dcubed, rehn
This commit is contained in:
Patricio Chilano Mateo 2020-10-14 22:15:57 +00:00
parent 03fa733e8b
commit 55d760d416
4 changed files with 23 additions and 35 deletions

View File

@ -406,6 +406,10 @@ HandshakeOperation* HandshakeState::pop() {
};
void HandshakeState::process_by_self() {
assert(Thread::current() == _handshakee, "should call from _handshakee");
assert(!_handshakee->is_terminated(), "should not be a terminated thread");
assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state");
assert(_handshakee->thread_state() != _thread_in_native, "should not be in native");
ThreadInVMForHandshake tivm(_handshakee);
{
NoSafepointVerifier nsv;
@ -414,11 +418,6 @@ void HandshakeState::process_by_self() {
}
void HandshakeState::process_self_inner() {
assert(Thread::current() == _handshakee, "should call from _handshakee");
assert(!_handshakee->is_terminated(), "should not be a terminated thread");
assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state");
assert(_handshakee->thread_state() != _thread_in_native, "should not be in native");
while (should_process()) {
HandleMark hm(_handshakee);
CautiouslyPreserveExceptionMark pem(_handshakee);

View File

@ -128,22 +128,7 @@ class ThreadStateTransition : public StackObj {
class ThreadInVMForHandshake : public ThreadStateTransition {
const JavaThreadState _original_state;
void transition_back() {
// This can be invoked from transition states and must return to the original state properly
assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
_thread->set_thread_state(_original_state);
if (_original_state != _thread_blocked_trans && _original_state != _thread_in_vm_trans &&
_thread->has_special_runtime_exit_condition()) {
_thread->handle_special_runtime_exit_condition(
!_thread->is_at_poll_safepoint() && (_original_state != _thread_in_native_trans));
}
}
public:
ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
_original_state(thread->thread_state()) {
@ -158,7 +143,8 @@ class ThreadInVMForHandshake : public ThreadStateTransition {
}
~ThreadInVMForHandshake() {
transition_back();
assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
_thread->set_thread_state(_original_state);
}
};

View File

@ -943,19 +943,21 @@ void ThreadSafepointState::print_on(outputStream *st) const {
// Process pending operation.
void ThreadSafepointState::handle_polling_page_exception() {
JavaThread* self = thread();
assert(self == Thread::current()->as_Java_thread(), "must be self");
// Step 1: Find the nmethod from the return address
address real_return_addr = thread()->saved_exception_pc();
address real_return_addr = self->saved_exception_pc();
CodeBlob *cb = CodeCache::find_blob(real_return_addr);
assert(cb != NULL && cb->is_compiled(), "return address should be in nmethod");
CompiledMethod* nm = (CompiledMethod*)cb;
// Find frame of caller
frame stub_fr = thread()->last_frame();
frame stub_fr = self->last_frame();
CodeBlob* stub_cb = stub_fr.cb();
assert(stub_cb->is_safepoint_stub(), "must be a safepoint stub");
RegisterMap map(thread(), true, false);
RegisterMap map(self, true, false);
frame caller_fr = stub_fr.sender(&map);
// Should only be poll_return or poll
@ -976,17 +978,18 @@ void ThreadSafepointState::handle_polling_page_exception() {
// to keep it in a handle.
oop result = caller_fr.saved_oop_result(&map);
assert(oopDesc::is_oop_or_null(result), "must be oop");
return_value = Handle(thread(), result);
return_value = Handle(self, result);
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// We get here if compiled return polls found a reason to call into the VM.
// One condition for that is that the top frame is not yet safe to use.
// The following stack watermark barrier poll will catch such situations.
StackWatermarkSet::after_unwind(thread());
StackWatermarkSet::after_unwind(self);
// Process pending operation
SafepointMechanism::process_if_requested(thread());
SafepointMechanism::process_if_requested(self);
self->check_and_handle_async_exceptions();
// restore oop result, if any
if (return_oop) {
@ -1002,21 +1005,21 @@ void ThreadSafepointState::handle_polling_page_exception() {
assert(real_return_addr == caller_fr.pc(), "must match");
// Process pending operation
SafepointMechanism::process_if_requested(thread());
SafepointMechanism::process_if_requested(self);
set_at_poll_safepoint(false);
// If we have a pending async exception deoptimize the frame
// as otherwise we may never deliver it.
if (thread()->has_async_condition()) {
ThreadInVMfromJavaNoAsyncException __tiv(thread());
Deoptimization::deoptimize_frame(thread(), caller_fr.id());
if (self->has_async_condition()) {
ThreadInVMfromJavaNoAsyncException __tiv(self);
Deoptimization::deoptimize_frame(self, caller_fr.id());
}
// If an exception has been installed we must check for a pending deoptimization
// Deoptimize frame if exception has been thrown.
if (thread()->has_pending_exception() ) {
RegisterMap map(thread(), true, false);
if (self->has_pending_exception() ) {
RegisterMap map(self, true, false);
frame caller_fr = stub_fr.sender(&map);
if (caller_fr.is_deoptimized_frame()) {
// The exception patch will destroy registers that are still

View File

@ -80,7 +80,7 @@ void SafepointMechanism::process(JavaThread *thread) {
// Any load in ::block must not pass the global poll load.
// Otherwise we might load an old safepoint counter (for example).
OrderAccess::loadload();
SafepointSynchronize::block(thread);
SafepointSynchronize::block(thread); // Recursive
}
// The call to start_processing fixes the thread's oops and the first few frames.
@ -92,7 +92,7 @@ void SafepointMechanism::process(JavaThread *thread) {
StackWatermarkSet::start_processing(thread, StackWatermarkKind::gc);
if (thread->handshake_state()->should_process()) {
thread->handshake_state()->process_by_self(); // Recursive
thread->handshake_state()->process_by_self();
}
}