6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
authornever
Thu, 12 Aug 2010 23:34:34 -0700
changeset 6269 10e06287c0b0
parent 6268 9e96dde307e9
child 6270 d628c75fbf48
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt Reviewed-by: kvn, twisti
hotspot/src/share/vm/runtime/frame.cpp
hotspot/src/share/vm/runtime/frame.hpp
hotspot/src/share/vm/runtime/safepoint.cpp
hotspot/src/share/vm/runtime/safepoint.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/share/vm/runtime/frame.cpp	Thu Aug 12 16:38:23 2010 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Thu Aug 12 23:34:34 2010 -0700
@@ -215,17 +215,15 @@
   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 @@
     // 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.
--- a/hotspot/src/share/vm/runtime/frame.hpp	Thu Aug 12 16:38:23 2010 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Thu Aug 12 23:34:34 2010 -0700
@@ -174,7 +174,7 @@
   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.
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Thu Aug 12 16:38:23 2010 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Thu Aug 12 23:34:34 2010 -0700
@@ -782,6 +782,9 @@
 
   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.
--- a/hotspot/src/share/vm/runtime/safepoint.hpp	Thu Aug 12 16:38:23 2010 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.hpp	Thu Aug 12 23:34:34 2010 -0700
@@ -185,6 +185,7 @@
 
   JavaThread *                   _thread;
   volatile suspend_type          _type;
+  JavaThreadState                _orig_thread_state;
 
 
  public:
@@ -199,6 +200,7 @@
   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; }
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Aug 12 16:38:23 2010 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Aug 12 23:34:34 2010 -0700
@@ -2110,8 +2110,7 @@
     }
     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!");
     }