8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
authorsspitsyn
Tue, 03 Dec 2013 15:41:35 -0800
changeset 21914 b60984ed653b
parent 21912 8d2924674592
child 21915 d14f8009ad2a
8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers Summary: Fix a race between VMOp_GetCurrentLocation reaching a safepoint and arget thread exiting from Java execution Reviewed-by: sla, dholmes, dsamersoff Contributed-by: serguei.spitsyn@oracle.com
hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	Tue Dec 03 08:36:15 2013 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	Tue Dec 03 15:41:35 2013 -0800
@@ -269,11 +269,20 @@
   void doit() {
     ResourceMark rmark; // _thread != Thread::current()
     RegisterMap rm(_thread, false);
-    javaVFrame* vf = _thread->last_java_vframe(&rm);
-    assert(vf != NULL, "must have last java frame");
-    Method* method = vf->method();
-    _method_id = method->jmethod_id();
-    _bci = vf->bci();
+    // There can be a race condition between a VM_Operation reaching a safepoint
+    // and the target thread exiting from Java execution.
+    // We must recheck the last Java frame still exists.
+    if (_thread->has_last_Java_frame()) {
+      javaVFrame* vf = _thread->last_java_vframe(&rm);
+      assert(vf != NULL, "must have last java frame");
+      Method* method = vf->method();
+      _method_id = method->jmethod_id();
+      _bci = vf->bci();
+    } else {
+      // Clear current location as the target thread has no Java frames anymore.
+      _method_id = (jmethodID)NULL;
+      _bci = 0;
+    }
   }
   void get_current_location(jmethodID *method_id, int *bci) {
     *method_id = _method_id;