ti_thread.cc revision 983c175aa134c7f6794a4b3407d7e99536b1f7f1
1af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe/* Copyright (C) 2017 The Android Open Source Project
2af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
4af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This file implements interfaces from the file jvmti.h. This implementation
5af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * is licensed under the same terms as the file jvmti.h.  The
6af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * copyright and license information for the file jvmti.h follows.
7af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
8af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
11af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is free software; you can redistribute it and/or modify it
12af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * under the terms of the GNU General Public License version 2 only, as
13af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * published by the Free Software Foundation.  Oracle designates this
14af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * particular file as subject to the "Classpath" exception as provided
15af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * by Oracle in the LICENSE file that accompanied this code.
16af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
17af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT
18af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * version 2 for more details (a copy is included in the LICENSE file that
21af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * accompanied this code).
22af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
23af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * You should have received a copy of the GNU General Public License version
24af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 2 along with this work; if not, write to the Free Software Foundation,
25af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *
27af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * or visit www.oracle.com if you need additional information or have any
29af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * questions.
30af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe */
31af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
32af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "ti_thread.h"
33af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
34eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "android-base/strings.h"
35af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_field.h"
36af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_jvmti.h"
37af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/logging.h"
38af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/mutex.h"
39eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "events-inl.h"
40f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc/system_weak.h"
41f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc_root-inl.h"
42af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "jni_internal.h"
43af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/class.h"
44af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/object-inl.h"
45af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/string.h"
46af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "obj_ptr.h"
47f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "runtime.h"
48eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "runtime_callbacks.h"
49eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "ScopedLocalRef.h"
50af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "scoped_thread_state_change-inl.h"
51af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "thread-inl.h"
528580744607a963d408956c3eb712b0e070c139b0Andreas Gampe#include "thread_list.h"
53af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "well_known_classes.h"
54af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
55af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampenamespace openjdkjvmti {
56af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
57eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampestruct ThreadCallback : public art::ThreadLifecycleCallback, public art::RuntimePhaseCallback {
58eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
59eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    if (self->GetPeer() == nullptr) {
60eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      return nullptr;
61eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    }
62eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer());
63eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
64983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe  template <ArtJvmtiEvent kEvent>
65983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe  void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
66eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    DCHECK_EQ(self, art::Thread::Current());
67eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self));
68e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
69983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    event_handler->DispatchEvent<kEvent>(self,
70983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe                                         reinterpret_cast<JNIEnv*>(self->GetJniEnv()),
71983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe                                         thread.get());
72eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
73eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
74eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  void ThreadStart(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
75eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    if (!started) {
76eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // Runtime isn't started. We only expect at most the signal handler or JIT threads to be
77eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // started here.
78eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      if (art::kIsDebugBuild) {
79eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        std::string name;
80eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        self->GetThreadName(name);
81eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        if (name != "Signal Catcher" && !android::base::StartsWith(name, "Jit thread pool")) {
82eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe          LOG(FATAL) << "Unexpected thread before start: " << name;
83eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe        }
84eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      }
85eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      return;
86eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    }
87983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    Post<ArtJvmtiEvent::kThreadStart>(self);
88eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
89eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
90eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  void ThreadDeath(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
91983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe    Post<ArtJvmtiEvent::kThreadEnd>(self);
92eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
93eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
94eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  void NextRuntimePhase(RuntimePhase phase) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
95eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    if (phase == RuntimePhase::kInit) {
96eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // We moved to VMInit. Report the main thread as started (it was attached early, and must
97eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      // not be reported until Init.
98eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe      started = true;
99983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe      Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current());
100eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe    }
101eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  }
102eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
103eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  EventHandler* event_handler = nullptr;
104eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  bool started = false;
105eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe};
106eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
107eafaf57557939bcabeb7a7388fb4951e74661a53Andreas GampeThreadCallback gThreadCallback;
108eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
109eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Register(EventHandler* handler) {
110eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::Runtime* runtime = art::Runtime::Current();
111eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
112eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  gThreadCallback.started = runtime->IsStarted();
113eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  gThreadCallback.event_handler = handler;
114eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
115eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
116eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
117eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedSuspendAll ssa("Add thread callback");
118eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback);
119eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gThreadCallback);
120eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}
121eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
122eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Unregister() {
123eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
124eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
125eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::ScopedSuspendAll ssa("Remove thread callback");
126eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  art::Runtime* runtime = art::Runtime::Current();
127eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback);
128eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe  runtime->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&gThreadCallback);
129eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}
130eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe
131af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) {
132af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::Thread* self = art::Thread::Current();
133af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
134af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::ScopedObjectAccess soa(self);
135af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
136af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  jthread thread_peer;
137af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (self->IsStillStarting()) {
138af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    thread_peer = nullptr;
139af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  } else {
140af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    thread_peer = soa.AddLocalReference<jthread>(self->GetPeer());
141af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
142af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
143af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  *thread_ptr = thread_peer;
144af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return ERR(NONE);
145af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
146af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
147af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Read the context classloader from a Java thread object. This is a lazy implementation
148af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// that assumes GetThreadInfo isn't called too often. If we instead cache the ArtField,
149af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// we will have to add synchronization as this can't be cached on startup (which is
150af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// potentially runtime startup).
151af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampestatic art::ObjPtr<art::mirror::Object> GetContextClassLoader(art::ObjPtr<art::mirror::Object> peer)
152af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    REQUIRES_SHARED(art::Locks::mutator_lock_) {
153af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (peer == nullptr) {
154af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    return nullptr;
155af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
156af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = peer->GetClass();
157af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::ArtField* cc_field = klass->FindDeclaredInstanceField("contextClassLoader",
158af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                                             "Ljava/lang/ClassLoader;");
159af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  CHECK(cc_field != nullptr);
160af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return cc_field->GetObject(peer);
161af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
162af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
163af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Get the native thread. The spec says a null object denotes the current thread.
164af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampestatic art::Thread* GetNativeThread(jthread thread,
165af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                    const art::ScopedObjectAccessAlreadyRunnable& soa)
166af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    REQUIRES_SHARED(art::Locks::mutator_lock_) {
167af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (thread == nullptr) {
168af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    return art::Thread::Current();
169af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
170af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
171af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
172af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return art::Thread::FromManagedThread(soa, thread);
173af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
174af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
175af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) {
176af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (info_ptr == nullptr) {
177af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    return ERR(NULL_POINTER);
178af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
179af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
180af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
181af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
182af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  art::Thread* self = GetNativeThread(thread, soa);
183af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (self == nullptr && thread == nullptr) {
184af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    return ERR(INVALID_THREAD);
185af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
186af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
187af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  JvmtiUniquePtr name_uptr;
188af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  if (self != nullptr) {
189af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Have a native thread object, this thread is alive.
190af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    std::string name;
191af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    self->GetThreadName(name);
192af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    jvmtiError name_result = CopyString(
193af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        env, name.c_str(), reinterpret_cast<unsigned char**>(&info_ptr->name));
194af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    if (name_result != ERR(NONE)) {
195af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      return name_result;
196af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
197af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    name_uptr = MakeJvmtiUniquePtr(env, info_ptr->name);
198af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
199af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->priority = self->GetNativePriority();
200af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
201af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->is_daemon = self->IsDaemon();
202af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
203af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = self->GetPeer();
204af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
205af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // ThreadGroup.
206af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    if (peer != nullptr) {
207af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
208af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
209af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
210af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = group == nullptr
211af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   ? nullptr
212af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   : soa.AddLocalReference<jthreadGroup>(group);
213af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    } else {
214af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = nullptr;
215af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
216af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
217af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Context classloader.
218af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    art::ObjPtr<art::mirror::Object> ccl = GetContextClassLoader(peer);
219af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->context_class_loader = ccl == nullptr
220af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         ? nullptr
221af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         : soa.AddLocalReference<jobject>(ccl);
222af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  } else {
223af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Only the peer. This thread has either not been started, or is dead. Read things from
224af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // the Java side.
225af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread);
226af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
227af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Name.
228af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
229af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name);
230af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
231af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> name = f->GetObject(peer);
232af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      std::string name_cpp;
233af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      const char* name_cstr;
234af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      if (name != nullptr) {
235af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cpp = name->AsString()->ToModifiedUtf8();
236af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cstr = name_cpp.c_str();
237af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      } else {
238af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        name_cstr = "";
239af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      }
240af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      jvmtiError name_result = CopyString(
241af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe          env, name_cstr, reinterpret_cast<unsigned char**>(&info_ptr->name));
242af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      if (name_result != ERR(NONE)) {
243af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe        return name_result;
244af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      }
245af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      name_uptr = MakeJvmtiUniquePtr(env, info_ptr->name);
246af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
247af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
248af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Priority.
249af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
250af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority);
251af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
252af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->priority = static_cast<jint>(f->GetInt(peer));
253af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
254af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
255af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Daemon.
256af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
257af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon);
258af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
259af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE;
260af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
261af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
262af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // ThreadGroup.
263af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    {
264af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
265af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      CHECK(f != nullptr);
266af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
267af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe      info_ptr->thread_group = group == nullptr
268af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   ? nullptr
269af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                   : soa.AddLocalReference<jthreadGroup>(group);
270af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    }
271af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
272af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    // Context classloader.
273af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    art::ObjPtr<art::mirror::Object> ccl = GetContextClassLoader(peer);
274af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe    info_ptr->context_class_loader = ccl == nullptr
275af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         ? nullptr
276af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe                                         : soa.AddLocalReference<jobject>(ccl);
277af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  }
278af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
279af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  name_uptr.release();
280af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
281af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe  return ERR(NONE);
282af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}
283af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe
28472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe// Return the thread's (or current thread, if null) thread state. Return kStarting in case
28572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe// there's no native counterpart (thread hasn't been started, yet, or is dead).
28672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic art::ThreadState GetNativeThreadState(jthread thread,
28772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                             const art::ScopedObjectAccessAlreadyRunnable& soa,
28872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                             art::Thread** native_thread)
28972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    REQUIRES_SHARED(art::Locks::mutator_lock_) {
29072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  art::Thread* self = nullptr;
29172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
29272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (thread == nullptr) {
29372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    self = art::Thread::Current();
29472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  } else {
29572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    self = art::Thread::FromManagedThread(soa, thread);
29672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
29772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  *native_thread = self;
29872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (self == nullptr || self->IsStillStarting()) {
29972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    return art::ThreadState::kStarting;
30072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
30172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  return self->GetState();
30272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
30372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
30472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic jint GetJvmtiThreadStateFromInternal(art::ThreadState internal_thread_state) {
30572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  jint jvmti_state = JVMTI_THREAD_STATE_ALIVE;
30672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
30772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (internal_thread_state == art::ThreadState::kSuspended) {
30872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED;
30972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    // Note: We do not have data about the previous state. Otherwise we should load the previous
31072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    //       state here.
31172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
31272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
31372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (internal_thread_state == art::ThreadState::kNative) {
31472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_IN_NATIVE;
31572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
31672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
31772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (internal_thread_state == art::ThreadState::kRunnable ||
31872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      internal_thread_state == art::ThreadState::kWaitingWeakGcRootRead ||
31972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      internal_thread_state == art::ThreadState::kSuspended) {
32072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE;
32172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  } else if (internal_thread_state == art::ThreadState::kBlocked) {
32272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
32372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  } else {
32472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    // Should be in waiting state.
32572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_WAITING;
32672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
32772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    if (internal_thread_state == art::ThreadState::kTimedWaiting ||
32872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe        internal_thread_state == art::ThreadState::kSleeping) {
32972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      jvmti_state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
33072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    } else {
33172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      jvmti_state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
33272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    }
33372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
33472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    if (internal_thread_state == art::ThreadState::kSleeping) {
33572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      jvmti_state |= JVMTI_THREAD_STATE_SLEEPING;
33672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    }
33772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
33872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    if (internal_thread_state == art::ThreadState::kTimedWaiting ||
33972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe        internal_thread_state == art::ThreadState::kWaiting) {
34072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      jvmti_state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
34172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    }
34272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
34372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    // TODO: PARKED. We'll have to inspect the stack.
34472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
34572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
34672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  return jvmti_state;
34772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
34872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
34972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic jint GetJavaStateFromInternal(art::ThreadState internal_thread_state) {
35072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  switch (internal_thread_state) {
35172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kTerminated:
35272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
35372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
35472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kRunnable:
35572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kNative:
35672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingWeakGcRootRead:
35772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kSuspended:
35872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE;
35972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
36072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kTimedWaiting:
36172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kSleeping:
36272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING;
36372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
36472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kBlocked:
36572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED;
36672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
36772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kStarting:
36872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_NEW;
36972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
37072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaiting:
37172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGcToComplete:
37272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingPerformingGc:
37372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForCheckPointsToRun:
37472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerSend:
37572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerToAttach:
37672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingInMainDebuggerLoop:
37772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDebuggerSuspension:
37872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForDeoptimization:
37972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGetObjectsAllocated:
38072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForJniOnLoad:
38172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForSignalCatcherOutput:
38272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingInMainSignalCatcherLoop:
38372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForMethodTracingStart:
38472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForVisitObjects:
38572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    case art::ThreadState::kWaitingForGcThreadFlip:
38672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return JVMTI_JAVA_LANG_THREAD_STATE_WAITING;
38772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
38872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  LOG(FATAL) << "Unreachable";
38972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  UNREACHABLE();
39072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
39172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
39272c19834136c81eace33687e06f5daf92a5a7583Andreas GampejvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED,
39372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                      jthread thread,
39472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                      jint* thread_state_ptr) {
39572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (thread_state_ptr == nullptr) {
39672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    return ERR(NULL_POINTER);
39772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
39872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
39972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
40072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  art::Thread* native_thread = nullptr;
40172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  art::ThreadState internal_thread_state = GetNativeThreadState(thread, soa, &native_thread);
40272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
40372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (internal_thread_state == art::ThreadState::kStarting) {
40472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    if (thread == nullptr) {
40572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      // No native thread, and no Java thread? We must be starting up. Report as wrong phase.
40672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe      return ERR(WRONG_PHASE);
40772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    }
40872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
40972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    // Need to read the Java "started" field to know whether this is starting or terminated.
41072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread);
41172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    art::ObjPtr<art::mirror::Class> klass = peer->GetClass();
41272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    art::ArtField* started_field = klass->FindDeclaredInstanceField("started", "Z");
41372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    CHECK(started_field != nullptr);
41472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    bool started = started_field->GetBoolean(peer) != 0;
41572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW;
41672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED |
41772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe                                      JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
41872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    *thread_state_ptr = started ? kTerminatedState : kStartedState;
41972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    return ERR(NONE);
42072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
42172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  DCHECK(native_thread != nullptr);
42272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
42372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  // Translate internal thread state to JVMTI and Java state.
42472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  jint jvmti_state = GetJvmtiThreadStateFromInternal(internal_thread_state);
42572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  if (native_thread->IsInterrupted()) {
42672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe    jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED;
42772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  }
42872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
42972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  // Java state is derived from nativeGetState.
43072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  // Note: Our implementation assigns "runnable" to suspended. As such, we will have slightly
43172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  //       different mask. However, this is for consistency with the Java view.
43272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  jint java_state = GetJavaStateFromInternal(internal_thread_state);
43372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
43472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  *thread_state_ptr = jvmti_state | java_state;
43572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
43672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe  return ERR(NONE);
43772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe}
43872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe
4398580744607a963d408956c3eb712b0e070c139b0Andreas GampejvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env,
4408580744607a963d408956c3eb712b0e070c139b0Andreas Gampe                                     jint* threads_count_ptr,
4418580744607a963d408956c3eb712b0e070c139b0Andreas Gampe                                     jthread** threads_ptr) {
4428580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  if (threads_count_ptr == nullptr || threads_ptr == nullptr) {
4438580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    return ERR(NULL_POINTER);
4448580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
4458580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4468580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::Thread* current = art::Thread::Current();
4478580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4488580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::ScopedObjectAccess soa(current);
4498580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4508580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  art::MutexLock mu(current, *art::Locks::thread_list_lock_);
4518580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList();
4528580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4538580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  std::vector<art::ObjPtr<art::mirror::Object>> peers;
4548580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4558580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  for (art::Thread* thread : thread_list) {
4568580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    // Skip threads that are still starting.
4578580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (thread->IsStillStarting()) {
4588580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      continue;
4598580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
4608580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4618580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    art::ObjPtr<art::mirror::Object> peer = thread->GetPeer();
4628580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (peer != nullptr) {
4638580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      peers.push_back(peer);
4648580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
4658580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
4668580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4678580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  if (peers.empty()) {
4688580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_count_ptr = 0;
4698580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_ptr = nullptr;
4708580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  } else {
4718580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    unsigned char* data;
4728580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data);
4738580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    if (data_result != ERR(NONE)) {
4748580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      return data_result;
4758580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
4768580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    jthread* threads = reinterpret_cast<jthread*>(data);
4778580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    for (size_t i = 0; i != peers.size(); ++i) {
4788580744607a963d408956c3eb712b0e070c139b0Andreas Gampe      threads[i] = soa.AddLocalReference<jthread>(peers[i]);
4798580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    }
4808580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
4818580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_count_ptr = static_cast<jint>(peers.size());
4828580744607a963d408956c3eb712b0e070c139b0Andreas Gampe    *threads_ptr = threads;
4838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  }
484f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  return ERR(NONE);
485f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe}
486f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
487f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas GampejvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED,
488f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             jthread thread,
489f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             const void* data) {
490f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
491f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  art::Thread* self = GetNativeThread(thread, soa);
492f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (self == nullptr && thread == nullptr) {
493f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(INVALID_THREAD);
494f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
495f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (self == nullptr) {
496f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(THREAD_NOT_ALIVE);
497f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
498f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
499f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  self->SetCustomTLS(data);
500f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
501f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  return ERR(NONE);
502f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe}
503f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
504f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas GampejvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED,
505f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             jthread thread,
506f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe                                             void** data_ptr) {
507f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (data_ptr == nullptr) {
508f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(NULL_POINTER);
509f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
510f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe
511f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
512f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  art::Thread* self = GetNativeThread(thread, soa);
513f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (self == nullptr && thread == nullptr) {
514f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(INVALID_THREAD);
515f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
516f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  if (self == nullptr) {
517f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe    return ERR(THREAD_NOT_ALIVE);
518f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  }
5198580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
520f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe  *data_ptr = const_cast<void*>(self->GetCustomTLS());
5218580744607a963d408956c3eb712b0e070c139b0Andreas Gampe  return ERR(NONE);
5228580744607a963d408956c3eb712b0e070c139b0Andreas Gampe}
5238580744607a963d408956c3eb712b0e070c139b0Andreas Gampe
524732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestruct AgentData {
525732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  const void* arg;
526732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jvmtiStartFunction proc;
527732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jthread thread;
528732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JavaVM* java_vm;
529732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jvmtiEnv* jvmti_env;
530732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  jint priority;
531732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe};
532732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
533732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestatic void* AgentCallback(void* arg) {
534732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg));
535732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  CHECK(data->thread != nullptr);
536732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
537732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // We already have a peer. So call our special Attach function.
538732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  art::Thread* self = art::Thread::Attach("JVMTI Agent thread", true, data->thread);
539732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  CHECK(self != nullptr);
540732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // The name in Attach() is only for logging. Set the thread name. This is important so
541732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // that the thread is no longer seen as starting up.
542732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  {
543732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    art::ScopedObjectAccess soa(self);
544732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    self->SetThreadName("JVMTI Agent thread");
545732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
546732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
547732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Release the peer.
548732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JNIEnv* env = self->GetJniEnv();
549732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  env->DeleteGlobalRef(data->thread);
550732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->thread = nullptr;
551732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
552732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Run the agent code.
553732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->proc(data->jvmti_env, env, const_cast<void*>(data->arg));
554732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
555732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // Detach the thread.
556732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  int detach_result = data->java_vm->DetachCurrentThread();
557732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  CHECK_EQ(detach_result, 0);
558732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
559732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  return nullptr;
560732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}
561732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
562732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas GampejvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env,
563732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jthread thread,
564732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jvmtiStartFunction proc,
565732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      const void* arg,
566732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                      jint priority) {
567732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
568732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INVALID_PRIORITY);
569732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
570732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  JNIEnv* env = art::Thread::Current()->GetJniEnv();
571732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) {
572732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INVALID_THREAD);
573732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
574732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (proc == nullptr) {
575732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(NULL_POINTER);
576732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
577732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
578732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  std::unique_ptr<AgentData> data(new AgentData);
579732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->arg = arg;
580732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->proc = proc;
581732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  // We need a global ref for Java objects, as local refs will be invalid.
582732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->thread = env->NewGlobalRef(thread);
583732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->java_vm = art::Runtime::Current()->GetJavaVM();
584732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->jvmti_env = jvmti_env;
585732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data->priority = priority;
586732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
587732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  pthread_t pthread;
588732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  int pthread_create_result = pthread_create(&pthread,
589732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                             nullptr,
590732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                             &AgentCallback,
591732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe                                             reinterpret_cast<void*>(data.get()));
592732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  if (pthread_create_result != 0) {
593732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe    return ERR(INTERNAL);
594732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  }
595732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  data.release();
596732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
597732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe  return ERR(NONE);
598732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}
599732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe
600af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe}  // namespace openjdkjvmti
601