1af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe/* Copyright (C) 2017 The Android Open Source Project 2af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 4af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This file implements interfaces from the file jvmti.h. This implementation 5af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * is licensed under the same terms as the file jvmti.h. The 6af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * copyright and license information for the file jvmti.h follows. 7af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 8af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 11af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is free software; you can redistribute it and/or modify it 12af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * under the terms of the GNU General Public License version 2 only, as 13af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * published by the Free Software Foundation. Oracle designates this 14af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * particular file as subject to the "Classpath" exception as provided 15af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * by Oracle in the LICENSE file that accompanied this code. 16af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 17af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT 18af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * version 2 for more details (a copy is included in the LICENSE file that 21af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * accompanied this code). 22af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 23af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * You should have received a copy of the GNU General Public License version 24af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 2 along with this work; if not, write to the Free Software Foundation, 25af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 27af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * or visit www.oracle.com if you need additional information or have any 29af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * questions. 30af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe */ 31af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 32af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "ti_thread.h" 33af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 3457943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include <android-base/logging.h> 3557943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include <android-base/strings.h> 3657943810cfc789da890d73621741729da5feaaf8Andreas Gampe 37a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field-inl.h" 38af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_jvmti.h" 39af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/mutex.h" 40eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "events-inl.h" 41f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc/system_weak.h" 42d9aff1372e6a2f573b14d124f3d6f5305bdc6080Alex Light#include "gc/collector_type.h" 43d9aff1372e6a2f573b14d124f3d6f5305bdc6080Alex Light#include "gc/gc_cause.h" 44d9aff1372e6a2f573b14d124f3d6f5305bdc6080Alex Light#include "gc/scoped_gc_critical_section.h" 45f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc_root-inl.h" 46af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "jni_internal.h" 47af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/class.h" 48af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/object-inl.h" 49af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/string.h" 50373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h" 519311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light#include "nativehelper/scoped_utf_chars.h" 52af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "obj_ptr.h" 53f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "runtime.h" 54eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "runtime_callbacks.h" 55af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "scoped_thread_state_change-inl.h" 56b486a98aadc95d80548953410cf23edba62259faAndreas Gampe#include "thread-current-inl.h" 578580744607a963d408956c3eb712b0e070c139b0Andreas Gampe#include "thread_list.h" 58e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "ti_phase.h" 59af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "well_known_classes.h" 60af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 61af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampenamespace openjdkjvmti { 62af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 63db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampeart::ArtField* ThreadUtil::context_class_loader_ = nullptr; 64db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe 651d8a9741d2979d09a21942fbf9107d212ce2511bAlex Lightstruct ThreadCallback : public art::ThreadLifecycleCallback { 66eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 67eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (self->GetPeer() == nullptr) { 68eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return nullptr; 69eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 70eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer()); 71eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 721d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light 73983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe template <ArtJvmtiEvent kEvent> 74983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 75eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe DCHECK_EQ(self, art::Thread::Current()); 76eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self)); 77e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 78983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe event_handler->DispatchEvent<kEvent>(self, 79983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe reinterpret_cast<JNIEnv*>(self->GetJniEnv()), 80983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe thread.get()); 81eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 82eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 83eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe void ThreadStart(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 84eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (!started) { 85eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // Runtime isn't started. We only expect at most the signal handler or JIT threads to be 86eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // started here. 87eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (art::kIsDebugBuild) { 88eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe std::string name; 89eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe self->GetThreadName(name); 905bd09549b443659ddd81768c811dcb5c6850775cAlex Light if (name != "JDWP" && 915bd09549b443659ddd81768c811dcb5c6850775cAlex Light name != "Signal Catcher" && 925bd09549b443659ddd81768c811dcb5c6850775cAlex Light !android::base::StartsWith(name, "Jit thread pool")) { 9323aa74818272a9d659414536324ae9133ecb8743Alex Light LOG(FATAL) << "Unexpected thread before start: " << name << " id: " 9423aa74818272a9d659414536324ae9133ecb8743Alex Light << self->GetThreadId(); 95eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 96eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 97eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return; 98eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 99983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe Post<ArtJvmtiEvent::kThreadStart>(self); 100eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 101eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 102eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe void ThreadDeath(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 103983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe Post<ArtJvmtiEvent::kThreadEnd>(self); 104eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 105eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 106eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe EventHandler* event_handler = nullptr; 107eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe bool started = false; 108eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}; 109eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 110eafaf57557939bcabeb7a7388fb4951e74661a53Andreas GampeThreadCallback gThreadCallback; 111eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 112eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Register(EventHandler* handler) { 113eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::Runtime* runtime = art::Runtime::Current(); 114eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 115eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe gThreadCallback.started = runtime->IsStarted(); 116eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe gThreadCallback.event_handler = handler; 117eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 118eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedThreadStateChange stsc(art::Thread::Current(), 119eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ThreadState::kWaitingForDebuggerToAttach); 120eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedSuspendAll ssa("Add thread callback"); 121eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback); 1221d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light} 1231d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light 1241d8a9741d2979d09a21942fbf9107d212ce2511bAlex Lightvoid ThreadUtil::VMInitEventSent() { 1251d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light // We should have already started. 1261d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light DCHECK(gThreadCallback.started); 1271d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light // We moved to VMInit. Report the main thread as started (it was attached early, and must not be 1281d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light // reported until Init. 1291d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light gThreadCallback.Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current()); 130eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe} 131eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 132db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampevoid ThreadUtil::CacheData() { 1331d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light // We must have started since it is now safe to cache our data; 1341d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light gThreadCallback.started = true; 135db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 136db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe art::ObjPtr<art::mirror::Class> thread_class = 137db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread); 138db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe CHECK(thread_class != nullptr); 139db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader", 140db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe "Ljava/lang/ClassLoader;"); 141db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe CHECK(context_class_loader_ != nullptr); 142db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe} 143db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe 144eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Unregister() { 145eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedThreadStateChange stsc(art::Thread::Current(), 146eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ThreadState::kWaitingForDebuggerToAttach); 147eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedSuspendAll ssa("Remove thread callback"); 148eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::Runtime* runtime = art::Runtime::Current(); 149eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback); 150eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe} 151eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 152af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) { 153af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::Thread* self = art::Thread::Current(); 154af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 155af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ScopedObjectAccess soa(self); 156af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 157af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe jthread thread_peer; 158af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (self->IsStillStarting()) { 159af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe thread_peer = nullptr; 160af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 161af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe thread_peer = soa.AddLocalReference<jthread>(self->GetPeer()); 162af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 163af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 164af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *thread_ptr = thread_peer; 165af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NONE); 166af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 167af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 168af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Get the native thread. The spec says a null object denotes the current thread. 1697ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightbool ThreadUtil::GetNativeThread(jthread thread, 1707ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light const art::ScopedObjectAccessAlreadyRunnable& soa, 1717ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light /*out*/ art::Thread** thr, 1727ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light /*out*/ jvmtiError* err) { 173af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (thread == nullptr) { 1747ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light *thr = art::Thread::Current(); 1757ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return true; 1767ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else if (!soa.Env()->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { 1777ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light *err = ERR(INVALID_THREAD); 1787ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return false; 1797ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else { 1807ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light *thr = art::Thread::FromManagedThread(soa, thread); 1817ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return true; 182af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 1837ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light} 184af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 1857ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightbool ThreadUtil::GetAliveNativeThread(jthread thread, 1867ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light const art::ScopedObjectAccessAlreadyRunnable& soa, 1877ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light /*out*/ art::Thread** thr, 1887ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light /*out*/ jvmtiError* err) { 1897ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetNativeThread(thread, soa, thr, err)) { 1907ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return false; 1917ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else if (*thr == nullptr || (*thr)->GetState() == art::ThreadState::kTerminated) { 1927ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light *err = ERR(THREAD_NOT_ALIVE); 1937ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return false; 1947ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else { 1957ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return true; 1967ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } 197af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 198af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 199af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) { 200af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (info_ptr == nullptr) { 201af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NULL_POINTER); 202af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 203db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe if (!PhaseUtil::IsLivePhase()) { 204db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe return JVMTI_ERROR_WRONG_PHASE; 205db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe } 206af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2073ae82531b336b195a78c864c28af1448a74af633Alex Light art::Thread* self = art::Thread::Current(); 2083ae82531b336b195a78c864c28af1448a74af633Alex Light art::ScopedObjectAccess soa(self); 2093ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 210af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2117ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target; 2127ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 2137ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetNativeThread(thread, soa, &target, &err)) { 2147ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 215af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 216af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2175471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe JvmtiUniquePtr<char[]> name_uptr; 2183ae82531b336b195a78c864c28af1448a74af633Alex Light if (target != nullptr) { 219af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Have a native thread object, this thread is alive. 220af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe std::string name; 2213ae82531b336b195a78c864c28af1448a74af633Alex Light target->GetThreadName(name); 2225471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe jvmtiError name_result; 2235471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe name_uptr = CopyString(env, name.c_str(), &name_result); 2245471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe if (name_uptr == nullptr) { 225af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return name_result; 226af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 2275471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe info_ptr->name = name_uptr.get(); 228af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2293ae82531b336b195a78c864c28af1448a74af633Alex Light info_ptr->priority = target->GetNativePriority(); 230af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2313ae82531b336b195a78c864c28af1448a74af633Alex Light info_ptr->is_daemon = target->IsDaemon(); 232af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 2333ae82531b336b195a78c864c28af1448a74af633Alex Light art::ObjPtr<art::mirror::Object> peer = target->GetPeerFromOtherThread(); 234af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 235af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // ThreadGroup. 236af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (peer != nullptr) { 237af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 238af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 239af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 240af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = group == nullptr 241af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 242af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jthreadGroup>(group); 243af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 244af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = nullptr; 245af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 246af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 247af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Context classloader. 248db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe DCHECK(context_class_loader_ != nullptr); 249db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe art::ObjPtr<art::mirror::Object> ccl = peer != nullptr 250db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe ? context_class_loader_->GetObject(peer) 251db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe : nullptr; 252af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->context_class_loader = ccl == nullptr 253af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 254af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jobject>(ccl); 255af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 256af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Only the peer. This thread has either not been started, or is dead. Read things from 257af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // the Java side. 258af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread); 259af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 260af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Name. 261af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 262af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name); 263af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 264af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> name = f->GetObject(peer); 265af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe std::string name_cpp; 266af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe const char* name_cstr; 267af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (name != nullptr) { 268af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cpp = name->AsString()->ToModifiedUtf8(); 269af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cstr = name_cpp.c_str(); 270af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 271af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cstr = ""; 272af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 2735471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe jvmtiError name_result; 2745471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe name_uptr = CopyString(env, name_cstr, &name_result); 2755471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe if (name_uptr == nullptr) { 276af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return name_result; 277af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 2785471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe info_ptr->name = name_uptr.get(); 279af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 280af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 281af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Priority. 282af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 283af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority); 284af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 285af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->priority = static_cast<jint>(f->GetInt(peer)); 286af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 287af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 288af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Daemon. 289af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 290af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon); 291af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 292af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE; 293af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 294af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 295af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // ThreadGroup. 296af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 297af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 298af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 299af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 300af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = group == nullptr 301af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 302af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jthreadGroup>(group); 303af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 304af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 305af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Context classloader. 306db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe DCHECK(context_class_loader_ != nullptr); 307db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe art::ObjPtr<art::mirror::Object> ccl = peer != nullptr 308db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe ? context_class_loader_->GetObject(peer) 309db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe : nullptr; 310af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->context_class_loader = ccl == nullptr 311af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 312af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jobject>(ccl); 313af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 314af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 315af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_uptr.release(); 316af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 317af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NONE); 318af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 319af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 3201f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstruct InternalThreadState { 3211f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::Thread* native_thread; 3221f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::ThreadState art_state; 3231f0a22f486873063246e64ec6bb38238987ae23eAlex Light int thread_user_code_suspend_count; 3241f0a22f486873063246e64ec6bb38238987ae23eAlex Light}; 3251f0a22f486873063246e64ec6bb38238987ae23eAlex Light 3261f0a22f486873063246e64ec6bb38238987ae23eAlex Light// Return the thread's (or current thread, if null) thread state. 3277ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightstatic InternalThreadState GetNativeThreadState(art::Thread* target) 3281f0a22f486873063246e64ec6bb38238987ae23eAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) 3293ae82531b336b195a78c864c28af1448a74af633Alex Light REQUIRES(art::Locks::thread_list_lock_, art::Locks::user_code_suspension_lock_) { 3301f0a22f486873063246e64ec6bb38238987ae23eAlex Light InternalThreadState thread_state = {}; 3317ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::MutexLock tscl_mu(art::Thread::Current(), *art::Locks::thread_suspend_count_lock_); 3327ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light thread_state.native_thread = target; 3337ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (target == nullptr || target->IsStillStarting()) { 3341f0a22f486873063246e64ec6bb38238987ae23eAlex Light thread_state.art_state = art::ThreadState::kStarting; 3351f0a22f486873063246e64ec6bb38238987ae23eAlex Light thread_state.thread_user_code_suspend_count = 0; 3361f0a22f486873063246e64ec6bb38238987ae23eAlex Light } else { 3377ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light thread_state.art_state = target->GetState(); 3387ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light thread_state.thread_user_code_suspend_count = target->GetUserCodeSuspendCount(); 33972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 3401f0a22f486873063246e64ec6bb38238987ae23eAlex Light return thread_state; 34172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 34272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 3431f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstatic jint GetJvmtiThreadStateFromInternal(const InternalThreadState& state) { 3441f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::ThreadState internal_thread_state = state.art_state; 34572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint jvmti_state = JVMTI_THREAD_STATE_ALIVE; 34672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 3471f0a22f486873063246e64ec6bb38238987ae23eAlex Light if (state.thread_user_code_suspend_count != 0) { 348597adad749499bc2da85851273e7623f6b249d1eAlex Light // Suspended can be set with any thread state so check it here. Even if the thread isn't in 349597adad749499bc2da85851273e7623f6b249d1eAlex Light // kSuspended state it will move to that once it hits a checkpoint so we can still set this. 35072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED; 35172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Note: We do not have data about the previous state. Otherwise we should load the previous 35272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // state here. 35372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 35472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 3551f0a22f486873063246e64ec6bb38238987ae23eAlex Light if (state.native_thread->IsInterrupted()) { 356597adad749499bc2da85851273e7623f6b249d1eAlex Light // Interrupted can be set with any thread state so check it here. 3571f0a22f486873063246e64ec6bb38238987ae23eAlex Light jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED; 3581f0a22f486873063246e64ec6bb38238987ae23eAlex Light } 3591f0a22f486873063246e64ec6bb38238987ae23eAlex Light 360597adad749499bc2da85851273e7623f6b249d1eAlex Light // Enumerate all the thread states and fill in the other bits. This contains the results of 361597adad749499bc2da85851273e7623f6b249d1eAlex Light // following the decision tree in the JVMTI spec GetThreadState documentation. 362597adad749499bc2da85851273e7623f6b249d1eAlex Light switch (internal_thread_state) { 363597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kRunnable: 364597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingWeakGcRootRead: 365597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kSuspended: 366597adad749499bc2da85851273e7623f6b249d1eAlex Light // These are all simply runnable. 367597adad749499bc2da85851273e7623f6b249d1eAlex Light // kRunnable is self-explanatory. 368597adad749499bc2da85851273e7623f6b249d1eAlex Light // kWaitingWeakGcRootRead is set during some operations with strings due to the intern-table 369597adad749499bc2da85851273e7623f6b249d1eAlex Light // so we want to keep it marked as runnable. 370597adad749499bc2da85851273e7623f6b249d1eAlex Light // kSuspended we don't mark since if we don't have a user_code_suspend_count then it is done 371597adad749499bc2da85851273e7623f6b249d1eAlex Light // by the GC and not a JVMTI suspension, which means it cannot be removed by ResumeThread. 372597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE; 373597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 374597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kNative: 375597adad749499bc2da85851273e7623f6b249d1eAlex Light // kNative means native and runnable. Technically THREAD_STATE_IN_NATIVE can be set with any 376597adad749499bc2da85851273e7623f6b249d1eAlex Light // state but we don't have the information to know if it should be present for any but the 377597adad749499bc2da85851273e7623f6b249d1eAlex Light // kNative state. 378597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= (JVMTI_THREAD_STATE_IN_NATIVE | 379597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_RUNNABLE); 380597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 381597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kBlocked: 382597adad749499bc2da85851273e7623f6b249d1eAlex Light // Blocked is one of the top level states so it sits alone. 383597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; 384597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 385597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaiting: 386597adad749499bc2da85851273e7623f6b249d1eAlex Light // Object.wait() so waiting, indefinitely, in object.wait. 387597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= (JVMTI_THREAD_STATE_WAITING | 388597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_WAITING_INDEFINITELY | 389597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_IN_OBJECT_WAIT); 390597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 391597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kTimedWaiting: 392597adad749499bc2da85851273e7623f6b249d1eAlex Light // Object.wait(long) so waiting, with timeout, in object.wait. 393597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= (JVMTI_THREAD_STATE_WAITING | 394597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | 395597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_IN_OBJECT_WAIT); 396597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 397597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kSleeping: 398597adad749499bc2da85851273e7623f6b249d1eAlex Light // In object.sleep. This is a timed wait caused by sleep. 399597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= (JVMTI_THREAD_STATE_WAITING | 400597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT | 401597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_SLEEPING); 402597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 403597adad749499bc2da85851273e7623f6b249d1eAlex Light // TODO We might want to print warnings if we have the debugger running while JVMTI agents are 404597adad749499bc2da85851273e7623f6b249d1eAlex Light // attached. 405597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForDebuggerSend: 406597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForDebuggerToAttach: 407597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingInMainDebuggerLoop: 408597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForDebuggerSuspension: 409597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForLockInflation: 410597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForTaskProcessor: 411597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForGcToComplete: 412597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForCheckPointsToRun: 413597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingPerformingGc: 414597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForJniOnLoad: 415597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingInMainSignalCatcherLoop: 416597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForSignalCatcherOutput: 417597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForDeoptimization: 418597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForMethodTracingStart: 419597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForVisitObjects: 420597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForGetObjectsAllocated: 421597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kWaitingForGcThreadFlip: 422597adad749499bc2da85851273e7623f6b249d1eAlex Light // All of these are causing the thread to wait for an indeterminate amount of time but isn't 423597adad749499bc2da85851273e7623f6b249d1eAlex Light // caused by sleep, park, or object#wait. 424597adad749499bc2da85851273e7623f6b249d1eAlex Light jvmti_state |= (JVMTI_THREAD_STATE_WAITING | 425597adad749499bc2da85851273e7623f6b249d1eAlex Light JVMTI_THREAD_STATE_WAITING_INDEFINITELY); 426597adad749499bc2da85851273e7623f6b249d1eAlex Light break; 427597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kStarting: 428597adad749499bc2da85851273e7623f6b249d1eAlex Light case art::ThreadState::kTerminated: 429597adad749499bc2da85851273e7623f6b249d1eAlex Light // We only call this if we are alive so we shouldn't see either of these states. 430597adad749499bc2da85851273e7623f6b249d1eAlex Light LOG(FATAL) << "Should not be in state " << internal_thread_state; 431597adad749499bc2da85851273e7623f6b249d1eAlex Light UNREACHABLE(); 43272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 433597adad749499bc2da85851273e7623f6b249d1eAlex Light // TODO: PARKED. We'll have to inspect the stack. 43472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 43572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return jvmti_state; 43672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 43772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 4381f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstatic jint GetJavaStateFromInternal(const InternalThreadState& state) { 4391f0a22f486873063246e64ec6bb38238987ae23eAlex Light switch (state.art_state) { 44072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kTerminated: 44172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 44272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 44372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kRunnable: 44472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kNative: 44572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingWeakGcRootRead: 44672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kSuspended: 44772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE; 44872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 44972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kTimedWaiting: 45072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kSleeping: 45172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING; 45272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 45372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kBlocked: 45472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED; 45572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 45672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kStarting: 45772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_NEW; 45872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 45972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaiting: 46077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case art::ThreadState::kWaitingForTaskProcessor: 46177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case art::ThreadState::kWaitingForLockInflation: 46272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGcToComplete: 46372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingPerformingGc: 46472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForCheckPointsToRun: 46572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerSend: 46672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerToAttach: 46772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingInMainDebuggerLoop: 46872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerSuspension: 46972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDeoptimization: 47072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGetObjectsAllocated: 47172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForJniOnLoad: 47272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForSignalCatcherOutput: 47372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingInMainSignalCatcherLoop: 47472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForMethodTracingStart: 47572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForVisitObjects: 47672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGcThreadFlip: 47772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_WAITING; 47872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 47972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe LOG(FATAL) << "Unreachable"; 48072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe UNREACHABLE(); 48172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 48272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 4831f0a22f486873063246e64ec6bb38238987ae23eAlex Light// Suspends the current thread if it has any suspend requests on it. 48423aa74818272a9d659414536324ae9133ecb8743Alex Lightvoid ThreadUtil::SuspendCheck(art::Thread* self) { 4851f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::ScopedObjectAccess soa(self); 4861f0a22f486873063246e64ec6bb38238987ae23eAlex Light // Really this is only needed if we are in FastJNI and actually have the mutator_lock_ already. 4871f0a22f486873063246e64ec6bb38238987ae23eAlex Light self->FullSuspendCheck(); 4881f0a22f486873063246e64ec6bb38238987ae23eAlex Light} 4891f0a22f486873063246e64ec6bb38238987ae23eAlex Light 49023aa74818272a9d659414536324ae9133ecb8743Alex Lightbool ThreadUtil::WouldSuspendForUserCodeLocked(art::Thread* self) { 49123aa74818272a9d659414536324ae9133ecb8743Alex Light DCHECK(self == art::Thread::Current()); 49223aa74818272a9d659414536324ae9133ecb8743Alex Light art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_); 49323aa74818272a9d659414536324ae9133ecb8743Alex Light return self->GetUserCodeSuspendCount() != 0; 49423aa74818272a9d659414536324ae9133ecb8743Alex Light} 49523aa74818272a9d659414536324ae9133ecb8743Alex Light 49623aa74818272a9d659414536324ae9133ecb8743Alex Lightbool ThreadUtil::WouldSuspendForUserCode(art::Thread* self) { 49723aa74818272a9d659414536324ae9133ecb8743Alex Light DCHECK(self == art::Thread::Current()); 49823aa74818272a9d659414536324ae9133ecb8743Alex Light art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_); 49923aa74818272a9d659414536324ae9133ecb8743Alex Light return WouldSuspendForUserCodeLocked(self); 50023aa74818272a9d659414536324ae9133ecb8743Alex Light} 50123aa74818272a9d659414536324ae9133ecb8743Alex Light 50272c19834136c81eace33687e06f5daf92a5a7583Andreas GampejvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED, 50372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jthread thread, 50472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint* thread_state_ptr) { 50572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (thread_state_ptr == nullptr) { 50672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NULL_POINTER); 50772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 50872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5091f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::Thread* self = art::Thread::Current(); 5101f0a22f486873063246e64ec6bb38238987ae23eAlex Light InternalThreadState state = {}; 5111f0a22f486873063246e64ec6bb38238987ae23eAlex Light // Loop since we need to bail out and try again if we would end up getting suspended while holding 5121f0a22f486873063246e64ec6bb38238987ae23eAlex Light // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we 5131f0a22f486873063246e64ec6bb38238987ae23eAlex Light // release the lock, wait to get resumed and try again. 5141f0a22f486873063246e64ec6bb38238987ae23eAlex Light do { 5151f0a22f486873063246e64ec6bb38238987ae23eAlex Light SuspendCheck(self); 5161f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_); 51723aa74818272a9d659414536324ae9133ecb8743Alex Light if (WouldSuspendForUserCodeLocked(self)) { 51823aa74818272a9d659414536324ae9133ecb8743Alex Light // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by 51923aa74818272a9d659414536324ae9133ecb8743Alex Light // a user-code suspension. We retry and do another SuspendCheck to clear this. 52023aa74818272a9d659414536324ae9133ecb8743Alex Light continue; 5211f0a22f486873063246e64ec6bb38238987ae23eAlex Light } 5221f0a22f486873063246e64ec6bb38238987ae23eAlex Light art::ScopedObjectAccess soa(self); 5233ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_); 5247ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 5257ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 5267ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetNativeThread(thread, soa, &target, &err)) { 5277ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 5287ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } 5297ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light state = GetNativeThreadState(target); 5303ae82531b336b195a78c864c28af1448a74af633Alex Light if (state.art_state == art::ThreadState::kStarting) { 5313ae82531b336b195a78c864c28af1448a74af633Alex Light break; 53272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 5333ae82531b336b195a78c864c28af1448a74af633Alex Light DCHECK(state.native_thread != nullptr); 53472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5353ae82531b336b195a78c864c28af1448a74af633Alex Light // Translate internal thread state to JVMTI and Java state. 5363ae82531b336b195a78c864c28af1448a74af633Alex Light jint jvmti_state = GetJvmtiThreadStateFromInternal(state); 5373ae82531b336b195a78c864c28af1448a74af633Alex Light 5383ae82531b336b195a78c864c28af1448a74af633Alex Light // Java state is derived from nativeGetState. 5393ae82531b336b195a78c864c28af1448a74af633Alex Light // TODO: Our implementation assigns "runnable" to suspended. As such, we will have slightly 5403ae82531b336b195a78c864c28af1448a74af633Alex Light // different mask if a thread got suspended due to user-code. However, this is for 5413ae82531b336b195a78c864c28af1448a74af633Alex Light // consistency with the Java view. 5423ae82531b336b195a78c864c28af1448a74af633Alex Light jint java_state = GetJavaStateFromInternal(state); 5433ae82531b336b195a78c864c28af1448a74af633Alex Light 5443ae82531b336b195a78c864c28af1448a74af633Alex Light *thread_state_ptr = jvmti_state | java_state; 5451f0a22f486873063246e64ec6bb38238987ae23eAlex Light 54672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NONE); 5473ae82531b336b195a78c864c28af1448a74af633Alex Light } while (true); 54872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5493ae82531b336b195a78c864c28af1448a74af633Alex Light DCHECK_EQ(state.art_state, art::ThreadState::kStarting); 55072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5513ae82531b336b195a78c864c28af1448a74af633Alex Light if (thread == nullptr) { 5523ae82531b336b195a78c864c28af1448a74af633Alex Light // No native thread, and no Java thread? We must be starting up. Report as wrong phase. 5533ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(WRONG_PHASE); 5543ae82531b336b195a78c864c28af1448a74af633Alex Light } 55572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5563ae82531b336b195a78c864c28af1448a74af633Alex Light art::ScopedObjectAccess soa(self); 557ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light art::StackHandleScope<1> hs(self); 55872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5593ae82531b336b195a78c864c28af1448a74af633Alex Light // Need to read the Java "started" field to know whether this is starting or terminated. 560ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light art::Handle<art::mirror::Object> peer(hs.NewHandle(soa.Decode<art::mirror::Object>(thread))); 561ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light art::ObjPtr<art::mirror::Class> thread_klass = 562ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread); 563ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light if (!thread_klass->IsAssignableFrom(peer->GetClass())) { 564ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light return ERR(INVALID_THREAD); 565ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light } 566ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light art::ArtField* started_field = thread_klass->FindDeclaredInstanceField("started", "Z"); 5673ae82531b336b195a78c864c28af1448a74af633Alex Light CHECK(started_field != nullptr); 568ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light bool started = started_field->GetBoolean(peer.Get()) != 0; 5693ae82531b336b195a78c864c28af1448a74af633Alex Light constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW; 5703ae82531b336b195a78c864c28af1448a74af633Alex Light constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED | 5713ae82531b336b195a78c864c28af1448a74af633Alex Light JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 5723ae82531b336b195a78c864c28af1448a74af633Alex Light *thread_state_ptr = started ? kTerminatedState : kStartedState; 57372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NONE); 57472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 57572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 5768580744607a963d408956c3eb712b0e070c139b0Andreas GampejvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env, 5778580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jint* threads_count_ptr, 5788580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jthread** threads_ptr) { 5798580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (threads_count_ptr == nullptr || threads_ptr == nullptr) { 5808580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return ERR(NULL_POINTER); 5818580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 5828580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 5838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::Thread* current = art::Thread::Current(); 5848580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 5858580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::ScopedObjectAccess soa(current); 5868580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 5878580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::MutexLock mu(current, *art::Locks::thread_list_lock_); 5888580744607a963d408956c3eb712b0e070c139b0Andreas Gampe std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList(); 5898580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 5908580744607a963d408956c3eb712b0e070c139b0Andreas Gampe std::vector<art::ObjPtr<art::mirror::Object>> peers; 5918580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 5928580744607a963d408956c3eb712b0e070c139b0Andreas Gampe for (art::Thread* thread : thread_list) { 5938580744607a963d408956c3eb712b0e070c139b0Andreas Gampe // Skip threads that are still starting. 5948580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (thread->IsStillStarting()) { 5958580744607a963d408956c3eb712b0e070c139b0Andreas Gampe continue; 5968580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 5978580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 598202f85a54bfd1844664a18c18a4c0494763c6b82Andreas Gampe art::ObjPtr<art::mirror::Object> peer = thread->GetPeerFromOtherThread(); 5998580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (peer != nullptr) { 6008580744607a963d408956c3eb712b0e070c139b0Andreas Gampe peers.push_back(peer); 6018580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 6028580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 6038580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 6048580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (peers.empty()) { 6058580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_count_ptr = 0; 6068580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_ptr = nullptr; 6078580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } else { 6088580744607a963d408956c3eb712b0e070c139b0Andreas Gampe unsigned char* data; 6098580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data); 6108580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (data_result != ERR(NONE)) { 6118580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return data_result; 6128580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 6138580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jthread* threads = reinterpret_cast<jthread*>(data); 6148580744607a963d408956c3eb712b0e070c139b0Andreas Gampe for (size_t i = 0; i != peers.size(); ++i) { 6158580744607a963d408956c3eb712b0e070c139b0Andreas Gampe threads[i] = soa.AddLocalReference<jthread>(peers[i]); 6168580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 6178580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 6188580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_count_ptr = static_cast<jint>(peers.size()); 6198580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_ptr = threads; 6208580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 621f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NONE); 622f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe} 623f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 624092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// The struct that we store in the art::Thread::custom_tls_ that maps the jvmtiEnvs to the data 625092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// stored with that thread. This is needed since different jvmtiEnvs are not supposed to share TLS 626092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// data but we only have a single slot in Thread objects to store data. 627092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightstruct JvmtiGlobalTLSData { 628092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light std::unordered_map<jvmtiEnv*, const void*> data GUARDED_BY(art::Locks::thread_list_lock_); 629092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light}; 630092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light 631092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightstatic void RemoveTLSData(art::Thread* target, void* ctx) REQUIRES(art::Locks::thread_list_lock_) { 632092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light jvmtiEnv* env = reinterpret_cast<jvmtiEnv*>(ctx); 633092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::Locks::thread_list_lock_->AssertHeld(art::Thread::Current()); 634092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 635092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light if (global_tls != nullptr) { 636092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light global_tls->data.erase(env); 637092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light } 638092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light} 639092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light 640092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightvoid ThreadUtil::RemoveEnvironment(jvmtiEnv* env) { 641092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::Thread* self = art::Thread::Current(); 642092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 643092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::ThreadList* list = art::Runtime::Current()->GetThreadList(); 644092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light list->ForEach(RemoveTLSData, env); 645092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light} 646092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light 647092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex LightjvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) { 648092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::Thread* self = art::Thread::Current(); 649092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::ScopedObjectAccess soa(self); 650092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 6517ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 6527ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 6537ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 6547ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 655f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 656f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 657092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 658092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light if (global_tls == nullptr) { 659092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light target->SetCustomTLS(new JvmtiGlobalTLSData); 660092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 661092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light } 662092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light 663092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light global_tls->data[env] = data; 664f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 665f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NONE); 666f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe} 667f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 668092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex LightjvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env, 669f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe jthread thread, 670f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe void** data_ptr) { 671f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (data_ptr == nullptr) { 672f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NULL_POINTER); 673f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 674f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 675092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::Thread* self = art::Thread::Current(); 676092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::ScopedObjectAccess soa(self); 677092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 6787ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 6797ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 6807ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 6817ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 682f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 6838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 684092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 685092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light if (global_tls == nullptr) { 686092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light *data_ptr = nullptr; 687092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light return OK; 688092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light } 689092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light auto it = global_tls->data.find(env); 690092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light if (it != global_tls->data.end()) { 691092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light *data_ptr = const_cast<void*>(it->second); 692092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light } else { 693092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light *data_ptr = nullptr; 694092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light } 695092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light 6968580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return ERR(NONE); 6978580744607a963d408956c3eb712b0e070c139b0Andreas Gampe} 6988580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 699732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestruct AgentData { 700732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe const void* arg; 701732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiStartFunction proc; 702732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jthread thread; 703732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JavaVM* java_vm; 704732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiEnv* jvmti_env; 705732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jint priority; 7069311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light std::string name; 707732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}; 708732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 709732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestatic void* AgentCallback(void* arg) { 710732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg)); 711732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe CHECK(data->thread != nullptr); 712732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 713732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // We already have a peer. So call our special Attach function. 7149311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light art::Thread* self = art::Thread::Attach(data->name.c_str(), true, data->thread); 715739bf72ccb22794bc65203aa4824dba737cadd72Alex Light CHECK(self != nullptr) << "threads_being_born_ should have ensured thread could be attached."; 716732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // The name in Attach() is only for logging. Set the thread name. This is important so 717732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // that the thread is no longer seen as starting up. 718732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe { 719732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe art::ScopedObjectAccess soa(self); 7209311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light self->SetThreadName(data->name.c_str()); 721732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 722732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 723732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Release the peer. 724732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JNIEnv* env = self->GetJniEnv(); 725732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe env->DeleteGlobalRef(data->thread); 726732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->thread = nullptr; 727732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 728739bf72ccb22794bc65203aa4824dba737cadd72Alex Light { 729739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // The StartThreadBirth was called in the parent thread. We let the runtime know we are up 730739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // before going into the provided code. 731739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_); 732739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::Runtime::Current()->EndThreadBirth(); 733739bf72ccb22794bc65203aa4824dba737cadd72Alex Light } 734739bf72ccb22794bc65203aa4824dba737cadd72Alex Light 735732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Run the agent code. 736732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->proc(data->jvmti_env, env, const_cast<void*>(data->arg)); 737732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 738732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Detach the thread. 739732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe int detach_result = data->java_vm->DetachCurrentThread(); 740732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe CHECK_EQ(detach_result, 0); 741732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 742732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return nullptr; 743732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe} 744732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 745732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas GampejvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, 746732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jthread thread, 747732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiStartFunction proc, 748732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe const void* arg, 749732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jint priority) { 75023aa74818272a9d659414536324ae9133ecb8743Alex Light if (!PhaseUtil::IsLivePhase()) { 75123aa74818272a9d659414536324ae9133ecb8743Alex Light return ERR(WRONG_PHASE); 75223aa74818272a9d659414536324ae9133ecb8743Alex Light } 753732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { 754732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INVALID_PRIORITY); 755732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 756732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JNIEnv* env = art::Thread::Current()->GetJniEnv(); 757732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { 758732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INVALID_THREAD); 759732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 760732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (proc == nullptr) { 761732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(NULL_POINTER); 762732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 763732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 764739bf72ccb22794bc65203aa4824dba737cadd72Alex Light { 765739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::Runtime* runtime = art::Runtime::Current(); 766739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_); 767739bf72ccb22794bc65203aa4824dba737cadd72Alex Light if (runtime->IsShuttingDownLocked()) { 768739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // The runtime is shutting down so we cannot create new threads. 769739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // TODO It's not fully clear from the spec what we should do here. We aren't yet in 770739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // JVMTI_PHASE_DEAD so we cannot return ERR(WRONG_PHASE) but creating new threads is now 771739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // impossible. Existing agents don't seem to generally do anything with this return value so 772739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // it doesn't matter too much. We could do something like sending a fake ThreadStart event 773739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // even though code is never actually run. 774739bf72ccb22794bc65203aa4824dba737cadd72Alex Light return ERR(INTERNAL); 775739bf72ccb22794bc65203aa4824dba737cadd72Alex Light } 776739bf72ccb22794bc65203aa4824dba737cadd72Alex Light runtime->StartThreadBirth(); 777739bf72ccb22794bc65203aa4824dba737cadd72Alex Light } 778739bf72ccb22794bc65203aa4824dba737cadd72Alex Light 779732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe std::unique_ptr<AgentData> data(new AgentData); 780732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->arg = arg; 781732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->proc = proc; 782732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // We need a global ref for Java objects, as local refs will be invalid. 783732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->thread = env->NewGlobalRef(thread); 784732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->java_vm = art::Runtime::Current()->GetJavaVM(); 785732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->jvmti_env = jvmti_env; 786732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->priority = priority; 7879311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light ScopedLocalRef<jstring> s( 7889311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light env, 7899311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light reinterpret_cast<jstring>( 7909311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light env->GetObjectField(thread, art::WellKnownClasses::java_lang_Thread_name))); 7919311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light if (s == nullptr) { 7929311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light data->name = "JVMTI Agent Thread"; 7939311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light } else { 7949311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light ScopedUtfChars name(env, s.get()); 7959311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light data->name = name.c_str(); 7969311297a763d9d6cf6059f110a9aa136c0c8d81fAlex Light } 797732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 798732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe pthread_t pthread; 799732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe int pthread_create_result = pthread_create(&pthread, 800739bf72ccb22794bc65203aa4824dba737cadd72Alex Light nullptr, 801739bf72ccb22794bc65203aa4824dba737cadd72Alex Light &AgentCallback, 802739bf72ccb22794bc65203aa4824dba737cadd72Alex Light reinterpret_cast<void*>(data.get())); 803732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (pthread_create_result != 0) { 804739bf72ccb22794bc65203aa4824dba737cadd72Alex Light // If the create succeeded the other thread will call EndThreadBirth. 805739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::Runtime* runtime = art::Runtime::Current(); 806739bf72ccb22794bc65203aa4824dba737cadd72Alex Light art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_); 807739bf72ccb22794bc65203aa4824dba737cadd72Alex Light runtime->EndThreadBirth(); 808732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INTERNAL); 809732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 810732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data.release(); 811732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 812732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(NONE); 813732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe} 814732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 81588fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendOther(art::Thread* self, 8163ae82531b336b195a78c864c28af1448a74af633Alex Light jthread target_jthread) { 81788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Loop since we need to bail out and try again if we would end up getting suspended while holding 81888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we 81988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // release the lock, wait to get resumed and try again. 82088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light do { 82188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Suspend ourself if we have any outstanding suspends. This is so we won't suspend due to 82288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // another SuspendThread in the middle of suspending something else potentially causing a 82388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // deadlock. We need to do this in the loop because if we ended up back here then we had 82488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // outstanding SuspendReason::kForUserCode suspensions and we should wait for them to be cleared 82588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // before continuing. 82688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light SuspendCheck(self); 82788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_); 82823aa74818272a9d659414536324ae9133ecb8743Alex Light if (WouldSuspendForUserCodeLocked(self)) { 82988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by 83088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // a user-code suspension. We retry and do another SuspendCheck to clear this. 83123aa74818272a9d659414536324ae9133ecb8743Alex Light continue; 83288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 83323aa74818272a9d659414536324ae9133ecb8743Alex Light // We are not going to be suspended by user code from now on. 8343ae82531b336b195a78c864c28af1448a74af633Alex Light { 8353ae82531b336b195a78c864c28af1448a74af633Alex Light art::ScopedObjectAccess soa(self); 8363ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock thread_list_mu(self, *art::Locks::thread_list_lock_); 8377ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 8387ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 8397ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetAliveNativeThread(target_jthread, soa, &target, &err)) { 8407ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 8417ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } 84288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::ThreadState state = target->GetState(); 8437ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (state == art::ThreadState::kStarting || target->IsStillStarting()) { 84488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(THREAD_NOT_ALIVE); 8453ae82531b336b195a78c864c28af1448a74af633Alex Light } else { 8463ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_); 8473ae82531b336b195a78c864c28af1448a74af633Alex Light if (target->GetUserCodeSuspendCount() != 0) { 8483ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(THREAD_SUSPENDED); 8493ae82531b336b195a78c864c28af1448a74af633Alex Light } 85088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 85188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 8523ae82531b336b195a78c864c28af1448a74af633Alex Light bool timeout = true; 8533ae82531b336b195a78c864c28af1448a74af633Alex Light art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer( 8543ae82531b336b195a78c864c28af1448a74af633Alex Light target_jthread, 8553ae82531b336b195a78c864c28af1448a74af633Alex Light /* request_suspension */ true, 8563ae82531b336b195a78c864c28af1448a74af633Alex Light art::SuspendReason::kForUserCode, 8573ae82531b336b195a78c864c28af1448a74af633Alex Light &timeout); 8583ae82531b336b195a78c864c28af1448a74af633Alex Light if (ret_target == nullptr && !timeout) { 8593ae82531b336b195a78c864c28af1448a74af633Alex Light // TODO It would be good to get more information about why exactly the thread failed to 8603ae82531b336b195a78c864c28af1448a74af633Alex Light // suspend. 8613ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(INTERNAL); 8623ae82531b336b195a78c864c28af1448a74af633Alex Light } else if (!timeout) { 8633ae82531b336b195a78c864c28af1448a74af633Alex Light // we didn't time out and got a result. 8643ae82531b336b195a78c864c28af1448a74af633Alex Light return OK; 8653ae82531b336b195a78c864c28af1448a74af633Alex Light } 8663ae82531b336b195a78c864c28af1448a74af633Alex Light // We timed out. Just go around and try again. 86788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } while (true); 86888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light UNREACHABLE(); 86988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 87088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 87188fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendSelf(art::Thread* self) { 87288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light CHECK(self == art::Thread::Current()); 87388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light { 87488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_); 87588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::MutexLock thread_list_mu(self, *art::Locks::thread_suspend_count_lock_); 87688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (self->GetUserCodeSuspendCount() != 0) { 87788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // This can only happen if we race with another thread to suspend 'self' and we lose. 87888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(THREAD_SUSPENDED); 87988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 88088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // We shouldn't be able to fail this. 88188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (!self->ModifySuspendCount(self, +1, nullptr, art::SuspendReason::kForUserCode)) { 88288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // TODO More specific error would be nice. 88388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(INTERNAL); 88488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 88588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 88688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Once we have requested the suspend we actually go to sleep. We need to do this after releasing 88788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // the suspend_lock to make sure we can be woken up. This call gains the mutator lock causing us 88888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // to go to sleep until we are resumed. 88988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light SuspendCheck(self); 89088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return OK; 89188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 89288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 89388fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) { 89488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::Thread* self = art::Thread::Current(); 8953ae82531b336b195a78c864c28af1448a74af633Alex Light bool target_is_self = false; 89688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light { 89788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::ScopedObjectAccess soa(self); 8983ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 8997ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 9007ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 9017ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 9027ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 9033ae82531b336b195a78c864c28af1448a74af633Alex Light } else if (target == self) { 9043ae82531b336b195a78c864c28af1448a74af633Alex Light target_is_self = true; 9053ae82531b336b195a78c864c28af1448a74af633Alex Light } 90688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 9073ae82531b336b195a78c864c28af1448a74af633Alex Light if (target_is_self) { 90888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return SuspendSelf(self); 90988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } else { 9103ae82531b336b195a78c864c28af1448a74af633Alex Light return SuspendOther(self, thread); 91188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 91288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 91388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 91488fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::ResumeThread(jvmtiEnv* env ATTRIBUTE_UNUSED, 91588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jthread thread) { 91688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (thread == nullptr) { 91788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(NULL_POINTER); 91888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 91988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::Thread* self = art::Thread::Current(); 92088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light art::Thread* target; 9213ae82531b336b195a78c864c28af1448a74af633Alex Light // Retry until we know we won't get suspended by user code while resuming something. 9223ae82531b336b195a78c864c28af1448a74af633Alex Light do { 9233ae82531b336b195a78c864c28af1448a74af633Alex Light SuspendCheck(self); 9243ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_); 92523aa74818272a9d659414536324ae9133ecb8743Alex Light if (WouldSuspendForUserCodeLocked(self)) { 9263ae82531b336b195a78c864c28af1448a74af633Alex Light // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by 9273ae82531b336b195a78c864c28af1448a74af633Alex Light // a user-code suspension. We retry and do another SuspendCheck to clear this. 92823aa74818272a9d659414536324ae9133ecb8743Alex Light continue; 92988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 9303ae82531b336b195a78c864c28af1448a74af633Alex Light // From now on we know we cannot get suspended by user-code. 9313ae82531b336b195a78c864c28af1448a74af633Alex Light { 9323ae82531b336b195a78c864c28af1448a74af633Alex Light // NB This does a SuspendCheck (during thread state change) so we need to make sure we don't 9333ae82531b336b195a78c864c28af1448a74af633Alex Light // have the 'suspend_lock' locked here. 9343ae82531b336b195a78c864c28af1448a74af633Alex Light art::ScopedObjectAccess soa(self); 9353ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_); 9367ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err = ERR(INTERNAL); 9377ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 9387ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return err; 9393ae82531b336b195a78c864c28af1448a74af633Alex Light } else if (target == self) { 9403ae82531b336b195a78c864c28af1448a74af633Alex Light // We would have paused until we aren't suspended anymore due to the ScopedObjectAccess so 9413ae82531b336b195a78c864c28af1448a74af633Alex Light // we can just return THREAD_NOT_SUSPENDED. Unfortunately we cannot do any real DCHECKs 9423ae82531b336b195a78c864c28af1448a74af633Alex Light // about current state since it's all concurrent. 9433ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(THREAD_NOT_SUSPENDED); 9443ae82531b336b195a78c864c28af1448a74af633Alex Light } 9453ae82531b336b195a78c864c28af1448a74af633Alex Light // The JVMTI spec requires us to return THREAD_NOT_SUSPENDED if it is alive but we really 9463ae82531b336b195a78c864c28af1448a74af633Alex Light // cannot tell why resume failed. 9473ae82531b336b195a78c864c28af1448a74af633Alex Light { 9483ae82531b336b195a78c864c28af1448a74af633Alex Light art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_); 9493ae82531b336b195a78c864c28af1448a74af633Alex Light if (target->GetUserCodeSuspendCount() == 0) { 9503ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(THREAD_NOT_SUSPENDED); 9513ae82531b336b195a78c864c28af1448a74af633Alex Light } 9523ae82531b336b195a78c864c28af1448a74af633Alex Light } 9533ae82531b336b195a78c864c28af1448a74af633Alex Light } 9543ae82531b336b195a78c864c28af1448a74af633Alex Light // It is okay that we don't have a thread_list_lock here since we know that the thread cannot 9553ae82531b336b195a78c864c28af1448a74af633Alex Light // die since it is currently held suspended by a SuspendReason::kForUserCode suspend. 9563ae82531b336b195a78c864c28af1448a74af633Alex Light DCHECK(target != self); 9573ae82531b336b195a78c864c28af1448a74af633Alex Light if (!art::Runtime::Current()->GetThreadList()->Resume(target, 9583ae82531b336b195a78c864c28af1448a74af633Alex Light art::SuspendReason::kForUserCode)) { 9593ae82531b336b195a78c864c28af1448a74af633Alex Light // TODO Give a better error. 9603ae82531b336b195a78c864c28af1448a74af633Alex Light // This is most likely THREAD_NOT_SUSPENDED but we cannot really be sure. 9613ae82531b336b195a78c864c28af1448a74af633Alex Light return ERR(INTERNAL); 9623ae82531b336b195a78c864c28af1448a74af633Alex Light } else { 9633ae82531b336b195a78c864c28af1448a74af633Alex Light return OK; 9643ae82531b336b195a78c864c28af1448a74af633Alex Light } 9653ae82531b336b195a78c864c28af1448a74af633Alex Light } while (true); 96688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 96788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 9687ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightstatic bool IsCurrentThread(jthread thr) { 9697ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (thr == nullptr) { 9707ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return true; 9717ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } 9727ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* self = art::Thread::Current(); 9737ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::ScopedObjectAccess soa(self); 9747ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::MutexLock mu(self, *art::Locks::thread_list_lock_); 9757ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light art::Thread* target = nullptr; 9767ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light jvmtiError err_unused = ERR(INTERNAL); 9777ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (ThreadUtil::GetNativeThread(thr, soa, &target, &err_unused)) { 9787ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return target == self; 9797ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else { 9807ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light return false; 9817ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } 9827ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light} 9837ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light 98488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// Suspends all the threads in the list at the same time. Getting this behavior is a little tricky 98588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// since we can have threads in the list multiple times. This generally doesn't matter unless the 98688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// current thread is present multiple times. In that case we need to suspend only once and either 98788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// return the same error code in all the other slots if it failed or return ERR(THREAD_SUSPENDED) if 98888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// it didn't. We also want to handle the current thread last to make the behavior of the code 98988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// simpler to understand. 99088fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendThreadList(jvmtiEnv* env, 99188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jint request_count, 99288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light const jthread* threads, 99388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jvmtiError* results) { 99488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (request_count == 0) { 99588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(ILLEGAL_ARGUMENT); 99688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } else if (results == nullptr || threads == nullptr) { 99788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(NULL_POINTER); 99888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 99988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // This is the list of the indexes in 'threads' and 'results' that correspond to the currently 100088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // running thread. These indexes we need to handle specially since we need to only actually 100188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // suspend a single time. 100288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light std::vector<jint> current_thread_indexes; 100388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light for (jint i = 0; i < request_count; i++) { 10047ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light if (IsCurrentThread(threads[i])) { 10057ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light current_thread_indexes.push_back(i); 10067ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light } else { 10077ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light results[i] = env->SuspendThread(threads[i]); 100888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 100988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 101088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (!current_thread_indexes.empty()) { 101188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jint first_current_thread_index = current_thread_indexes[0]; 101288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Suspend self. 101388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jvmtiError res = env->SuspendThread(threads[first_current_thread_index]); 101488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light results[first_current_thread_index] = res; 101588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light // Fill in the rest of the error values as appropriate. 101688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jvmtiError other_results = (res != OK) ? res : ERR(THREAD_SUSPENDED); 101788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light for (auto it = ++current_thread_indexes.begin(); it != current_thread_indexes.end(); ++it) { 101888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light results[*it] = other_results; 101988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 102088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 102188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return OK; 102288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 102388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 102488fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::ResumeThreadList(jvmtiEnv* env, 102588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jint request_count, 102688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light const jthread* threads, 102788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light jvmtiError* results) { 102888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light if (request_count == 0) { 102988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(ILLEGAL_ARGUMENT); 103088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } else if (results == nullptr || threads == nullptr) { 103188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return ERR(NULL_POINTER); 103288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 103388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light for (jint i = 0; i < request_count; i++) { 103488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light results[i] = env->ResumeThread(threads[i]); 103588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light } 103688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light return OK; 103788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light} 103888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light 103954d39dc42630cd83f2d1bec5704805febb894819Alex LightjvmtiError ThreadUtil::StopThread(jvmtiEnv* env ATTRIBUTE_UNUSED, 104054d39dc42630cd83f2d1bec5704805febb894819Alex Light jthread thread, 104154d39dc42630cd83f2d1bec5704805febb894819Alex Light jobject exception) { 104254d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Thread* self = art::Thread::Current(); 104354d39dc42630cd83f2d1bec5704805febb894819Alex Light art::ScopedObjectAccess soa(self); 104454d39dc42630cd83f2d1bec5704805febb894819Alex Light art::StackHandleScope<1> hs(self); 104554d39dc42630cd83f2d1bec5704805febb894819Alex Light if (exception == nullptr) { 104654d39dc42630cd83f2d1bec5704805febb894819Alex Light return ERR(INVALID_OBJECT); 104754d39dc42630cd83f2d1bec5704805febb894819Alex Light } 104854d39dc42630cd83f2d1bec5704805febb894819Alex Light art::ObjPtr<art::mirror::Object> obj(soa.Decode<art::mirror::Object>(exception)); 104954d39dc42630cd83f2d1bec5704805febb894819Alex Light if (!obj->GetClass()->IsThrowableClass()) { 105054d39dc42630cd83f2d1bec5704805febb894819Alex Light return ERR(INVALID_OBJECT); 105154d39dc42630cd83f2d1bec5704805febb894819Alex Light } 105254d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Handle<art::mirror::Throwable> exc(hs.NewHandle(obj->AsThrowable())); 1053b1e31a8337b9cce2f3160a972123886b355dce27Alex Light art::Locks::thread_list_lock_->ExclusiveLock(self); 105454d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Thread* target = nullptr; 105554d39dc42630cd83f2d1bec5704805febb894819Alex Light jvmtiError err = ERR(INTERNAL); 105654d39dc42630cd83f2d1bec5704805febb894819Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 1057b1e31a8337b9cce2f3160a972123886b355dce27Alex Light art::Locks::thread_list_lock_->ExclusiveUnlock(self); 105854d39dc42630cd83f2d1bec5704805febb894819Alex Light return err; 105954d39dc42630cd83f2d1bec5704805febb894819Alex Light } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) { 1060b1e31a8337b9cce2f3160a972123886b355dce27Alex Light art::Locks::thread_list_lock_->ExclusiveUnlock(self); 106154d39dc42630cd83f2d1bec5704805febb894819Alex Light return ERR(THREAD_NOT_ALIVE); 106254d39dc42630cd83f2d1bec5704805febb894819Alex Light } 106354d39dc42630cd83f2d1bec5704805febb894819Alex Light struct StopThreadClosure : public art::Closure { 106454d39dc42630cd83f2d1bec5704805febb894819Alex Light public: 106554d39dc42630cd83f2d1bec5704805febb894819Alex Light explicit StopThreadClosure(art::Handle<art::mirror::Throwable> except) : exception_(except) { } 106654d39dc42630cd83f2d1bec5704805febb894819Alex Light 106754d39dc42630cd83f2d1bec5704805febb894819Alex Light void Run(art::Thread* me) REQUIRES_SHARED(art::Locks::mutator_lock_) { 106854d39dc42630cd83f2d1bec5704805febb894819Alex Light // Make sure the thread is prepared to notice the exception. 106954d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Runtime::Current()->GetInstrumentation()->InstrumentThreadStack(me); 107054d39dc42630cd83f2d1bec5704805febb894819Alex Light me->SetAsyncException(exception_.Get()); 107154d39dc42630cd83f2d1bec5704805febb894819Alex Light // Wake up the thread if it is sleeping. 107254d39dc42630cd83f2d1bec5704805febb894819Alex Light me->Notify(); 107354d39dc42630cd83f2d1bec5704805febb894819Alex Light } 107454d39dc42630cd83f2d1bec5704805febb894819Alex Light 107554d39dc42630cd83f2d1bec5704805febb894819Alex Light private: 107654d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Handle<art::mirror::Throwable> exception_; 107754d39dc42630cd83f2d1bec5704805febb894819Alex Light }; 107854d39dc42630cd83f2d1bec5704805febb894819Alex Light StopThreadClosure c(exc); 1079b1e31a8337b9cce2f3160a972123886b355dce27Alex Light // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution. 1080ac5fea049d898713bb5802141af2ee3d59ee592dAlex Light if (target->RequestSynchronousCheckpoint(&c)) { 108154d39dc42630cd83f2d1bec5704805febb894819Alex Light return OK; 108254d39dc42630cd83f2d1bec5704805febb894819Alex Light } else { 108354d39dc42630cd83f2d1bec5704805febb894819Alex Light // Something went wrong, probably the thread died. 108454d39dc42630cd83f2d1bec5704805febb894819Alex Light return ERR(THREAD_NOT_ALIVE); 108554d39dc42630cd83f2d1bec5704805febb894819Alex Light } 108654d39dc42630cd83f2d1bec5704805febb894819Alex Light} 108754d39dc42630cd83f2d1bec5704805febb894819Alex Light 108854d39dc42630cd83f2d1bec5704805febb894819Alex LightjvmtiError ThreadUtil::InterruptThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) { 108954d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Thread* self = art::Thread::Current(); 109054d39dc42630cd83f2d1bec5704805febb894819Alex Light art::ScopedObjectAccess soa(self); 109154d39dc42630cd83f2d1bec5704805febb894819Alex Light art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_); 109254d39dc42630cd83f2d1bec5704805febb894819Alex Light art::Thread* target = nullptr; 109354d39dc42630cd83f2d1bec5704805febb894819Alex Light jvmtiError err = ERR(INTERNAL); 109454d39dc42630cd83f2d1bec5704805febb894819Alex Light if (!GetAliveNativeThread(thread, soa, &target, &err)) { 109554d39dc42630cd83f2d1bec5704805febb894819Alex Light return err; 109654d39dc42630cd83f2d1bec5704805febb894819Alex Light } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) { 109754d39dc42630cd83f2d1bec5704805febb894819Alex Light return ERR(THREAD_NOT_ALIVE); 109854d39dc42630cd83f2d1bec5704805febb894819Alex Light } 109954d39dc42630cd83f2d1bec5704805febb894819Alex Light target->Interrupt(self); 110054d39dc42630cd83f2d1bec5704805febb894819Alex Light return OK; 110154d39dc42630cd83f2d1bec5704805febb894819Alex Light} 110254d39dc42630cd83f2d1bec5704805febb894819Alex Light 1103af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} // namespace openjdkjvmti 1104