ti_thread.cc revision 373a9b5c718a45ac484afcf4fe6ce84f4bb562b3
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
34eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "android-base/strings.h"
35a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field-inl.h"
36af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_jvmti.h"
37af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/logging.h"
38af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/mutex.h"
39eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "events-inl.h"
40f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc/system_weak.h"
41f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc_root-inl.h"
42af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "jni_internal.h"
43af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/class.h"
44af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/object-inl.h"
45af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/string.h"
46373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h"
47af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "obj_ptr.h"
48f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "runtime.h"
49eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "runtime_callbacks.h"
50af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "scoped_thread_state_change-inl.h"
51b486a98aadc95d80548953410cf23edba62259faAndreas Gampe#include "thread-current-inl.h"
528580744607a963d408956c3eb712b0e070c139b0Andreas Gampe#include "thread_list.h"
53e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "ti_phase.h"
54af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "well_known_classes.h"
55af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
56af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampenamespace openjdkjvmti {
57af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
58db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampeart::ArtField* ThreadUtil::context_class_loader_ = nullptr;
59db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe
601d8a9741d2979d09a21942fbf9107d212ce2511bAlex Lightstruct ThreadCallback : public art::ThreadLifecycleCallback {
61eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
62eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    if (self->GetPeer() == nullptr) {
63eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      return nullptr;
64eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    }
65eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer());
66eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
671d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light
68983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe  template <ArtJvmtiEvent kEvent>
69983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe  void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
70eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    DCHECK_EQ(self, art::Thread::Current());
71eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self));
72e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
73983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    event_handler->DispatchEvent<kEvent>(self,
74983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe                                         reinterpret_cast<JNIEnv*>(self->GetJniEnv()),
75983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe                                         thread.get());
76eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
77eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
78eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  void ThreadStart(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
79eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    if (!started) {
80eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // Runtime isn't started. We only expect at most the signal handler or JIT threads to be
81eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // started here.
82eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      if (art::kIsDebugBuild) {
83eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        std::string name;
84eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        self->GetThreadName(name);
855bd09549b443659ddd81768c811dcb5c6850775cAlex Light        if (name != "JDWP" &&
865bd09549b443659ddd81768c811dcb5c6850775cAlex Light            name != "Signal Catcher" &&
875bd09549b443659ddd81768c811dcb5c6850775cAlex Light            !android::base::StartsWith(name, "Jit thread pool")) {
8823aa74818272a9d659414536324ae9133ecb8743Alex Light          LOG(FATAL) << "Unexpected thread before start: " << name << " id: "
8923aa74818272a9d659414536324ae9133ecb8743Alex Light                     << self->GetThreadId();
90eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        }
91eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      }
92eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      return;
93eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    }
94983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    Post<ArtJvmtiEvent::kThreadStart>(self);
95eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
96eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
97eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  void ThreadDeath(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
98983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    Post<ArtJvmtiEvent::kThreadEnd>(self);
99eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
100eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
101eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  EventHandler* event_handler = nullptr;
102eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  bool started = false;
103eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe};
104eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
105eafaf57557939bcabeb7a7388fb4951e74661a53Andreas GampeThreadCallback gThreadCallback;
106eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
107eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Register(EventHandler* handler) {
108eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::Runtime* runtime = art::Runtime::Current();
109eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
110eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  gThreadCallback.started = runtime->IsStarted();
111eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  gThreadCallback.event_handler = handler;
112eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
113eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
114eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
115eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedSuspendAll ssa("Add thread callback");
116eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback);
1171d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light}
1181d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light
1191d8a9741d2979d09a21942fbf9107d212ce2511bAlex Lightvoid ThreadUtil::VMInitEventSent() {
1201d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  // We should have already started.
1211d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  DCHECK(gThreadCallback.started);
1221d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  // We moved to VMInit. Report the main thread as started (it was attached early, and must not be
1231d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  // reported until Init.
1241d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  gThreadCallback.Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current());
125eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}
126eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
127db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampevoid ThreadUtil::CacheData() {
1281d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  // We must have started since it is now safe to cache our data;
1291d8a9741d2979d09a21942fbf9107d212ce2511bAlex Light  gThreadCallback.started = true;
130db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
131db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  art::ObjPtr<art::mirror::Class> thread_class =
132db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe      soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread);
133db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  CHECK(thread_class != nullptr);
134db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader",
135db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe                                                                  "Ljava/lang/ClassLoader;");
136db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  CHECK(context_class_loader_ != nullptr);
137db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe}
138db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe
139eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Unregister() {
140eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
141eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
142eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedSuspendAll ssa("Remove thread callback");
143eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::Runtime* runtime = art::Runtime::Current();
144eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback);
145eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}
146eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
147af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) {
148af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::Thread* self = art::Thread::Current();
149af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
150af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::ScopedObjectAccess soa(self);
151af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
152af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  jthread thread_peer;
153af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (self->IsStillStarting()) {
154af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    thread_peer = nullptr;
155af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  } else {
156af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    thread_peer = soa.AddLocalReference<jthread>(self->GetPeer());
157af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
158af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
159af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  *thread_ptr = thread_peer;
160af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return ERR(NONE);
161af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
162af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
163af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Get the native thread. The spec says a null object denotes the current thread.
1647ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightbool ThreadUtil::GetNativeThread(jthread thread,
1657ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                 const art::ScopedObjectAccessAlreadyRunnable& soa,
1667ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                 /*out*/ art::Thread** thr,
1677ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                 /*out*/ jvmtiError* err) {
168af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (thread == nullptr) {
1697ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    *thr = art::Thread::Current();
1707ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return true;
1717ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  } else if (!soa.Env()->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) {
1727ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    *err = ERR(INVALID_THREAD);
1737ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return false;
1747ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  } else {
1757ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    *thr = art::Thread::FromManagedThread(soa, thread);
1767ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return true;
177af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
1787ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light}
179af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
1807ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightbool ThreadUtil::GetAliveNativeThread(jthread thread,
1817ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                      const art::ScopedObjectAccessAlreadyRunnable& soa,
1827ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                      /*out*/ art::Thread** thr,
1837ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light                                      /*out*/ jvmtiError* err) {
1847ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (!GetNativeThread(thread, soa, thr, err)) {
1857ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return false;
1867ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  } else if (*thr == nullptr || (*thr)->GetState() == art::ThreadState::kTerminated) {
1877ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    *err = ERR(THREAD_NOT_ALIVE);
1887ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return false;
1897ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  } else {
1907ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return true;
1917ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  }
192af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
193af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
194af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) {
195af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (info_ptr == nullptr) {
196af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    return ERR(NULL_POINTER);
197af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
198db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  if (!PhaseUtil::IsLivePhase()) {
199db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe    return JVMTI_ERROR_WRONG_PHASE;
200db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe  }
201af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2023ae82531b336b195a78c864c28af1448a74af633Alex Light  art::Thread* self = art::Thread::Current();
2033ae82531b336b195a78c864c28af1448a74af633Alex Light  art::ScopedObjectAccess soa(self);
2043ae82531b336b195a78c864c28af1448a74af633Alex Light  art::MutexLock mu(self, *art::Locks::thread_list_lock_);
205af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2067ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::Thread* target;
2077ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  jvmtiError err = ERR(INTERNAL);
2087ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (!GetNativeThread(thread, soa, &target, &err)) {
2097ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return err;
210af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
211af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2125471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  JvmtiUniquePtr<char[]> name_uptr;
2133ae82531b336b195a78c864c28af1448a74af633Alex Light  if (target != nullptr) {
214af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Have a native thread object, this thread is alive.
215af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    std::string name;
2163ae82531b336b195a78c864c28af1448a74af633Alex Light    target->GetThreadName(name);
2175471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    jvmtiError name_result;
2185471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    name_uptr = CopyString(env, name.c_str(), &name_result);
2195471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    if (name_uptr == nullptr) {
220af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      return name_result;
221af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
2225471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    info_ptr->name = name_uptr.get();
223af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2243ae82531b336b195a78c864c28af1448a74af633Alex Light    info_ptr->priority = target->GetNativePriority();
225af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2263ae82531b336b195a78c864c28af1448a74af633Alex Light    info_ptr->is_daemon = target->IsDaemon();
227af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
2283ae82531b336b195a78c864c28af1448a74af633Alex Light    art::ObjPtr<art::mirror::Object> peer = target->GetPeerFromOtherThread();
229af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
230af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // ThreadGroup.
231af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    if (peer != nullptr) {
232af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
233af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
234af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
235af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = group == nullptr
236af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   ? nullptr
237af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   : soa.AddLocalReference<jthreadGroup>(group);
238af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    } else {
239af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = nullptr;
240af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
241af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
242af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Context classloader.
243db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe    DCHECK(context_class_loader_ != nullptr);
244db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe    art::ObjPtr<art::mirror::Object> ccl = peer != nullptr
245db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe        ? context_class_loader_->GetObject(peer)
246db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe        : nullptr;
247af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->context_class_loader = ccl == nullptr
248af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         ? nullptr
249af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         : soa.AddLocalReference<jobject>(ccl);
250af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  } else {
251af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Only the peer. This thread has either not been started, or is dead. Read things from
252af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // the Java side.
253af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread);
254af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
255af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Name.
256af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
257af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name);
258af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
259af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> name = f->GetObject(peer);
260af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      std::string name_cpp;
261af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      const char* name_cstr;
262af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      if (name != nullptr) {
263af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cpp = name->AsString()->ToModifiedUtf8();
264af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cstr = name_cpp.c_str();
265af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      } else {
266af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cstr = "";
267af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      }
2685471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe      jvmtiError name_result;
2695471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe      name_uptr = CopyString(env, name_cstr, &name_result);
2705471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe      if (name_uptr == nullptr) {
271af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        return name_result;
272af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      }
2735471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe      info_ptr->name = name_uptr.get();
274af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
275af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
276af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Priority.
277af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
278af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority);
279af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
280af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->priority = static_cast<jint>(f->GetInt(peer));
281af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
282af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
283af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Daemon.
284af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
285af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon);
286af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
287af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE;
288af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
289af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
290af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // ThreadGroup.
291af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
292af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
293af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
294af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
295af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = group == nullptr
296af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   ? nullptr
297af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   : soa.AddLocalReference<jthreadGroup>(group);
298af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
299af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
300af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Context classloader.
301db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe    DCHECK(context_class_loader_ != nullptr);
302db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe    art::ObjPtr<art::mirror::Object> ccl = peer != nullptr
303db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe        ? context_class_loader_->GetObject(peer)
304db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe        : nullptr;
305af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->context_class_loader = ccl == nullptr
306af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         ? nullptr
307af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         : soa.AddLocalReference<jobject>(ccl);
308af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
309af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
310af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  name_uptr.release();
311af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
312af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return ERR(NONE);
313af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
314af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
3151f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstruct InternalThreadState {
3161f0a22f486873063246e64ec6bb38238987ae23eAlex Light  art::Thread* native_thread;
3171f0a22f486873063246e64ec6bb38238987ae23eAlex Light  art::ThreadState art_state;
3181f0a22f486873063246e64ec6bb38238987ae23eAlex Light  int thread_user_code_suspend_count;
3191f0a22f486873063246e64ec6bb38238987ae23eAlex Light};
3201f0a22f486873063246e64ec6bb38238987ae23eAlex Light
3211f0a22f486873063246e64ec6bb38238987ae23eAlex Light// Return the thread's (or current thread, if null) thread state.
3227ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightstatic InternalThreadState GetNativeThreadState(art::Thread* target)
3231f0a22f486873063246e64ec6bb38238987ae23eAlex Light    REQUIRES_SHARED(art::Locks::mutator_lock_)
3243ae82531b336b195a78c864c28af1448a74af633Alex Light    REQUIRES(art::Locks::thread_list_lock_, art::Locks::user_code_suspension_lock_) {
3251f0a22f486873063246e64ec6bb38238987ae23eAlex Light  InternalThreadState thread_state = {};
3267ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::MutexLock tscl_mu(art::Thread::Current(), *art::Locks::thread_suspend_count_lock_);
3277ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  thread_state.native_thread = target;
3287ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (target == nullptr || target->IsStillStarting()) {
3291f0a22f486873063246e64ec6bb38238987ae23eAlex Light    thread_state.art_state = art::ThreadState::kStarting;
3301f0a22f486873063246e64ec6bb38238987ae23eAlex Light    thread_state.thread_user_code_suspend_count = 0;
3311f0a22f486873063246e64ec6bb38238987ae23eAlex Light  } else {
3327ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    thread_state.art_state = target->GetState();
3337ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    thread_state.thread_user_code_suspend_count = target->GetUserCodeSuspendCount();
33472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
3351f0a22f486873063246e64ec6bb38238987ae23eAlex Light  return thread_state;
33672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
33772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
3381f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstatic jint GetJvmtiThreadStateFromInternal(const InternalThreadState& state) {
3391f0a22f486873063246e64ec6bb38238987ae23eAlex Light  art::ThreadState internal_thread_state = state.art_state;
34072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  jint jvmti_state = JVMTI_THREAD_STATE_ALIVE;
34172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
3421f0a22f486873063246e64ec6bb38238987ae23eAlex Light  if (state.thread_user_code_suspend_count != 0) {
343597adad749499bc2da85851273e7623f6b249d1eAlex Light    // Suspended can be set with any thread state so check it here. Even if the thread isn't in
344597adad749499bc2da85851273e7623f6b249d1eAlex Light    // kSuspended state it will move to that once it hits a checkpoint so we can still set this.
34572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED;
34672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    // Note: We do not have data about the previous state. Otherwise we should load the previous
34772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    //       state here.
34872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
34972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
3501f0a22f486873063246e64ec6bb38238987ae23eAlex Light  if (state.native_thread->IsInterrupted()) {
351597adad749499bc2da85851273e7623f6b249d1eAlex Light    // Interrupted can be set with any thread state so check it here.
3521f0a22f486873063246e64ec6bb38238987ae23eAlex Light    jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED;
3531f0a22f486873063246e64ec6bb38238987ae23eAlex Light  }
3541f0a22f486873063246e64ec6bb38238987ae23eAlex Light
355597adad749499bc2da85851273e7623f6b249d1eAlex Light  // Enumerate all the thread states and fill in the other bits. This contains the results of
356597adad749499bc2da85851273e7623f6b249d1eAlex Light  // following the decision tree in the JVMTI spec GetThreadState documentation.
357597adad749499bc2da85851273e7623f6b249d1eAlex Light  switch (internal_thread_state) {
358597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kRunnable:
359597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingWeakGcRootRead:
360597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kSuspended:
361597adad749499bc2da85851273e7623f6b249d1eAlex Light      // These are all simply runnable.
362597adad749499bc2da85851273e7623f6b249d1eAlex Light      // kRunnable is self-explanatory.
363597adad749499bc2da85851273e7623f6b249d1eAlex Light      // kWaitingWeakGcRootRead is set during some operations with strings due to the intern-table
364597adad749499bc2da85851273e7623f6b249d1eAlex Light      // so we want to keep it marked as runnable.
365597adad749499bc2da85851273e7623f6b249d1eAlex Light      // kSuspended we don't mark since if we don't have a user_code_suspend_count then it is done
366597adad749499bc2da85851273e7623f6b249d1eAlex Light      // by the GC and not a JVMTI suspension, which means it cannot be removed by ResumeThread.
367597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE;
368597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
369597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kNative:
370597adad749499bc2da85851273e7623f6b249d1eAlex Light      // kNative means native and runnable. Technically THREAD_STATE_IN_NATIVE can be set with any
371597adad749499bc2da85851273e7623f6b249d1eAlex Light      // state but we don't have the information to know if it should be present for any but the
372597adad749499bc2da85851273e7623f6b249d1eAlex Light      // kNative state.
373597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= (JVMTI_THREAD_STATE_IN_NATIVE |
374597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_RUNNABLE);
375597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
376597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kBlocked:
377597adad749499bc2da85851273e7623f6b249d1eAlex Light      // Blocked is one of the top level states so it sits alone.
378597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
379597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
380597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaiting:
381597adad749499bc2da85851273e7623f6b249d1eAlex Light      // Object.wait() so waiting, indefinitely, in object.wait.
382597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
383597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
384597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_IN_OBJECT_WAIT);
385597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
386597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kTimedWaiting:
387597adad749499bc2da85851273e7623f6b249d1eAlex Light      // Object.wait(long) so waiting, with timeout, in object.wait.
388597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
389597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
390597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_IN_OBJECT_WAIT);
391597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
392597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kSleeping:
393597adad749499bc2da85851273e7623f6b249d1eAlex Light      // In object.sleep. This is a timed wait caused by sleep.
394597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
395597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
396597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_SLEEPING);
397597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
398597adad749499bc2da85851273e7623f6b249d1eAlex Light    // TODO We might want to print warnings if we have the debugger running while JVMTI agents are
399597adad749499bc2da85851273e7623f6b249d1eAlex Light    // attached.
400597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForDebuggerSend:
401597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForDebuggerToAttach:
402597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingInMainDebuggerLoop:
403597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForDebuggerSuspension:
404597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForLockInflation:
405597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForTaskProcessor:
406597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForGcToComplete:
407597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForCheckPointsToRun:
408597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingPerformingGc:
409597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForJniOnLoad:
410597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingInMainSignalCatcherLoop:
411597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForSignalCatcherOutput:
412597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForDeoptimization:
413597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForMethodTracingStart:
414597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForVisitObjects:
415597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForGetObjectsAllocated:
416597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kWaitingForGcThreadFlip:
417597adad749499bc2da85851273e7623f6b249d1eAlex Light      // All of these are causing the thread to wait for an indeterminate amount of time but isn't
418597adad749499bc2da85851273e7623f6b249d1eAlex Light      // caused by sleep, park, or object#wait.
419597adad749499bc2da85851273e7623f6b249d1eAlex Light      jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
420597adad749499bc2da85851273e7623f6b249d1eAlex Light                      JVMTI_THREAD_STATE_WAITING_INDEFINITELY);
421597adad749499bc2da85851273e7623f6b249d1eAlex Light      break;
422597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kStarting:
423597adad749499bc2da85851273e7623f6b249d1eAlex Light    case art::ThreadState::kTerminated:
424597adad749499bc2da85851273e7623f6b249d1eAlex Light      // We only call this if we are alive so we shouldn't see either of these states.
425597adad749499bc2da85851273e7623f6b249d1eAlex Light      LOG(FATAL) << "Should not be in state " << internal_thread_state;
426597adad749499bc2da85851273e7623f6b249d1eAlex Light      UNREACHABLE();
42772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
428597adad749499bc2da85851273e7623f6b249d1eAlex Light  // TODO: PARKED. We'll have to inspect the stack.
42972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
43072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  return jvmti_state;
43172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
43272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
4331f0a22f486873063246e64ec6bb38238987ae23eAlex Lightstatic jint GetJavaStateFromInternal(const InternalThreadState& state) {
4341f0a22f486873063246e64ec6bb38238987ae23eAlex Light  switch (state.art_state) {
43572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kTerminated:
43672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
43772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
43872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kRunnable:
43972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kNative:
44072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingWeakGcRootRead:
44172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kSuspended:
44272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE;
44372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
44472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kTimedWaiting:
44572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kSleeping:
44672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING;
44772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
44872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kBlocked:
44972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED;
45072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
45172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kStarting:
45272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_NEW;
45372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
45472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaiting:
45577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case art::ThreadState::kWaitingForTaskProcessor:
45677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case art::ThreadState::kWaitingForLockInflation:
45772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGcToComplete:
45872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingPerformingGc:
45972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForCheckPointsToRun:
46072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerSend:
46172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerToAttach:
46272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingInMainDebuggerLoop:
46372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerSuspension:
46472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDeoptimization:
46572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGetObjectsAllocated:
46672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForJniOnLoad:
46772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForSignalCatcherOutput:
46872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingInMainSignalCatcherLoop:
46972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForMethodTracingStart:
47072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForVisitObjects:
47172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGcThreadFlip:
47272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_WAITING;
47372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
47472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  LOG(FATAL) << "Unreachable";
47572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  UNREACHABLE();
47672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
47772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
4781f0a22f486873063246e64ec6bb38238987ae23eAlex Light// Suspends the current thread if it has any suspend requests on it.
47923aa74818272a9d659414536324ae9133ecb8743Alex Lightvoid ThreadUtil::SuspendCheck(art::Thread* self) {
4801f0a22f486873063246e64ec6bb38238987ae23eAlex Light  art::ScopedObjectAccess soa(self);
4811f0a22f486873063246e64ec6bb38238987ae23eAlex Light  // Really this is only needed if we are in FastJNI and actually have the mutator_lock_ already.
4821f0a22f486873063246e64ec6bb38238987ae23eAlex Light  self->FullSuspendCheck();
4831f0a22f486873063246e64ec6bb38238987ae23eAlex Light}
4841f0a22f486873063246e64ec6bb38238987ae23eAlex Light
48523aa74818272a9d659414536324ae9133ecb8743Alex Lightbool ThreadUtil::WouldSuspendForUserCodeLocked(art::Thread* self) {
48623aa74818272a9d659414536324ae9133ecb8743Alex Light  DCHECK(self == art::Thread::Current());
48723aa74818272a9d659414536324ae9133ecb8743Alex Light  art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_);
48823aa74818272a9d659414536324ae9133ecb8743Alex Light  return self->GetUserCodeSuspendCount() != 0;
48923aa74818272a9d659414536324ae9133ecb8743Alex Light}
49023aa74818272a9d659414536324ae9133ecb8743Alex Light
49123aa74818272a9d659414536324ae9133ecb8743Alex Lightbool ThreadUtil::WouldSuspendForUserCode(art::Thread* self) {
49223aa74818272a9d659414536324ae9133ecb8743Alex Light  DCHECK(self == art::Thread::Current());
49323aa74818272a9d659414536324ae9133ecb8743Alex Light  art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
49423aa74818272a9d659414536324ae9133ecb8743Alex Light  return WouldSuspendForUserCodeLocked(self);
49523aa74818272a9d659414536324ae9133ecb8743Alex Light}
49623aa74818272a9d659414536324ae9133ecb8743Alex Light
49772c19834136c81eace33687e06f5daf92a5a7583Andreas GampejvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED,
49872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                      jthread thread,
49972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                      jint* thread_state_ptr) {
50072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (thread_state_ptr == nullptr) {
50172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    return ERR(NULL_POINTER);
50272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
50372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5041f0a22f486873063246e64ec6bb38238987ae23eAlex Light  art::Thread* self = art::Thread::Current();
5051f0a22f486873063246e64ec6bb38238987ae23eAlex Light  InternalThreadState state = {};
5061f0a22f486873063246e64ec6bb38238987ae23eAlex Light  // Loop since we need to bail out and try again if we would end up getting suspended while holding
5071f0a22f486873063246e64ec6bb38238987ae23eAlex Light  // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we
5081f0a22f486873063246e64ec6bb38238987ae23eAlex Light  // release the lock, wait to get resumed and try again.
5091f0a22f486873063246e64ec6bb38238987ae23eAlex Light  do {
5101f0a22f486873063246e64ec6bb38238987ae23eAlex Light    SuspendCheck(self);
5111f0a22f486873063246e64ec6bb38238987ae23eAlex Light    art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
51223aa74818272a9d659414536324ae9133ecb8743Alex Light    if (WouldSuspendForUserCodeLocked(self)) {
51323aa74818272a9d659414536324ae9133ecb8743Alex Light      // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
51423aa74818272a9d659414536324ae9133ecb8743Alex Light      // a user-code suspension. We retry and do another SuspendCheck to clear this.
51523aa74818272a9d659414536324ae9133ecb8743Alex Light      continue;
5161f0a22f486873063246e64ec6bb38238987ae23eAlex Light    }
5171f0a22f486873063246e64ec6bb38238987ae23eAlex Light    art::ScopedObjectAccess soa(self);
5183ae82531b336b195a78c864c28af1448a74af633Alex Light    art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
5197ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    jvmtiError err = ERR(INTERNAL);
5207ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    art::Thread* target = nullptr;
5217ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    if (!GetNativeThread(thread, soa, &target, &err)) {
5227ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      return err;
5237ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    }
5247ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    state = GetNativeThreadState(target);
5253ae82531b336b195a78c864c28af1448a74af633Alex Light    if (state.art_state == art::ThreadState::kStarting) {
5263ae82531b336b195a78c864c28af1448a74af633Alex Light      break;
52772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    }
5283ae82531b336b195a78c864c28af1448a74af633Alex Light    DCHECK(state.native_thread != nullptr);
52972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5303ae82531b336b195a78c864c28af1448a74af633Alex Light    // Translate internal thread state to JVMTI and Java state.
5313ae82531b336b195a78c864c28af1448a74af633Alex Light    jint jvmti_state = GetJvmtiThreadStateFromInternal(state);
5323ae82531b336b195a78c864c28af1448a74af633Alex Light
5333ae82531b336b195a78c864c28af1448a74af633Alex Light    // Java state is derived from nativeGetState.
5343ae82531b336b195a78c864c28af1448a74af633Alex Light    // TODO: Our implementation assigns "runnable" to suspended. As such, we will have slightly
5353ae82531b336b195a78c864c28af1448a74af633Alex Light    //       different mask if a thread got suspended due to user-code. However, this is for
5363ae82531b336b195a78c864c28af1448a74af633Alex Light    //       consistency with the Java view.
5373ae82531b336b195a78c864c28af1448a74af633Alex Light    jint java_state = GetJavaStateFromInternal(state);
5383ae82531b336b195a78c864c28af1448a74af633Alex Light
5393ae82531b336b195a78c864c28af1448a74af633Alex Light    *thread_state_ptr = jvmti_state | java_state;
5401f0a22f486873063246e64ec6bb38238987ae23eAlex Light
54172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    return ERR(NONE);
5423ae82531b336b195a78c864c28af1448a74af633Alex Light  } while (true);
54372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5443ae82531b336b195a78c864c28af1448a74af633Alex Light  DCHECK_EQ(state.art_state, art::ThreadState::kStarting);
54572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5463ae82531b336b195a78c864c28af1448a74af633Alex Light  if (thread == nullptr) {
5473ae82531b336b195a78c864c28af1448a74af633Alex Light    // No native thread, and no Java thread? We must be starting up. Report as wrong phase.
5483ae82531b336b195a78c864c28af1448a74af633Alex Light    return ERR(WRONG_PHASE);
5493ae82531b336b195a78c864c28af1448a74af633Alex Light  }
55072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5513ae82531b336b195a78c864c28af1448a74af633Alex Light  art::ScopedObjectAccess soa(self);
552ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  art::StackHandleScope<1> hs(self);
55372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5543ae82531b336b195a78c864c28af1448a74af633Alex Light  // Need to read the Java "started" field to know whether this is starting or terminated.
555ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  art::Handle<art::mirror::Object> peer(hs.NewHandle(soa.Decode<art::mirror::Object>(thread)));
556ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  art::ObjPtr<art::mirror::Class> thread_klass =
557ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light      soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread);
558ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  if (!thread_klass->IsAssignableFrom(peer->GetClass())) {
559ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light    return ERR(INVALID_THREAD);
560ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  }
561ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  art::ArtField* started_field = thread_klass->FindDeclaredInstanceField("started", "Z");
5623ae82531b336b195a78c864c28af1448a74af633Alex Light  CHECK(started_field != nullptr);
563ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light  bool started = started_field->GetBoolean(peer.Get()) != 0;
5643ae82531b336b195a78c864c28af1448a74af633Alex Light  constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW;
5653ae82531b336b195a78c864c28af1448a74af633Alex Light  constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED |
5663ae82531b336b195a78c864c28af1448a74af633Alex Light                                    JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
5673ae82531b336b195a78c864c28af1448a74af633Alex Light  *thread_state_ptr = started ? kTerminatedState : kStartedState;
56872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  return ERR(NONE);
56972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
57072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
5718580744607a963d408956c3eb712b0e070c139b0Andreas GampejvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env,
5728580744607a963d408956c3eb712b0e070c139b0Andreas Gampe                                     jint* threads_count_ptr,
5738580744607a963d408956c3eb712b0e070c139b0Andreas Gampe                                     jthread** threads_ptr) {
5748580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  if (threads_count_ptr == nullptr || threads_ptr == nullptr) {
5758580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    return ERR(NULL_POINTER);
5768580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
5778580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5788580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::Thread* current = art::Thread::Current();
5798580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5808580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::ScopedObjectAccess soa(current);
5818580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5828580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::MutexLock mu(current, *art::Locks::thread_list_lock_);
5838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList();
5848580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5858580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  std::vector<art::ObjPtr<art::mirror::Object>> peers;
5868580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5878580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  for (art::Thread* thread : thread_list) {
5888580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    // Skip threads that are still starting.
5898580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (thread->IsStillStarting()) {
5908580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      continue;
5918580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
5928580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
593202f85a54bfd1844664a18c18a4c0494763c6b82Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = thread->GetPeerFromOtherThread();
5948580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (peer != nullptr) {
5958580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      peers.push_back(peer);
5968580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
5978580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
5988580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
5998580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  if (peers.empty()) {
6008580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_count_ptr = 0;
6018580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_ptr = nullptr;
6028580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  } else {
6038580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    unsigned char* data;
6048580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data);
6058580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (data_result != ERR(NONE)) {
6068580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      return data_result;
6078580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
6088580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    jthread* threads = reinterpret_cast<jthread*>(data);
6098580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    for (size_t i = 0; i != peers.size(); ++i) {
6108580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      threads[i] = soa.AddLocalReference<jthread>(peers[i]);
6118580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
6128580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
6138580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_count_ptr = static_cast<jint>(peers.size());
6148580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_ptr = threads;
6158580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
616f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  return ERR(NONE);
617f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe}
618f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
619092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// The struct that we store in the art::Thread::custom_tls_ that maps the jvmtiEnvs to the data
620092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// stored with that thread. This is needed since different jvmtiEnvs are not supposed to share TLS
621092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light// data but we only have a single slot in Thread objects to store data.
622092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightstruct JvmtiGlobalTLSData {
623092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  std::unordered_map<jvmtiEnv*, const void*> data GUARDED_BY(art::Locks::thread_list_lock_);
624092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light};
625092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light
626092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightstatic void RemoveTLSData(art::Thread* target, void* ctx) REQUIRES(art::Locks::thread_list_lock_) {
627092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  jvmtiEnv* env = reinterpret_cast<jvmtiEnv*>(ctx);
628092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::Locks::thread_list_lock_->AssertHeld(art::Thread::Current());
629092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS());
630092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  if (global_tls != nullptr) {
631092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    global_tls->data.erase(env);
632092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  }
633092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light}
634092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light
635092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Lightvoid ThreadUtil::RemoveEnvironment(jvmtiEnv* env) {
636092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::Thread* self = art::Thread::Current();
637092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::MutexLock mu(self, *art::Locks::thread_list_lock_);
638092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::ThreadList* list = art::Runtime::Current()->GetThreadList();
639092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  list->ForEach(RemoveTLSData, env);
640092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light}
641092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light
642092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex LightjvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) {
643092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::Thread* self = art::Thread::Current();
644092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::ScopedObjectAccess soa(self);
645092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::MutexLock mu(self, *art::Locks::thread_list_lock_);
6467ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::Thread* target = nullptr;
6477ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  jvmtiError err = ERR(INTERNAL);
6487ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
6497ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return err;
650f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
651f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
652092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS());
653092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  if (global_tls == nullptr) {
654092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    target->SetCustomTLS(new JvmtiGlobalTLSData);
655092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS());
656092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  }
657092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light
658092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  global_tls->data[env] = data;
659f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
660f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  return ERR(NONE);
661f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe}
662f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
663092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex LightjvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env,
664f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             jthread thread,
665f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             void** data_ptr) {
666f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (data_ptr == nullptr) {
667f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(NULL_POINTER);
668f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
669f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
670092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::Thread* self = art::Thread::Current();
671092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::ScopedObjectAccess soa(self);
672092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  art::MutexLock mu(self, *art::Locks::thread_list_lock_);
6737ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::Thread* target = nullptr;
6747ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  jvmtiError err = ERR(INTERNAL);
6757ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
6767ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return err;
677f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
6788580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
679092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS());
680092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  if (global_tls == nullptr) {
681092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    *data_ptr = nullptr;
682092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    return OK;
683092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  }
684092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  auto it = global_tls->data.find(env);
685092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  if (it != global_tls->data.end()) {
686092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    *data_ptr = const_cast<void*>(it->second);
687092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  } else {
688092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light    *data_ptr = nullptr;
689092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light  }
690092a4046ff7bd3d7e24bc77cecf3d1bb0aa52107Alex Light
6918580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  return ERR(NONE);
6928580744607a963d408956c3eb712b0e070c139b0Andreas Gampe}
6938580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
694732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestruct AgentData {
695732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  const void* arg;
696732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jvmtiStartFunction proc;
697732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jthread thread;
698732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JavaVM* java_vm;
699732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jvmtiEnv* jvmti_env;
700732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jint priority;
701732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe};
702732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
703732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestatic void* AgentCallback(void* arg) {
704732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg));
705732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  CHECK(data->thread != nullptr);
706732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
707732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // We already have a peer. So call our special Attach function.
708732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  art::Thread* self = art::Thread::Attach("JVMTI Agent thread", true, data->thread);
709739bf72ccb22794bc65203aa4824dba737cadd72Alex Light  CHECK(self != nullptr) << "threads_being_born_ should have ensured thread could be attached.";
710732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // The name in Attach() is only for logging. Set the thread name. This is important so
711732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // that the thread is no longer seen as starting up.
712732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  {
713732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    art::ScopedObjectAccess soa(self);
714732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    self->SetThreadName("JVMTI Agent thread");
715732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
716732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
717732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Release the peer.
718732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JNIEnv* env = self->GetJniEnv();
719732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  env->DeleteGlobalRef(data->thread);
720732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->thread = nullptr;
721732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
722739bf72ccb22794bc65203aa4824dba737cadd72Alex Light  {
723739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    // The StartThreadBirth was called in the parent thread. We let the runtime know we are up
724739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    // before going into the provided code.
725739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_);
726739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::Runtime::Current()->EndThreadBirth();
727739bf72ccb22794bc65203aa4824dba737cadd72Alex Light  }
728739bf72ccb22794bc65203aa4824dba737cadd72Alex Light
729732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Run the agent code.
730732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->proc(data->jvmti_env, env, const_cast<void*>(data->arg));
731732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
732732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Detach the thread.
733732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  int detach_result = data->java_vm->DetachCurrentThread();
734732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  CHECK_EQ(detach_result, 0);
735732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
736732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  return nullptr;
737732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}
738732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
739732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas GampejvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env,
740732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jthread thread,
741732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jvmtiStartFunction proc,
742732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      const void* arg,
743732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jint priority) {
74423aa74818272a9d659414536324ae9133ecb8743Alex Light  if (!PhaseUtil::IsLivePhase()) {
74523aa74818272a9d659414536324ae9133ecb8743Alex Light    return ERR(WRONG_PHASE);
74623aa74818272a9d659414536324ae9133ecb8743Alex Light  }
747732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
748732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INVALID_PRIORITY);
749732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
750732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JNIEnv* env = art::Thread::Current()->GetJniEnv();
751732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) {
752732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INVALID_THREAD);
753732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
754732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (proc == nullptr) {
755732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(NULL_POINTER);
756732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
757732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
758739bf72ccb22794bc65203aa4824dba737cadd72Alex Light  {
759739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::Runtime* runtime = art::Runtime::Current();
760739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_);
761739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    if (runtime->IsShuttingDownLocked()) {
762739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // The runtime is shutting down so we cannot create new threads.
763739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // TODO It's not fully clear from the spec what we should do here. We aren't yet in
764739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // JVMTI_PHASE_DEAD so we cannot return ERR(WRONG_PHASE) but creating new threads is now
765739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // impossible. Existing agents don't seem to generally do anything with this return value so
766739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // it doesn't matter too much. We could do something like sending a fake ThreadStart event
767739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      // even though code is never actually run.
768739bf72ccb22794bc65203aa4824dba737cadd72Alex Light      return ERR(INTERNAL);
769739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    }
770739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    runtime->StartThreadBirth();
771739bf72ccb22794bc65203aa4824dba737cadd72Alex Light  }
772739bf72ccb22794bc65203aa4824dba737cadd72Alex Light
773732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  std::unique_ptr<AgentData> data(new AgentData);
774732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->arg = arg;
775732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->proc = proc;
776732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // We need a global ref for Java objects, as local refs will be invalid.
777732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->thread = env->NewGlobalRef(thread);
778732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->java_vm = art::Runtime::Current()->GetJavaVM();
779732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->jvmti_env = jvmti_env;
780732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->priority = priority;
781732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
782732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  pthread_t pthread;
783732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  int pthread_create_result = pthread_create(&pthread,
784739bf72ccb22794bc65203aa4824dba737cadd72Alex Light                                            nullptr,
785739bf72ccb22794bc65203aa4824dba737cadd72Alex Light                                            &AgentCallback,
786739bf72ccb22794bc65203aa4824dba737cadd72Alex Light                                            reinterpret_cast<void*>(data.get()));
787732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (pthread_create_result != 0) {
788739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    // If the create succeeded the other thread will call EndThreadBirth.
789739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::Runtime* runtime = art::Runtime::Current();
790739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_);
791739bf72ccb22794bc65203aa4824dba737cadd72Alex Light    runtime->EndThreadBirth();
792732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INTERNAL);
793732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
794732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data.release();
795732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
796732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  return ERR(NONE);
797732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}
798732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
79988fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendOther(art::Thread* self,
8003ae82531b336b195a78c864c28af1448a74af633Alex Light                                    jthread target_jthread) {
80188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // Loop since we need to bail out and try again if we would end up getting suspended while holding
80288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we
80388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // release the lock, wait to get resumed and try again.
80488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  do {
80588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // Suspend ourself if we have any outstanding suspends. This is so we won't suspend due to
80688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // another SuspendThread in the middle of suspending something else potentially causing a
80788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // deadlock. We need to do this in the loop because if we ended up back here then we had
80888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // outstanding SuspendReason::kForUserCode suspensions and we should wait for them to be cleared
80988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // before continuing.
81088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    SuspendCheck(self);
81188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_);
81223aa74818272a9d659414536324ae9133ecb8743Alex Light    if (WouldSuspendForUserCodeLocked(self)) {
81388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
81488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // a user-code suspension. We retry and do another SuspendCheck to clear this.
81523aa74818272a9d659414536324ae9133ecb8743Alex Light      continue;
81688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
81723aa74818272a9d659414536324ae9133ecb8743Alex Light    // We are not going to be suspended by user code from now on.
8183ae82531b336b195a78c864c28af1448a74af633Alex Light    {
8193ae82531b336b195a78c864c28af1448a74af633Alex Light      art::ScopedObjectAccess soa(self);
8203ae82531b336b195a78c864c28af1448a74af633Alex Light      art::MutexLock thread_list_mu(self, *art::Locks::thread_list_lock_);
8217ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      art::Thread* target = nullptr;
8227ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      jvmtiError err = ERR(INTERNAL);
8237ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      if (!GetAliveNativeThread(target_jthread, soa, &target, &err)) {
8247ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light        return err;
8257ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      }
82688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      art::ThreadState state = target->GetState();
8277ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      if (state == art::ThreadState::kStarting || target->IsStillStarting()) {
82888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light        return ERR(THREAD_NOT_ALIVE);
8293ae82531b336b195a78c864c28af1448a74af633Alex Light      } else {
8303ae82531b336b195a78c864c28af1448a74af633Alex Light        art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_);
8313ae82531b336b195a78c864c28af1448a74af633Alex Light        if (target->GetUserCodeSuspendCount() != 0) {
8323ae82531b336b195a78c864c28af1448a74af633Alex Light          return ERR(THREAD_SUSPENDED);
8333ae82531b336b195a78c864c28af1448a74af633Alex Light        }
83488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      }
83588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
8363ae82531b336b195a78c864c28af1448a74af633Alex Light    bool timeout = true;
8373ae82531b336b195a78c864c28af1448a74af633Alex Light    art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer(
8383ae82531b336b195a78c864c28af1448a74af633Alex Light        target_jthread,
8393ae82531b336b195a78c864c28af1448a74af633Alex Light        /* request_suspension */ true,
8403ae82531b336b195a78c864c28af1448a74af633Alex Light        art::SuspendReason::kForUserCode,
8413ae82531b336b195a78c864c28af1448a74af633Alex Light        &timeout);
8423ae82531b336b195a78c864c28af1448a74af633Alex Light    if (ret_target == nullptr && !timeout) {
8433ae82531b336b195a78c864c28af1448a74af633Alex Light      // TODO It would be good to get more information about why exactly the thread failed to
8443ae82531b336b195a78c864c28af1448a74af633Alex Light      // suspend.
8453ae82531b336b195a78c864c28af1448a74af633Alex Light      return ERR(INTERNAL);
8463ae82531b336b195a78c864c28af1448a74af633Alex Light    } else if (!timeout) {
8473ae82531b336b195a78c864c28af1448a74af633Alex Light      // we didn't time out and got a result.
8483ae82531b336b195a78c864c28af1448a74af633Alex Light      return OK;
8493ae82531b336b195a78c864c28af1448a74af633Alex Light    }
8503ae82531b336b195a78c864c28af1448a74af633Alex Light    // We timed out. Just go around and try again.
85188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  } while (true);
85288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  UNREACHABLE();
85388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
85488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
85588fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendSelf(art::Thread* self) {
85688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  CHECK(self == art::Thread::Current());
85788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  {
85888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_);
85988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    art::MutexLock thread_list_mu(self, *art::Locks::thread_suspend_count_lock_);
86088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    if (self->GetUserCodeSuspendCount() != 0) {
86188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // This can only happen if we race with another thread to suspend 'self' and we lose.
86288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      return ERR(THREAD_SUSPENDED);
86388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
86488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // We shouldn't be able to fail this.
86588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    if (!self->ModifySuspendCount(self, +1, nullptr, art::SuspendReason::kForUserCode)) {
86688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      // TODO More specific error would be nice.
86788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      return ERR(INTERNAL);
86888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
86988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
87088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // Once we have requested the suspend we actually go to sleep. We need to do this after releasing
87188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // the suspend_lock to make sure we can be woken up. This call gains the mutator lock causing us
87288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // to go to sleep until we are resumed.
87388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  SuspendCheck(self);
87488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  return OK;
87588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
87688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
87788fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) {
87888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  art::Thread* self = art::Thread::Current();
8793ae82531b336b195a78c864c28af1448a74af633Alex Light  bool target_is_self = false;
88088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  {
88188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    art::ScopedObjectAccess soa(self);
8823ae82531b336b195a78c864c28af1448a74af633Alex Light    art::MutexLock mu(self, *art::Locks::thread_list_lock_);
8837ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    art::Thread* target = nullptr;
8847ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    jvmtiError err = ERR(INTERNAL);
8857ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    if (!GetAliveNativeThread(thread, soa, &target, &err)) {
8867ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      return err;
8873ae82531b336b195a78c864c28af1448a74af633Alex Light    } else if (target == self) {
8883ae82531b336b195a78c864c28af1448a74af633Alex Light      target_is_self = true;
8893ae82531b336b195a78c864c28af1448a74af633Alex Light    }
89088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
8913ae82531b336b195a78c864c28af1448a74af633Alex Light  if (target_is_self) {
89288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return SuspendSelf(self);
89388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  } else {
8943ae82531b336b195a78c864c28af1448a74af633Alex Light    return SuspendOther(self, thread);
89588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
89688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
89788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
89888fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::ResumeThread(jvmtiEnv* env ATTRIBUTE_UNUSED,
89988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                    jthread thread) {
90088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  if (thread == nullptr) {
90188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return ERR(NULL_POINTER);
90288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
90388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  art::Thread* self = art::Thread::Current();
90488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  art::Thread* target;
9053ae82531b336b195a78c864c28af1448a74af633Alex Light  // Retry until we know we won't get suspended by user code while resuming something.
9063ae82531b336b195a78c864c28af1448a74af633Alex Light  do {
9073ae82531b336b195a78c864c28af1448a74af633Alex Light    SuspendCheck(self);
9083ae82531b336b195a78c864c28af1448a74af633Alex Light    art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
90923aa74818272a9d659414536324ae9133ecb8743Alex Light    if (WouldSuspendForUserCodeLocked(self)) {
9103ae82531b336b195a78c864c28af1448a74af633Alex Light      // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by
9113ae82531b336b195a78c864c28af1448a74af633Alex Light      // a user-code suspension. We retry and do another SuspendCheck to clear this.
91223aa74818272a9d659414536324ae9133ecb8743Alex Light      continue;
91388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
9143ae82531b336b195a78c864c28af1448a74af633Alex Light    // From now on we know we cannot get suspended by user-code.
9153ae82531b336b195a78c864c28af1448a74af633Alex Light    {
9163ae82531b336b195a78c864c28af1448a74af633Alex Light      // NB This does a SuspendCheck (during thread state change) so we need to make sure we don't
9173ae82531b336b195a78c864c28af1448a74af633Alex Light      // have the 'suspend_lock' locked here.
9183ae82531b336b195a78c864c28af1448a74af633Alex Light      art::ScopedObjectAccess soa(self);
9193ae82531b336b195a78c864c28af1448a74af633Alex Light      art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
9207ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      jvmtiError err = ERR(INTERNAL);
9217ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      if (!GetAliveNativeThread(thread, soa, &target, &err)) {
9227ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light        return err;
9233ae82531b336b195a78c864c28af1448a74af633Alex Light      } else if (target == self) {
9243ae82531b336b195a78c864c28af1448a74af633Alex Light        // We would have paused until we aren't suspended anymore due to the ScopedObjectAccess so
9253ae82531b336b195a78c864c28af1448a74af633Alex Light        // we can just return THREAD_NOT_SUSPENDED. Unfortunately we cannot do any real DCHECKs
9263ae82531b336b195a78c864c28af1448a74af633Alex Light        // about current state since it's all concurrent.
9273ae82531b336b195a78c864c28af1448a74af633Alex Light        return ERR(THREAD_NOT_SUSPENDED);
9283ae82531b336b195a78c864c28af1448a74af633Alex Light      }
9293ae82531b336b195a78c864c28af1448a74af633Alex Light      // The JVMTI spec requires us to return THREAD_NOT_SUSPENDED if it is alive but we really
9303ae82531b336b195a78c864c28af1448a74af633Alex Light      // cannot tell why resume failed.
9313ae82531b336b195a78c864c28af1448a74af633Alex Light      {
9323ae82531b336b195a78c864c28af1448a74af633Alex Light        art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_);
9333ae82531b336b195a78c864c28af1448a74af633Alex Light        if (target->GetUserCodeSuspendCount() == 0) {
9343ae82531b336b195a78c864c28af1448a74af633Alex Light          return ERR(THREAD_NOT_SUSPENDED);
9353ae82531b336b195a78c864c28af1448a74af633Alex Light        }
9363ae82531b336b195a78c864c28af1448a74af633Alex Light      }
9373ae82531b336b195a78c864c28af1448a74af633Alex Light    }
9383ae82531b336b195a78c864c28af1448a74af633Alex Light    // It is okay that we don't have a thread_list_lock here since we know that the thread cannot
9393ae82531b336b195a78c864c28af1448a74af633Alex Light    // die since it is currently held suspended by a SuspendReason::kForUserCode suspend.
9403ae82531b336b195a78c864c28af1448a74af633Alex Light    DCHECK(target != self);
9413ae82531b336b195a78c864c28af1448a74af633Alex Light    if (!art::Runtime::Current()->GetThreadList()->Resume(target,
9423ae82531b336b195a78c864c28af1448a74af633Alex Light                                                          art::SuspendReason::kForUserCode)) {
9433ae82531b336b195a78c864c28af1448a74af633Alex Light      // TODO Give a better error.
9443ae82531b336b195a78c864c28af1448a74af633Alex Light      // This is most likely THREAD_NOT_SUSPENDED but we cannot really be sure.
9453ae82531b336b195a78c864c28af1448a74af633Alex Light      return ERR(INTERNAL);
9463ae82531b336b195a78c864c28af1448a74af633Alex Light    } else {
9473ae82531b336b195a78c864c28af1448a74af633Alex Light      return OK;
9483ae82531b336b195a78c864c28af1448a74af633Alex Light    }
9493ae82531b336b195a78c864c28af1448a74af633Alex Light  } while (true);
95088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
95188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
9527ddc23d9ea95848724754eae270a0a1ce108edb9Alex Lightstatic bool IsCurrentThread(jthread thr) {
9537ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (thr == nullptr) {
9547ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return true;
9557ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  }
9567ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::Thread* self = art::Thread::Current();
9577ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::ScopedObjectAccess soa(self);
9587ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::MutexLock mu(self, *art::Locks::thread_list_lock_);
9597ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  art::Thread* target = nullptr;
9607ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  jvmtiError err_unused = ERR(INTERNAL);
9617ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  if (ThreadUtil::GetNativeThread(thr, soa, &target, &err_unused)) {
9627ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return target == self;
9637ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  } else {
9647ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    return false;
9657ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light  }
9667ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light}
9677ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light
96888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// Suspends all the threads in the list at the same time. Getting this behavior is a little tricky
96988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// since we can have threads in the list multiple times. This generally doesn't matter unless the
97088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// current thread is present multiple times. In that case we need to suspend only once and either
97188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// return the same error code in all the other slots if it failed or return ERR(THREAD_SUSPENDED) if
97288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// it didn't. We also want to handle the current thread last to make the behavior of the code
97388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light// simpler to understand.
97488fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::SuspendThreadList(jvmtiEnv* env,
97588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                         jint request_count,
97688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                         const jthread* threads,
97788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                         jvmtiError* results) {
97888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  if (request_count == 0) {
97988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return ERR(ILLEGAL_ARGUMENT);
98088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  } else if (results == nullptr || threads == nullptr) {
98188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return ERR(NULL_POINTER);
98288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
98388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // This is the list of the indexes in 'threads' and 'results' that correspond to the currently
98488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // running thread. These indexes we need to handle specially since we need to only actually
98588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  // suspend a single time.
98688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  std::vector<jint> current_thread_indexes;
98788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  for (jint i = 0; i < request_count; i++) {
9887ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    if (IsCurrentThread(threads[i])) {
9897ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      current_thread_indexes.push_back(i);
9907ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light    } else {
9917ddc23d9ea95848724754eae270a0a1ce108edb9Alex Light      results[i] = env->SuspendThread(threads[i]);
99288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
99388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
99488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  if (!current_thread_indexes.empty()) {
99588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    jint first_current_thread_index = current_thread_indexes[0];
99688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // Suspend self.
99788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    jvmtiError res = env->SuspendThread(threads[first_current_thread_index]);
99888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    results[first_current_thread_index] = res;
99988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    // Fill in the rest of the error values as appropriate.
100088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    jvmtiError other_results = (res != OK) ? res : ERR(THREAD_SUSPENDED);
100188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    for (auto it = ++current_thread_indexes.begin(); it != current_thread_indexes.end(); ++it) {
100288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light      results[*it] = other_results;
100388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    }
100488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
100588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  return OK;
100688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
100788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
100888fd720b6799184c8ad61e766a6d37af33ed30efAlex LightjvmtiError ThreadUtil::ResumeThreadList(jvmtiEnv* env,
100988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                        jint request_count,
101088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                        const jthread* threads,
101188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light                                        jvmtiError* results) {
101288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  if (request_count == 0) {
101388fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return ERR(ILLEGAL_ARGUMENT);
101488fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  } else if (results == nullptr || threads == nullptr) {
101588fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    return ERR(NULL_POINTER);
101688fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
101788fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  for (jint i = 0; i < request_count; i++) {
101888fd720b6799184c8ad61e766a6d37af33ed30efAlex Light    results[i] = env->ResumeThread(threads[i]);
101988fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  }
102088fd720b6799184c8ad61e766a6d37af33ed30efAlex Light  return OK;
102188fd720b6799184c8ad61e766a6d37af33ed30efAlex Light}
102288fd720b6799184c8ad61e766a6d37af33ed30efAlex Light
102354d39dc42630cd83f2d1bec5704805febb894819Alex LightjvmtiError ThreadUtil::StopThread(jvmtiEnv* env ATTRIBUTE_UNUSED,
102454d39dc42630cd83f2d1bec5704805febb894819Alex Light                                  jthread thread,
102554d39dc42630cd83f2d1bec5704805febb894819Alex Light                                  jobject exception) {
102654d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::Thread* self = art::Thread::Current();
102754d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::ScopedObjectAccess soa(self);
102854d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::StackHandleScope<1> hs(self);
102954d39dc42630cd83f2d1bec5704805febb894819Alex Light  if (exception == nullptr) {
103054d39dc42630cd83f2d1bec5704805febb894819Alex Light    return ERR(INVALID_OBJECT);
103154d39dc42630cd83f2d1bec5704805febb894819Alex Light  }
103254d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::ObjPtr<art::mirror::Object> obj(soa.Decode<art::mirror::Object>(exception));
103354d39dc42630cd83f2d1bec5704805febb894819Alex Light  if (!obj->GetClass()->IsThrowableClass()) {
103454d39dc42630cd83f2d1bec5704805febb894819Alex Light    return ERR(INVALID_OBJECT);
103554d39dc42630cd83f2d1bec5704805febb894819Alex Light  }
103654d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::Handle<art::mirror::Throwable> exc(hs.NewHandle(obj->AsThrowable()));
1037b1e31a8337b9cce2f3160a972123886b355dce27Alex Light  art::Locks::thread_list_lock_->ExclusiveLock(self);
103854d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::Thread* target = nullptr;
103954d39dc42630cd83f2d1bec5704805febb894819Alex Light  jvmtiError err = ERR(INTERNAL);
104054d39dc42630cd83f2d1bec5704805febb894819Alex Light  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
1041b1e31a8337b9cce2f3160a972123886b355dce27Alex Light    art::Locks::thread_list_lock_->ExclusiveUnlock(self);
104254d39dc42630cd83f2d1bec5704805febb894819Alex Light    return err;
104354d39dc42630cd83f2d1bec5704805febb894819Alex Light  } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
1044b1e31a8337b9cce2f3160a972123886b355dce27Alex Light    art::Locks::thread_list_lock_->ExclusiveUnlock(self);
104554d39dc42630cd83f2d1bec5704805febb894819Alex Light    return ERR(THREAD_NOT_ALIVE);
104654d39dc42630cd83f2d1bec5704805febb894819Alex Light  }
104754d39dc42630cd83f2d1bec5704805febb894819Alex Light  struct StopThreadClosure : public art::Closure {
104854d39dc42630cd83f2d1bec5704805febb894819Alex Light   public:
104954d39dc42630cd83f2d1bec5704805febb894819Alex Light    explicit StopThreadClosure(art::Handle<art::mirror::Throwable> except) : exception_(except) { }
105054d39dc42630cd83f2d1bec5704805febb894819Alex Light
105154d39dc42630cd83f2d1bec5704805febb894819Alex Light    void Run(art::Thread* me) REQUIRES_SHARED(art::Locks::mutator_lock_) {
105254d39dc42630cd83f2d1bec5704805febb894819Alex Light      // Make sure the thread is prepared to notice the exception.
105354d39dc42630cd83f2d1bec5704805febb894819Alex Light      art::Runtime::Current()->GetInstrumentation()->InstrumentThreadStack(me);
105454d39dc42630cd83f2d1bec5704805febb894819Alex Light      me->SetAsyncException(exception_.Get());
105554d39dc42630cd83f2d1bec5704805febb894819Alex Light      // Wake up the thread if it is sleeping.
105654d39dc42630cd83f2d1bec5704805febb894819Alex Light      me->Notify();
105754d39dc42630cd83f2d1bec5704805febb894819Alex Light    }
105854d39dc42630cd83f2d1bec5704805febb894819Alex Light
105954d39dc42630cd83f2d1bec5704805febb894819Alex Light   private:
106054d39dc42630cd83f2d1bec5704805febb894819Alex Light    art::Handle<art::mirror::Throwable> exception_;
106154d39dc42630cd83f2d1bec5704805febb894819Alex Light  };
106254d39dc42630cd83f2d1bec5704805febb894819Alex Light  StopThreadClosure c(exc);
1063b1e31a8337b9cce2f3160a972123886b355dce27Alex Light  // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution.
106454d39dc42630cd83f2d1bec5704805febb894819Alex Light  if (target->RequestSynchronousCheckpoint(&c)) {
106554d39dc42630cd83f2d1bec5704805febb894819Alex Light    return OK;
106654d39dc42630cd83f2d1bec5704805febb894819Alex Light  } else {
106754d39dc42630cd83f2d1bec5704805febb894819Alex Light    // Something went wrong, probably the thread died.
106854d39dc42630cd83f2d1bec5704805febb894819Alex Light    return ERR(THREAD_NOT_ALIVE);
106954d39dc42630cd83f2d1bec5704805febb894819Alex Light  }
107054d39dc42630cd83f2d1bec5704805febb894819Alex Light}
107154d39dc42630cd83f2d1bec5704805febb894819Alex Light
107254d39dc42630cd83f2d1bec5704805febb894819Alex LightjvmtiError ThreadUtil::InterruptThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) {
107354d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::Thread* self = art::Thread::Current();
107454d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::ScopedObjectAccess soa(self);
107554d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
107654d39dc42630cd83f2d1bec5704805febb894819Alex Light  art::Thread* target = nullptr;
107754d39dc42630cd83f2d1bec5704805febb894819Alex Light  jvmtiError err = ERR(INTERNAL);
107854d39dc42630cd83f2d1bec5704805febb894819Alex Light  if (!GetAliveNativeThread(thread, soa, &target, &err)) {
107954d39dc42630cd83f2d1bec5704805febb894819Alex Light    return err;
108054d39dc42630cd83f2d1bec5704805febb894819Alex Light  } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
108154d39dc42630cd83f2d1bec5704805febb894819Alex Light    return ERR(THREAD_NOT_ALIVE);
108254d39dc42630cd83f2d1bec5704805febb894819Alex Light  }
108354d39dc42630cd83f2d1bec5704805febb894819Alex Light  target->Interrupt(self);
108454d39dc42630cd83f2d1bec5704805febb894819Alex Light  return OK;
108554d39dc42630cd83f2d1bec5704805febb894819Alex Light}
108654d39dc42630cd83f2d1bec5704805febb894819Alex Light
1087af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}  // namespace openjdkjvmti
1088