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