8223313: Use handshakes for CountStackFrames.
authorrehn
Tue, 21 May 2019 10:46:08 +0200
changeset 54957 b6b02a503d02
parent 54956 43340a79840d
child 54958 55bfc2eee3ab
8223313: Use handshakes for CountStackFrames. Reviewed-by: dholmes, rrich, dcubed
src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/prims/jvm.cpp	Tue May 21 10:36:23 2019 +0200
+++ b/src/hotspot/share/prims/jvm.cpp	Tue May 21 10:46:08 2019 +0200
@@ -64,6 +64,7 @@
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/deoptimization.hpp"
+#include "runtime/handshake.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jfieldIDWorkaround.hpp"
@@ -3006,31 +3007,47 @@
   return JNIHandles::make_local(env, jthread);
 JVM_END
 
+class CountStackFramesTC : public ThreadClosure {
+  int _count;
+  bool _suspended;
+ public:
+  CountStackFramesTC() : _count(0), _suspended(false) {}
+  virtual void do_thread(Thread* thread) {
+    JavaThread* jt = (JavaThread*)thread;
+    if (!jt->is_external_suspend()) {
+      // To keep same behavior we fail this operation,
+      // even if it would work perfectly.
+      return;
+    }
+    _suspended = true;
+     // Count all java activation, i.e., number of vframes.
+    for (vframeStream vfst(jt); !vfst.at_end(); vfst.next()) {
+      // Native frames are not counted.
+      if (!vfst.method()->is_native()) _count++;
+    }
+  }
+  int count() { return _count; }
+  int suspended() { return _suspended; }
+};
 
 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_CountStackFrames");
 
-  uint32_t debug_bits = 0;
   ThreadsListHandle tlh(thread);
   JavaThread* receiver = NULL;
   bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
-  int count = 0;
   if (is_alive) {
     // jthread refers to a live JavaThread.
-    if (receiver->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
-      // Count all java activation, i.e., number of vframes.
-      for (vframeStream vfst(receiver); !vfst.at_end(); vfst.next()) {
-        // Native frames are not counted.
-        if (!vfst.method()->is_native()) count++;
-      }
-    } else {
+    CountStackFramesTC csf;
+    Handshake::execute(&csf, receiver);
+    if (!csf.suspended()) {
       THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
                   "this thread is not suspended");
     }
+    return csf.count();
   }
   // Implied else: if JavaThread is not alive simply return a count of 0.
-
-  return count;
+  return 0;
 JVM_END