diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp index 89de3ca1a996e1c80978de8f26ebd4455c0e8afc..69d287984993bb49737a027b4833bec834c6aa10 100644 --- a/src/share/vm/runtime/frame.cpp +++ b/src/share/vm/runtime/frame.cpp @@ -215,17 +215,15 @@ bool frame::can_be_deoptimized() const { return !nm->is_at_poll_return(pc()); } -void frame::deoptimize(JavaThread* thread, bool thread_is_known_safe) { -// Schedule deoptimization of an nmethod activation with this frame. - - // Store the original pc before an patch (or request to self-deopt) - // in the published location of the frame. - +void frame::deoptimize(JavaThread* thread) { + // Schedule deoptimization of an nmethod activation with this frame. assert(_cb != NULL && _cb->is_nmethod(), "must be"); nmethod* nm = (nmethod*)_cb; // This is a fix for register window patching race - if (NeedsDeoptSuspend && !thread_is_known_safe) { + if (NeedsDeoptSuspend && Thread::current() != thread) { + assert(SafepointSynchronize::is_at_safepoint(), + "patching other threads for deopt may only occur at a safepoint"); // It is possible especially with DeoptimizeALot/DeoptimizeRandom that // we could see the frame again and ask for it to be deoptimized since @@ -248,7 +246,11 @@ void frame::deoptimize(JavaThread* thread, bool thread_is_known_safe) { // whether to spin or block. It isn't worth it. Just treat it like // native and be done with it. // - JavaThreadState state = thread->thread_state(); + // Examine the state of the thread at the start of safepoint since + // threads that were in native at the start of the safepoint could + // come to a halt during the safepoint, changing the current value + // of the safepoint_state. + JavaThreadState state = thread->safepoint_state()->orig_thread_state(); if (state == _thread_in_native || state == _thread_in_native_trans) { // Since we are at a safepoint the target thread will stop itself // before it can return to java as long as we remain at the safepoint. diff --git a/src/share/vm/runtime/frame.hpp b/src/share/vm/runtime/frame.hpp index 4f2df2ad964135bed9fad49fcba804e9b8650557..a2ac51f3669364610d32752ff63517706f863c49 100644 --- a/src/share/vm/runtime/frame.hpp +++ b/src/share/vm/runtime/frame.hpp @@ -174,7 +174,7 @@ class frame VALUE_OBJ_CLASS_SPEC { address sender_pc() const; // Support for deoptimization - void deoptimize(JavaThread* thread, bool thread_is_known_safe = false); + void deoptimize(JavaThread* thread); // The frame's original SP, before any extension by an interpreted callee; // used for packing debug info into vframeArray objects and vframeArray lookup. diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp index 65d130de103b0c14b62d03aa7ab0ac07a5601f0b..2b51d3037169ad4e0e3c0942a9fd9e124af1d746 100644 --- a/src/share/vm/runtime/safepoint.cpp +++ b/src/share/vm/runtime/safepoint.cpp @@ -782,6 +782,9 @@ void ThreadSafepointState::examine_state_of_thread() { JavaThreadState state = _thread->thread_state(); + // Save the state at the start of safepoint processing. + _orig_thread_state = state; + // Check for a thread that is suspended. Note that thread resume tries // to grab the Threads_lock which we own here, so a thread cannot be // resumed during safepoint synchronization. diff --git a/src/share/vm/runtime/safepoint.hpp b/src/share/vm/runtime/safepoint.hpp index 46d7f3c3b97c96e5f4a8a0d3bb4eb21b0aa78ac4..740cbd61c44df3cb6c755981627b8da2a0080fa3 100644 --- a/src/share/vm/runtime/safepoint.hpp +++ b/src/share/vm/runtime/safepoint.hpp @@ -185,6 +185,7 @@ class ThreadSafepointState: public CHeapObj { JavaThread * _thread; volatile suspend_type _type; + JavaThreadState _orig_thread_state; public: @@ -199,6 +200,7 @@ class ThreadSafepointState: public CHeapObj { JavaThread* thread() const { return _thread; } suspend_type type() const { return _type; } bool is_running() const { return (_type==_running); } + JavaThreadState orig_thread_state() const { return _orig_thread_state; } // Support for safepoint timeout (debugging) bool has_called_back() const { return _has_called_back; } diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index e2ac4f86be88f190d45226934d14bb7424b70fc5..d9fdbbd7511d6c4e59be3ed1188e5418cbf10d9a 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -2110,8 +2110,7 @@ void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread } if (f.id() == thread->must_deopt_id()) { thread->clear_must_deopt_id(); - // Since we know we're safe to deopt the current state is a safe state - f.deoptimize(thread, true); + f.deoptimize(thread); } else { fatal("missed deoptimization!"); }