mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
Reviewed-by: kvn, twisti
This commit is contained in:
parent
1d736d2851
commit
a96301c84e
5 changed files with 17 additions and 11 deletions
|
@ -215,17 +215,15 @@ bool frame::can_be_deoptimized() const {
|
||||||
return !nm->is_at_poll_return(pc());
|
return !nm->is_at_poll_return(pc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void frame::deoptimize(JavaThread* thread, bool thread_is_known_safe) {
|
void frame::deoptimize(JavaThread* thread) {
|
||||||
// Schedule deoptimization of an nmethod activation with this frame.
|
// 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.
|
|
||||||
|
|
||||||
assert(_cb != NULL && _cb->is_nmethod(), "must be");
|
assert(_cb != NULL && _cb->is_nmethod(), "must be");
|
||||||
nmethod* nm = (nmethod*)_cb;
|
nmethod* nm = (nmethod*)_cb;
|
||||||
|
|
||||||
// This is a fix for register window patching race
|
// 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
|
// It is possible especially with DeoptimizeALot/DeoptimizeRandom that
|
||||||
// we could see the frame again and ask for it to be deoptimized since
|
// 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
|
// whether to spin or block. It isn't worth it. Just treat it like
|
||||||
// native and be done with it.
|
// 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) {
|
if (state == _thread_in_native || state == _thread_in_native_trans) {
|
||||||
// Since we are at a safepoint the target thread will stop itself
|
// 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.
|
// before it can return to java as long as we remain at the safepoint.
|
||||||
|
|
|
@ -174,7 +174,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
|
||||||
address sender_pc() const;
|
address sender_pc() const;
|
||||||
|
|
||||||
// Support for deoptimization
|
// 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;
|
// The frame's original SP, before any extension by an interpreted callee;
|
||||||
// used for packing debug info into vframeArray objects and vframeArray lookup.
|
// used for packing debug info into vframeArray objects and vframeArray lookup.
|
||||||
|
|
|
@ -782,6 +782,9 @@ void ThreadSafepointState::examine_state_of_thread() {
|
||||||
|
|
||||||
JavaThreadState state = _thread->thread_state();
|
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
|
// 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
|
// to grab the Threads_lock which we own here, so a thread cannot be
|
||||||
// resumed during safepoint synchronization.
|
// resumed during safepoint synchronization.
|
||||||
|
|
|
@ -185,6 +185,7 @@ class ThreadSafepointState: public CHeapObj {
|
||||||
|
|
||||||
JavaThread * _thread;
|
JavaThread * _thread;
|
||||||
volatile suspend_type _type;
|
volatile suspend_type _type;
|
||||||
|
JavaThreadState _orig_thread_state;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -199,6 +200,7 @@ class ThreadSafepointState: public CHeapObj {
|
||||||
JavaThread* thread() const { return _thread; }
|
JavaThread* thread() const { return _thread; }
|
||||||
suspend_type type() const { return _type; }
|
suspend_type type() const { return _type; }
|
||||||
bool is_running() const { return (_type==_running); }
|
bool is_running() const { return (_type==_running); }
|
||||||
|
JavaThreadState orig_thread_state() const { return _orig_thread_state; }
|
||||||
|
|
||||||
// Support for safepoint timeout (debugging)
|
// Support for safepoint timeout (debugging)
|
||||||
bool has_called_back() const { return _has_called_back; }
|
bool has_called_back() const { return _has_called_back; }
|
||||||
|
|
|
@ -2110,8 +2110,7 @@ void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread
|
||||||
}
|
}
|
||||||
if (f.id() == thread->must_deopt_id()) {
|
if (f.id() == thread->must_deopt_id()) {
|
||||||
thread->clear_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);
|
||||||
f.deoptimize(thread, true);
|
|
||||||
} else {
|
} else {
|
||||||
fatal("missed deoptimization!");
|
fatal("missed deoptimization!");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue