8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
authorrehn
Thu, 04 Oct 2018 14:03:13 +0200
changeset 52013 92383597fa21
parent 52012 6f58ecdb060a
child 52014 1aa9beac610e
child 56925 6dd05d35378e
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable" Reviewed-by: dcubed, dholmes
src/hotspot/share/runtime/handshake.cpp
--- a/src/hotspot/share/runtime/handshake.cpp	Thu Oct 04 17:25:51 2018 +0530
+++ b/src/hotspot/share/runtime/handshake.cpp	Thu Oct 04 14:03:13 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -347,6 +347,27 @@
          target->is_ext_suspended();
 }
 
+static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
+  // An externally suspended thread cannot be resumed while the
+  // Threads_lock is held so it is safe.
+  // Note that this method is allowed to produce false positives.
+  assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
+  if (target->is_ext_suspended()) {
+    return true;
+  }
+  switch (target->thread_state()) {
+  case _thread_in_native:
+    // native threads are safe if they have no java stack or have walkable stack
+    return !target->has_last_Java_frame() || target->frame_anchor()->walkable();
+
+  case _thread_blocked:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
 bool HandshakeState::claim_handshake_for_vmthread() {
   if (!_semaphore.trywait()) {
     return false;
@@ -366,7 +387,7 @@
     return;
   }
 
-  if (!vmthread_can_process_handshake(target)) {
+  if (!possibly_vmthread_can_process_handshake(target)) {
     // JT is observed in an unsafe state, it must notice the handshake itself
     return;
   }