# HG changeset patch # User rehn # Date 1538654593 -7200 # Node ID 92383597fa212c254bd399cc3772d9d7b13deb53 # Parent 6f58ecdb060a180693f0c60775e78202c7c9e8b8 8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable" Reviewed-by: dcubed, dholmes diff -r 6f58ecdb060a -r 92383597fa21 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; }