Change well known `Thread` fields to `ArtField*`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 253570082
Change-Id: Ie2d3075ba75e8513aa91b9e4d950e71616fc1cc1
diff --git a/adbconnection/adbconnection.cc b/adbconnection/adbconnection.cc
index f9ebe40..d0dde29 100644
--- a/adbconnection/adbconnection.cc
+++ b/adbconnection/adbconnection.cc
@@ -23,6 +23,7 @@
#include "adbconnection/client.h"
#include "android-base/endian.h"
#include "android-base/stringprintf.h"
+#include "art_field-inl.h"
#include "base/file_utils.h"
#include "base/globals.h"
#include "base/logging.h"
@@ -180,15 +181,18 @@
}
}
-static jobject CreateAdbConnectionThread(art::Thread* thr) {
- JNIEnv* env = thr->GetJniEnv();
- // Move to native state to talk with the jnienv api.
- art::ScopedThreadStateChange stsc(thr, art::ThreadState::kNative);
+static jobject CreateAdbConnectionThread(art::ScopedObjectAccess& soa)
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ JNIEnv* env = soa.Self()->GetJniEnv();
ScopedLocalRef<jstring> thr_name(env, env->NewStringUTF(kAdbConnectionThreadName));
- ScopedLocalRef<jobject> thr_group(
- env,
- env->GetStaticObjectField(art::WellKnownClasses::java_lang_ThreadGroup,
- art::WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup));
+ art::ArtField* system_thread_group_field =
+ art::WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
+ // Avoid using `ArtField::GetObject` as it requires linking against `libdexfile` for
+ // `operator<<(std::ostream&, Primitive::Type)`.
+ art::ObjPtr<art::mirror::Object> system_thread_group =
+ system_thread_group_field->GetDeclaringClass()->GetFieldObject<art::mirror::Object>(
+ system_thread_group_field->GetOffset());
+ ScopedLocalRef<jobject> thr_group(env, soa.AddLocalReference<jobject>(system_thread_group));
return env->NewObject(art::WellKnownClasses::java_lang_Thread,
art::WellKnownClasses::java_lang_Thread_init,
thr_group.get(),
@@ -274,7 +278,7 @@
}
runtime->StartThreadBirth();
}
- ScopedLocalRef<jobject> thr(soa.Env(), CreateAdbConnectionThread(soa.Self()));
+ ScopedLocalRef<jobject> thr(soa.Env(), CreateAdbConnectionThread(soa));
// Note: Using pthreads instead of std::thread to not abort when the thread cannot be
// created (exception support required).
std::unique_ptr<CallbackData> data(new CallbackData { this, soa.Env()->NewGlobalRef(thr.get()) });
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 82165d0..55fe9ef 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -447,9 +447,8 @@
if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
art::Thread* self = art::Thread::Current();
art::JNIEnvExt* jnienv = self->GetJniEnv();
- art::ArtField* parkBlockerField = art::jni::DecodeArtField(
- art::WellKnownClasses::java_lang_Thread_parkBlocker);
- art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
+ art::ObjPtr<art::mirror::Object> blocker_obj =
+ art::WellKnownClasses::java_lang_Thread_parkBlocker->GetObj(self->GetPeer());
if (blocker_obj.IsNull()) {
blocker_obj = self->GetPeer();
}
@@ -505,9 +504,8 @@
if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
art::Thread* self = art::Thread::Current();
art::JNIEnvExt* jnienv = self->GetJniEnv();
- art::ArtField* parkBlockerField = art::jni::DecodeArtField(
- art::WellKnownClasses::java_lang_Thread_parkBlocker);
- art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
+ art::ObjPtr<art::mirror::Object> blocker_obj =
+ art::WellKnownClasses::java_lang_Thread_parkBlocker->GetObj(self->GetPeer());
if (blocker_obj.IsNull()) {
blocker_obj = self->GetPeer();
}
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 7fb789d..a138c69 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -297,7 +297,7 @@
// ThreadGroup.
if (peer != nullptr) {
- art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
+ art::ArtField* f = art::WellKnownClasses::java_lang_Thread_group;
CHECK(f != nullptr);
art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
info_ptr->thread_group = group == nullptr
@@ -322,7 +322,7 @@
// Name.
{
- art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name);
+ art::ArtField* f = art::WellKnownClasses::java_lang_Thread_name;
CHECK(f != nullptr);
art::ObjPtr<art::mirror::Object> name = f->GetObject(peer);
std::string name_cpp;
@@ -343,21 +343,21 @@
// Priority.
{
- art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority);
+ art::ArtField* f = art::WellKnownClasses::java_lang_Thread_priority;
CHECK(f != nullptr);
info_ptr->priority = static_cast<jint>(f->GetInt(peer));
}
// Daemon.
{
- art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon);
+ art::ArtField* f = art::WellKnownClasses::java_lang_Thread_daemon;
CHECK(f != nullptr);
info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE;
}
// ThreadGroup.
{
- art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
+ art::ArtField* f = art::WellKnownClasses::java_lang_Thread_group;
CHECK(f != nullptr);
art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
info_ptr->thread_group = group == nullptr
@@ -846,15 +846,16 @@
data->java_vm = art::Runtime::Current()->GetJavaVM();
data->jvmti_env = jvmti_env;
data->priority = priority;
- ScopedLocalRef<jstring> s(
- env,
- reinterpret_cast<jstring>(
- env->GetObjectField(thread, art::WellKnownClasses::java_lang_Thread_name)));
- if (s == nullptr) {
- data->name = "JVMTI Agent Thread";
- } else {
- ScopedUtfChars name(env, s.get());
- data->name = name.c_str();
+ {
+ art::ScopedObjectAccess soa(env);
+ art::ObjPtr<art::mirror::Object> name =
+ art::WellKnownClasses::java_lang_Thread_name->GetObject(
+ soa.Decode<art::mirror::Object>(thread));
+ if (name == nullptr) {
+ data->name = "JVMTI Agent Thread";
+ } else {
+ data->name = name->AsString()->ToModifiedUtf8();
+ }
}
pthread_t pthread;
diff --git a/openjdkjvmti/ti_threadgroup.cc b/openjdkjvmti/ti_threadgroup.cc
index bc912cf..e7d91ef 100644
--- a/openjdkjvmti/ti_threadgroup.cc
+++ b/openjdkjvmti/ti_threadgroup.cc
@@ -106,8 +106,7 @@
// Do the name first. It's the only thing that can fail.
{
- art::ArtField* name_field =
- art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_name);
+ art::ArtField* name_field = art::WellKnownClasses::java_lang_ThreadGroup_name;
CHECK(name_field != nullptr);
art::ObjPtr<art::mirror::String> name_obj =
art::ObjPtr<art::mirror::String>::DownCast(name_field->GetObject(obj.Get()));
@@ -129,8 +128,7 @@
// Parent.
{
- art::ArtField* parent_field =
- art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_parent);
+ art::ArtField* parent_field = art::WellKnownClasses::java_lang_ThreadGroup_parent;
CHECK(parent_field != nullptr);
art::ObjPtr<art::mirror::Object> parent_group = parent_field->GetObject(obj.Get());
info_ptr->parent = parent_group == nullptr
@@ -161,8 +159,7 @@
REQUIRES_SHARED(art::Locks::mutator_lock_) {
CHECK(desired_thread_group != nullptr);
- art::ArtField* thread_group_field =
- art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group);
+ art::ArtField* thread_group_field = art::WellKnownClasses::java_lang_Thread_group;
DCHECK(thread_group_field != nullptr);
art::ObjPtr<art::mirror::Object> group = thread_group_field->GetObject(peer);
return (group == desired_thread_group.Get());
@@ -194,8 +191,7 @@
CHECK(thread_group != nullptr);
// Get the ThreadGroup[] "groups" out of this thread group...
- art::ArtField* groups_field =
- art::jni::DecodeArtField(art::WellKnownClasses::java_lang_ThreadGroup_groups);
+ art::ArtField* groups_field = art::WellKnownClasses::java_lang_ThreadGroup_groups;
art::ObjPtr<art::mirror::Object> groups_array = groups_field->GetObject(thread_group.Get());
if (groups_array == nullptr) {
diff --git a/runtime/native/jdk_internal_misc_Unsafe.cc b/runtime/native/jdk_internal_misc_Unsafe.cc
index e708732..7ab9152 100644
--- a/runtime/native/jdk_internal_misc_Unsafe.cc
+++ b/runtime/native/jdk_internal_misc_Unsafe.cc
@@ -487,8 +487,7 @@
// or the thread has already terminated. Setting the field to true will be
// respected when the thread does start, and is harmless if the thread has
// already terminated.
- ArtField* unparked =
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_unparkedBeforeStart);
+ ArtField* unparked = WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
// JNI must use non transactional mode.
unparked->SetBoolean<false>(soa.Decode<mirror::Object>(jthread), JNI_TRUE);
}
diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc
index 1781a29..da28489 100644
--- a/runtime/native/sun_misc_Unsafe.cc
+++ b/runtime/native/sun_misc_Unsafe.cc
@@ -534,8 +534,7 @@
// or the thread has already terminated. Setting the field to true will be
// respected when the thread does start, and is harmless if the thread has
// already terminated.
- ArtField* unparked =
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_unparkedBeforeStart);
+ ArtField* unparked = WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
// JNI must use non transactional mode.
unparked->SetBoolean<false>(soa.Decode<mirror::Object>(jthread), JNI_TRUE);
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 46429e8..d3c268b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2246,17 +2246,15 @@
}
void Runtime::InitThreadGroups(Thread* self) {
- JNIEnvExt* env = self->GetJniEnv();
- ScopedJniEnvLocalRefState env_state(env);
+ ScopedObjectAccess soa(self);
+ ArtField* main_thread_group_field = WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup;
+ ArtField* system_thread_group_field = WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
+ ObjPtr<mirror::Class> thread_group_class = main_thread_group_field->GetDeclaringClass();
main_thread_group_ =
- env->NewGlobalRef(env->GetStaticObjectField(
- WellKnownClasses::java_lang_ThreadGroup,
- WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup));
+ soa.Vm()->AddGlobalRef(self, main_thread_group_field->GetObject(thread_group_class));
CHECK_IMPLIES(main_thread_group_ == nullptr, IsAotCompiler());
system_thread_group_ =
- env->NewGlobalRef(env->GetStaticObjectField(
- WellKnownClasses::java_lang_ThreadGroup,
- WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup));
+ soa.Vm()->AddGlobalRef(self, system_thread_group_field->GetObject(thread_group_class));
CHECK_IMPLIES(system_thread_group_ == nullptr, IsAotCompiler());
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 58f1dc1..5ce9d17 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -641,7 +641,7 @@
self->DeleteJPeer(self->GetJniEnv());
self->SetThreadName(self->GetThreadName()->ToModifiedUtf8().c_str());
- ArtField* priorityField = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_priority);
+ ArtField* priorityField = WellKnownClasses::java_lang_Thread_priority;
self->SetNativePriority(priorityField->GetInt(self->tlsPtr_.opeer));
runtime->GetRuntimeCallbacks()->ThreadStart(self);
@@ -649,8 +649,7 @@
// Unpark ourselves if the java peer was unparked before it started (see
// b/28845097#comment49 for more information)
- ArtField* unparkedField = jni::DecodeArtField(
- WellKnownClasses::java_lang_Thread_unparkedBeforeStart);
+ ArtField* unparkedField = WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
bool should_unpark = false;
{
// Hold the lock here, so that if another thread calls unpark before the thread starts
@@ -676,7 +675,7 @@
Thread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa,
ObjPtr<mirror::Object> thread_peer) {
- ArtField* f = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_nativePeer);
+ ArtField* f = WellKnownClasses::java_lang_Thread_nativePeer;
Thread* result = reinterpret_cast64<Thread*>(f->GetLong(thread_peer));
// Check that if we have a result it is either suspended or we hold the thread_list_lock_
// to stop it from going away.
@@ -834,6 +833,22 @@
madvise(pregion, unwanted_size, MADV_DONTNEED);
}
+template <bool kSupportTransaction>
+static void SetNativePeer(ObjPtr<mirror::Object> java_peer, Thread* thread)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ ArtField* field = WellKnownClasses::java_lang_Thread_nativePeer;
+ if (kSupportTransaction && Runtime::Current()->IsActiveTransaction()) {
+ field->SetLong</*kTransactionActive=*/ true>(java_peer, reinterpret_cast<jlong>(thread));
+ } else {
+ field->SetLong</*kTransactionActive=*/ false>(java_peer, reinterpret_cast<jlong>(thread));
+ }
+}
+
+static void SetNativePeer(JNIEnv* env, jobject java_peer, Thread* thread) {
+ ScopedObjectAccess soa(env);
+ SetNativePeer</*kSupportTransaction=*/ false>(soa.Decode<mirror::Object>(java_peer), thread);
+}
+
void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) {
CHECK(java_peer != nullptr);
Thread* self = static_cast<JNIEnvExt*>(env)->GetSelf();
@@ -841,7 +856,7 @@
if (VLOG_IS_ON(threads)) {
ScopedObjectAccess soa(env);
- ArtField* f = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_name);
+ ArtField* f = WellKnownClasses::java_lang_Thread_name;
ObjPtr<mirror::String> java_name =
f->GetObject(soa.Decode<mirror::Object>(java_peer))->AsString();
std::string thread_name;
@@ -880,8 +895,7 @@
// Thread.start is synchronized, so we know that nativePeer is 0, and know that we're not racing
// to assign it.
- env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer,
- reinterpret_cast<jlong>(child_thread));
+ SetNativePeer(env, java_peer, child_thread);
// Try to allocate a JNIEnvExt for the thread. We do this here as we might be out of memory and
// do not have a good way to report this on the child's side.
@@ -925,7 +939,7 @@
delete child_thread;
child_thread = nullptr;
// TODO: remove from thread group?
- env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, 0);
+ SetNativePeer(env, java_peer, nullptr);
{
std::string msg(child_jni_env_ext.get() == nullptr ?
StringPrintf("Could not allocate JNI Env: %s", error_msg.c_str()) :
@@ -1093,14 +1107,11 @@
Thread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_peer) {
auto set_peer_action = [&](Thread* self) {
// Install the given peer.
- {
- DCHECK(self == Thread::Current());
- ScopedObjectAccess soa(self);
- self->tlsPtr_.opeer = soa.Decode<mirror::Object>(thread_peer).Ptr();
- }
- self->GetJniEnv()->SetLongField(thread_peer,
- WellKnownClasses::java_lang_Thread_nativePeer,
- reinterpret_cast64<jlong>(self));
+ DCHECK(self == Thread::Current());
+ ScopedObjectAccess soa(self);
+ ObjPtr<mirror::Object> peer = soa.Decode<mirror::Object>(thread_peer);
+ self->tlsPtr_.opeer = peer.Ptr();
+ SetNativePeer</*kSupportTransaction=*/ false>(peer, self);
return true;
};
return Attach(thread_name, as_daemon, set_peer_action, /* should_run_callbacks= */ true);
@@ -1142,11 +1153,9 @@
Thread* self = this;
DCHECK_EQ(self, Thread::Current());
- env->SetLongField(peer.get(),
- WellKnownClasses::java_lang_Thread_nativePeer,
- reinterpret_cast64<jlong>(self));
-
ScopedObjectAccess soa(self);
+ SetNativePeer</*kSupportTransaction=*/ false>(soa.Decode<mirror::Object>(peer.get()), self);
+
StackHandleScope<1> hs(self);
MutableHandle<mirror::String> peer_thread_name(hs.NewHandle(GetThreadName()));
if (peer_thread_name == nullptr) {
@@ -1235,14 +1244,13 @@
jobject thread_group,
jobject thread_name,
jint thread_priority) {
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_daemon)->
+ WellKnownClasses::java_lang_Thread_daemon->
SetBoolean<kTransactionActive>(peer, thread_is_daemon);
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_group)->
+ WellKnownClasses::java_lang_Thread_group->
SetObject<kTransactionActive>(peer, soa.Decode<mirror::Object>(thread_group));
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_name)->
+ WellKnownClasses::java_lang_Thread_name->
SetObject<kTransactionActive>(peer, soa.Decode<mirror::Object>(thread_name));
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_priority)->
- SetInt<kTransactionActive>(peer, thread_priority);
+ WellKnownClasses::java_lang_Thread_priority->SetInt<kTransactionActive>(peer, thread_priority);
}
void Thread::SetCachedThreadName(const char* name) {
@@ -1417,11 +1425,10 @@
}
ObjPtr<mirror::String> Thread::GetThreadName() const {
- ArtField* f = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_name);
if (tlsPtr_.opeer == nullptr) {
return nullptr;
}
- ObjPtr<mirror::Object> name = f->GetObject(tlsPtr_.opeer);
+ ObjPtr<mirror::Object> name = WellKnownClasses::java_lang_Thread_name->GetObject(tlsPtr_.opeer);
return name == nullptr ? nullptr : name->AsString();
}
@@ -1959,20 +1966,15 @@
// cause ScopedObjectAccessUnchecked to deadlock.
if (gAborting == 0 && self != nullptr && thread != nullptr && thread->tlsPtr_.opeer != nullptr) {
ScopedObjectAccessUnchecked soa(self);
- priority = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_priority)
- ->GetInt(thread->tlsPtr_.opeer);
- is_daemon = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_daemon)
- ->GetBoolean(thread->tlsPtr_.opeer);
+ priority = WellKnownClasses::java_lang_Thread_priority->GetInt(thread->tlsPtr_.opeer);
+ is_daemon = WellKnownClasses::java_lang_Thread_daemon->GetBoolean(thread->tlsPtr_.opeer);
ObjPtr<mirror::Object> thread_group =
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_group)
- ->GetObject(thread->tlsPtr_.opeer);
+ WellKnownClasses::java_lang_Thread_group->GetObject(thread->tlsPtr_.opeer);
if (thread_group != nullptr) {
- ArtField* group_name_field =
- jni::DecodeArtField(WellKnownClasses::java_lang_ThreadGroup_name);
ObjPtr<mirror::String> group_name_string =
- group_name_field->GetObject(thread_group)->AsString();
+ WellKnownClasses::java_lang_ThreadGroup_name->GetObject(thread_group)->AsString();
group_name = (group_name_string != nullptr) ? group_name_string->ToModifiedUtf8() : "<null>";
}
} else if (thread != nullptr) {
@@ -2434,9 +2436,9 @@
jobject thread_group_jobject = thread_group;
if (thread_group == nullptr || kIsDebugBuild) {
// There is always a group set. Retrieve it.
- thread_group_jobject_scoped.reset(
- soa.Env()->GetObjectField(thread_jobject.get(),
- WellKnownClasses::java_lang_Thread_group));
+ thread_group_jobject_scoped.reset(soa.AddLocalReference<jobject>(
+ WellKnownClasses::java_lang_Thread_group->GetObject(
+ soa.Decode<mirror::Object>(thread_jobject.get()))));
thread_group_jobject = thread_group_jobject_scoped.get();
if (kIsDebugBuild && thread_group != nullptr) {
CHECK(soa.Env()->IsSameObject(thread_group, thread_group_jobject));
@@ -2578,18 +2580,12 @@
}
// this.nativePeer = 0;
- if (Runtime::Current()->IsActiveTransaction()) {
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_nativePeer)
- ->SetLong<true>(tlsPtr_.opeer, 0);
- } else {
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_nativePeer)
- ->SetLong<false>(tlsPtr_.opeer, 0);
- }
+ SetNativePeer</*kSupportTransaction=*/ true>(tlsPtr_.opeer, nullptr);
// Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone
// who is waiting.
ObjPtr<mirror::Object> lock =
- jni::DecodeArtField(WellKnownClasses::java_lang_Thread_lock)->GetObject(tlsPtr_.opeer);
+ WellKnownClasses::java_lang_Thread_lock->GetObject(tlsPtr_.opeer);
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != nullptr) {
StackHandleScope<1> hs(self);
@@ -2679,8 +2675,8 @@
void Thread::RemoveFromThreadGroup(ScopedObjectAccessAlreadyRunnable& soa) {
// this.group.removeThread(this);
// group can be null if we're in the compiler or a test.
- ObjPtr<mirror::Object> ogroup = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_group)
- ->GetObject(tlsPtr_.opeer);
+ ObjPtr<mirror::Object> ogroup =
+ WellKnownClasses::java_lang_Thread_group->GetObject(tlsPtr_.opeer);
if (ogroup != nullptr) {
ScopedLocalRef<jobject> group(soa.Env(), soa.AddLocalReference<jobject>(ogroup));
ScopedLocalRef<jobject> peer(soa.Env(), soa.AddLocalReference<jobject>(tlsPtr_.opeer));
@@ -4800,8 +4796,7 @@
if (GetPeer() == nullptr) {
return false;
}
- return jni::DecodeArtField(
- WellKnownClasses::java_lang_Thread_systemDaemon)->GetBoolean(GetPeer());
+ return WellKnownClasses::java_lang_Thread_systemDaemon->GetBoolean(GetPeer());
}
std::string Thread::StateAndFlagsAsHexString() const {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index d2614a6..8fa7bde 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -30,6 +30,7 @@
#include "nativehelper/scoped_utf_chars.h"
#include "unwindstack/AndroidUnwinder.h"
+#include "art_field-inl.h"
#include "base/aborting.h"
#include "base/histogram-inl.h"
#include "base/mutex-inl.h"
@@ -44,8 +45,10 @@
#include "gc_root.h"
#include "jni/jni_internal.h"
#include "lock_word.h"
+#include "mirror/string.h"
#include "monitor.h"
#include "native_stack_dump.h"
+#include "obj_ptr-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "trace.h"
@@ -862,20 +865,16 @@
return true;
}
-static void ThreadSuspendByPeerWarning(Thread* self,
+static void ThreadSuspendByPeerWarning(ScopedObjectAccess& soa,
LogSeverity severity,
const char* message,
- jobject peer) {
- JNIEnvExt* env = self->GetJniEnv();
- ScopedLocalRef<jstring>
- scoped_name_string(env, static_cast<jstring>(env->GetObjectField(
- peer, WellKnownClasses::java_lang_Thread_name)));
- ScopedUtfChars scoped_name_chars(env, scoped_name_string.get());
- if (scoped_name_chars.c_str() == nullptr) {
- LOG(severity) << message << ": " << peer;
- env->ExceptionClear();
+ jobject peer) REQUIRES_SHARED(Locks::mutator_lock_) {
+ ObjPtr<mirror::Object> name =
+ WellKnownClasses::java_lang_Thread_name->GetObject(soa.Decode<mirror::Object>(peer));
+ if (name == nullptr) {
+ LOG(severity) << message << ": " << peer;
} else {
- LOG(severity) << message << ": " << peer << ":" << scoped_name_chars.c_str();
+ LOG(severity) << message << ": " << peer << ":" << name->AsString()->ToModifiedUtf8();
}
}
@@ -913,7 +912,7 @@
reason);
DCHECK(updated);
}
- ThreadSuspendByPeerWarning(self,
+ ThreadSuspendByPeerWarning(soa,
::android::base::WARNING,
"No such thread for suspend",
peer);
@@ -966,7 +965,7 @@
const uint64_t total_delay = NanoTime() - start_time;
if (total_delay >= thread_suspend_timeout_ns_) {
if (suspended_thread == nullptr) {
- ThreadSuspendByPeerWarning(self,
+ ThreadSuspendByPeerWarning(soa,
::android::base::FATAL,
"Failed to issue suspend request",
peer);
@@ -978,7 +977,7 @@
// Explicitly release thread_suspend_count_lock_; we haven't held it for long, so
// seeing threads blocked on it is not informative.
Locks::thread_suspend_count_lock_->Unlock(self);
- ThreadSuspendByPeerWarning(self,
+ ThreadSuspendByPeerWarning(soa,
::android::base::FATAL,
"Thread suspension timed out",
peer);
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 308e013..52a9f6b 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -143,21 +143,21 @@
ArtField* WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
ArtField* WellKnownClasses::java_io_FileDescriptor_descriptor;
ArtField* WellKnownClasses::java_lang_ClassLoader_parent;
-jfieldID WellKnownClasses::java_lang_Thread_parkBlocker;
-jfieldID WellKnownClasses::java_lang_Thread_daemon;
-jfieldID WellKnownClasses::java_lang_Thread_group;
-jfieldID WellKnownClasses::java_lang_Thread_lock;
-jfieldID WellKnownClasses::java_lang_Thread_name;
-jfieldID WellKnownClasses::java_lang_Thread_priority;
-jfieldID WellKnownClasses::java_lang_Thread_nativePeer;
-jfieldID WellKnownClasses::java_lang_Thread_systemDaemon;
-jfieldID WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_groups;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_ngroups;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_name;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_parent;
-jfieldID WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
+ArtField* WellKnownClasses::java_lang_Thread_parkBlocker;
+ArtField* WellKnownClasses::java_lang_Thread_daemon;
+ArtField* WellKnownClasses::java_lang_Thread_group;
+ArtField* WellKnownClasses::java_lang_Thread_lock;
+ArtField* WellKnownClasses::java_lang_Thread_name;
+ArtField* WellKnownClasses::java_lang_Thread_priority;
+ArtField* WellKnownClasses::java_lang_Thread_nativePeer;
+ArtField* WellKnownClasses::java_lang_Thread_systemDaemon;
+ArtField* WellKnownClasses::java_lang_Thread_unparkedBeforeStart;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_groups;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_ngroups;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_name;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_parent;
+ArtField* WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
jfieldID WellKnownClasses::java_lang_Throwable_cause;
jfieldID WellKnownClasses::java_lang_Throwable_detailMessage;
jfieldID WellKnownClasses::java_lang_Throwable_stackTrace;
@@ -502,29 +502,36 @@
java_lang_ClassLoader_parent = CacheField(
j_l_cl, /*is_static=*/ false, "parent", "Ljava/lang/ClassLoader;");
+ ObjPtr<mirror::Class> j_l_Thread = soa.Decode<mirror::Class>(java_lang_Thread);
java_lang_Thread_parkBlocker =
- CacheField(env, java_lang_Thread, false, "parkBlocker", "Ljava/lang/Object;");
- java_lang_Thread_daemon = CacheField(env, java_lang_Thread, false, "daemon", "Z");
+ CacheField(j_l_Thread, /*is_static=*/ false, "parkBlocker", "Ljava/lang/Object;");
+ java_lang_Thread_daemon = CacheField(j_l_Thread, /*is_static=*/ false, "daemon", "Z");
java_lang_Thread_group =
- CacheField(env, java_lang_Thread, false, "group", "Ljava/lang/ThreadGroup;");
- java_lang_Thread_lock = CacheField(env, java_lang_Thread, false, "lock", "Ljava/lang/Object;");
- java_lang_Thread_name = CacheField(env, java_lang_Thread, false, "name", "Ljava/lang/String;");
- java_lang_Thread_priority = CacheField(env, java_lang_Thread, false, "priority", "I");
- java_lang_Thread_nativePeer = CacheField(env, java_lang_Thread, false, "nativePeer", "J");
- java_lang_Thread_systemDaemon = CacheField(env, java_lang_Thread, false, "systemDaemon", "Z");
+ CacheField(j_l_Thread, /*is_static=*/ false, "group", "Ljava/lang/ThreadGroup;");
+ java_lang_Thread_lock =
+ CacheField(j_l_Thread, /*is_static=*/ false, "lock", "Ljava/lang/Object;");
+ java_lang_Thread_name =
+ CacheField(j_l_Thread, /*is_static=*/ false, "name", "Ljava/lang/String;");
+ java_lang_Thread_priority = CacheField(j_l_Thread, /*is_static=*/ false, "priority", "I");
+ java_lang_Thread_nativePeer = CacheField(j_l_Thread, /*is_static=*/ false, "nativePeer", "J");
+ java_lang_Thread_systemDaemon =
+ CacheField(j_l_Thread, /*is_static=*/ false, "systemDaemon", "Z");
java_lang_Thread_unparkedBeforeStart =
- CacheField(env, java_lang_Thread, false, "unparkedBeforeStart", "Z");
+ CacheField(j_l_Thread, /*is_static=*/ false, "unparkedBeforeStart", "Z");
+
+ ObjPtr<mirror::Class> j_l_tg = soa.Decode<mirror::Class>(java_lang_ThreadGroup);
java_lang_ThreadGroup_groups =
- CacheField(env, java_lang_ThreadGroup, false, "groups", "[Ljava/lang/ThreadGroup;");
- java_lang_ThreadGroup_ngroups = CacheField(env, java_lang_ThreadGroup, false, "ngroups", "I");
+ CacheField(j_l_tg, /*is_static=*/ false, "groups", "[Ljava/lang/ThreadGroup;");
+ java_lang_ThreadGroup_ngroups = CacheField(j_l_tg, /*is_static=*/ false, "ngroups", "I");
java_lang_ThreadGroup_mainThreadGroup =
- CacheField(env, java_lang_ThreadGroup, true, "mainThreadGroup", "Ljava/lang/ThreadGroup;");
+ CacheField(j_l_tg, /*is_static=*/ true, "mainThreadGroup", "Ljava/lang/ThreadGroup;");
java_lang_ThreadGroup_name =
- CacheField(env, java_lang_ThreadGroup, false, "name", "Ljava/lang/String;");
+ CacheField(j_l_tg, /*is_static=*/ false, "name", "Ljava/lang/String;");
java_lang_ThreadGroup_parent =
- CacheField(env, java_lang_ThreadGroup, false, "parent", "Ljava/lang/ThreadGroup;");
+ CacheField(j_l_tg, /*is_static=*/ false, "parent", "Ljava/lang/ThreadGroup;");
java_lang_ThreadGroup_systemThreadGroup =
- CacheField(env, java_lang_ThreadGroup, true, "systemThreadGroup", "Ljava/lang/ThreadGroup;");
+ CacheField(j_l_tg, /*is_static=*/ true, "systemThreadGroup", "Ljava/lang/ThreadGroup;");
+
java_lang_Throwable_cause =
CacheField(env, java_lang_Throwable, false, "cause", "Ljava/lang/Throwable;");
java_lang_Throwable_detailMessage =
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index c6a0197..6ffca8a 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -156,21 +156,21 @@
static ArtField* dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
static ArtField* java_io_FileDescriptor_descriptor;
static ArtField* java_lang_ClassLoader_parent;
- static jfieldID java_lang_Thread_parkBlocker;
- static jfieldID java_lang_Thread_daemon;
- static jfieldID java_lang_Thread_group;
- static jfieldID java_lang_Thread_lock;
- static jfieldID java_lang_Thread_name;
- static jfieldID java_lang_Thread_priority;
- static jfieldID java_lang_Thread_nativePeer;
- static jfieldID java_lang_Thread_systemDaemon;
- static jfieldID java_lang_Thread_unparkedBeforeStart;
- static jfieldID java_lang_ThreadGroup_groups;
- static jfieldID java_lang_ThreadGroup_ngroups;
- static jfieldID java_lang_ThreadGroup_mainThreadGroup;
- static jfieldID java_lang_ThreadGroup_name;
- static jfieldID java_lang_ThreadGroup_parent;
- static jfieldID java_lang_ThreadGroup_systemThreadGroup;
+ static ArtField* java_lang_Thread_parkBlocker;
+ static ArtField* java_lang_Thread_daemon;
+ static ArtField* java_lang_Thread_group;
+ static ArtField* java_lang_Thread_lock;
+ static ArtField* java_lang_Thread_name;
+ static ArtField* java_lang_Thread_priority;
+ static ArtField* java_lang_Thread_nativePeer;
+ static ArtField* java_lang_Thread_systemDaemon;
+ static ArtField* java_lang_Thread_unparkedBeforeStart;
+ static ArtField* java_lang_ThreadGroup_groups;
+ static ArtField* java_lang_ThreadGroup_ngroups;
+ static ArtField* java_lang_ThreadGroup_mainThreadGroup;
+ static ArtField* java_lang_ThreadGroup_name;
+ static ArtField* java_lang_ThreadGroup_parent;
+ static ArtField* java_lang_ThreadGroup_systemThreadGroup;
static jfieldID java_lang_Throwable_cause;
static jfieldID java_lang_Throwable_detailMessage;
static jfieldID java_lang_Throwable_stackTrace;