summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2012-05-29 09:12:18 -0700
committerElliott Hughes <enh@google.com>2012-05-29 11:38:43 -0700
commitaf8d15a3267343dec135cc6df1db740c0a5c7b52 (patch)
tree8fb28f60c50ca9c6d0f2bfa14e855a2a0a980ab4
parent8029cbe626a467b344ff84d86170d757aa12ecd4 (diff)
downloadart-af8d15a3267343dec135cc6df1db740c0a5c7b52.zip
art-af8d15a3267343dec135cc6df1db740c0a5c7b52.tar.gz
art-af8d15a3267343dec135cc6df1db740c0a5c7b52.tar.bz2
Move the thread.cc Class*/Field*/Method* caching over to WellKnownClasses.
Just heap.cc left to do, plus maybe some of the less convincing ClassLinker roots. Change-Id: Ib8adf3e28e00025e0c016dcd8d7b17e42f96796c
-rw-r--r--src/thread.cc141
-rw-r--r--src/well_known_classes.cc57
-rw-r--r--src/well_known_classes.h21
3 files changed, 109 insertions, 110 deletions
diff --git a/src/thread.cc b/src/thread.cc
index 3c3e56e..5c221e8 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -56,23 +56,6 @@ namespace art {
pthread_key_t Thread::pthread_key_self_;
-static Class* gThreadGroup = NULL;
-static Class* gThreadLock = NULL;
-static Field* gThread_daemon = NULL;
-static Field* gThread_group = NULL;
-static Field* gThread_lock = NULL;
-static Field* gThread_name = NULL;
-static Field* gThread_priority = NULL;
-static Field* gThread_uncaughtHandler = NULL;
-static Field* gThread_vmData = NULL;
-static Field* gThreadGroup_mMain = NULL;
-static Field* gThreadGroup_mSystem = NULL;
-static Field* gThreadGroup_name = NULL;
-static Field* gThreadLock_thread = NULL;
-static Method* gThread_run = NULL;
-static Method* gThreadGroup_removeThread = NULL;
-static Method* gUncaughtExceptionHandler_uncaughtException = NULL;
-
static const char* kThreadNameDuringStartup = "<native thread without managed peer>";
void Thread::InitCardTable() {
@@ -136,7 +119,8 @@ void* Thread::CreateCallback(void* arg) {
// Invoke the 'run' method of our java.lang.Thread.
CHECK(self->peer_ != NULL);
Object* receiver = self->peer_;
- Method* m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(gThread_run);
+ jmethodID mid = WellKnownClasses::java_lang_Thread_run;
+ Method* m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(DecodeMethod(mid));
m->Invoke(self, receiver, NULL, NULL);
// Detach.
@@ -146,11 +130,13 @@ void* Thread::CreateCallback(void* arg) {
}
static void SetVmData(Object* managed_thread, Thread* native_thread) {
- gThread_vmData->SetInt(managed_thread, reinterpret_cast<uintptr_t>(native_thread));
+ Field* f = DecodeField(WellKnownClasses::java_lang_Thread_vmData);
+ f->SetInt(managed_thread, reinterpret_cast<uintptr_t>(native_thread));
}
Thread* Thread::FromManagedThread(Object* thread_peer) {
- return reinterpret_cast<Thread*>(static_cast<uintptr_t>(gThread_vmData->GetInt(thread_peer)));
+ Field* f = DecodeField(WellKnownClasses::java_lang_Thread_vmData);
+ return reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetInt(thread_peer)));
}
Thread* Thread::FromManagedThread(JNIEnv* env, jobject java_thread) {
@@ -299,18 +285,20 @@ Thread* Thread::Attach(const char* thread_name, bool as_daemon, Object* thread_g
return self;
}
-Object* Thread::GetMainThreadGroup() {
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(gThreadGroup, true, true)) {
+static Object* GetWellKnownThreadGroup(jfieldID which) {
+ Class* c = WellKnownClasses::ToClass(WellKnownClasses::java_lang_ThreadGroup);
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
return NULL;
}
- return gThreadGroup_mMain->GetObject(NULL);
+ return DecodeField(which)->GetObject(NULL);
+}
+
+Object* Thread::GetMainThreadGroup() {
+ return GetWellKnownThreadGroup(WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup);
}
Object* Thread::GetSystemThreadGroup() {
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(gThreadGroup, true, true)) {
- return NULL;
- }
- return gThreadGroup_mSystem->GetObject(NULL);
+ return GetWellKnownThreadGroup(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
}
void Thread::CreatePeer(const char* name, bool as_daemon, Object* thread_group) {
@@ -344,10 +332,10 @@ void Thread::CreatePeer(const char* name, bool as_daemon, Object* thread_group)
// non-null value. However, because we can run without code
// available (in the compiler, in tests), we manually assign the
// fields the constructor should have set.
- gThread_daemon->SetBoolean(peer_, thread_is_daemon);
- gThread_group->SetObject(peer_, thread_group);
- gThread_name->SetObject(peer_, Decode<Object*>(env, thread_name.get()));
- gThread_priority->SetInt(peer_, thread_priority);
+ DecodeField(WellKnownClasses::java_lang_Thread_daemon)->SetBoolean(peer_, thread_is_daemon);
+ DecodeField(WellKnownClasses::java_lang_Thread_group)->SetObject(peer_, thread_group);
+ DecodeField(WellKnownClasses::java_lang_Thread_name)->SetObject(peer_, Decode<Object*>(env, thread_name.get()));
+ DecodeField(WellKnownClasses::java_lang_Thread_priority)->SetInt(peer_, thread_priority);
peer_thread_name.reset(GetThreadName());
}
// thread_name may have been null, so don't trust this to be non-null
@@ -442,7 +430,8 @@ void Thread::Dump(std::ostream& os, bool full) const {
}
String* Thread::GetThreadName() const {
- return (peer_ != NULL) ? reinterpret_cast<String*>(gThread_name->GetObject(peer_)) : NULL;
+ Field* f = DecodeField(WellKnownClasses::java_lang_Thread_name);
+ return (peer_ != NULL) ? reinterpret_cast<String*>(f->GetObject(peer_)) : NULL;
}
void Thread::GetThreadName(std::string& name) const {
@@ -455,12 +444,13 @@ void Thread::DumpState(std::ostream& os) const {
bool is_daemon = false;
if (peer_ != NULL) {
- priority = gThread_priority->GetInt(peer_);
- is_daemon = gThread_daemon->GetBoolean(peer_);
+ priority = DecodeField(WellKnownClasses::java_lang_Thread_priority)->GetInt(peer_);
+ is_daemon = DecodeField(WellKnownClasses::java_lang_Thread_daemon)->GetBoolean(peer_);
Object* thread_group = GetThreadGroup();
if (thread_group != NULL) {
- String* group_name_string = reinterpret_cast<String*>(gThreadGroup_name->GetObject(thread_group));
+ Field* group_name_field = DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
+ String* group_name_string = reinterpret_cast<String*>(group_name_field->GetObject(thread_group));
group_name = (group_name_string != NULL) ? group_name_string->ToModifiedUtf8() : "<null>";
}
} else {
@@ -788,71 +778,16 @@ void Thread::Startup() {
}
}
-// TODO: make more accessible?
-static Class* FindClassOrDie(ClassLinker* class_linker, const char* descriptor) {
- Class* c = class_linker->FindSystemClass(descriptor);
- CHECK(c != NULL) << descriptor;
- return c;
-}
-
-// TODO: make more accessible?
-static Field* FindFieldOrDie(Class* c, const char* name, const char* descriptor) {
- Field* f = c->FindDeclaredInstanceField(name, descriptor);
- CHECK(f != NULL) << PrettyClass(c) << " " << name << " " << descriptor;
- return f;
-}
-
-// TODO: make more accessible?
-static Method* FindMethodOrDie(Class* c, const char* name, const char* signature) {
- Method* m = c->FindVirtualMethod(name, signature);
- CHECK(m != NULL) << PrettyClass(c) << " " << name << " " << signature;
- return m;
-}
-
-// TODO: make more accessible?
-static Field* FindStaticFieldOrDie(Class* c, const char* name, const char* descriptor) {
- Field* f = c->FindDeclaredStaticField(name, descriptor);
- CHECK(f != NULL) << PrettyClass(c) << " " << name << " " << descriptor;
- return f;
-}
-
void Thread::FinishStartup() {
CHECK(Runtime::Current()->IsStarted());
Thread* self = Thread::Current();
- // Need to be kRunnable for FindClass
- ScopedThreadStateChange tsc(self, kRunnable);
-
- // Now the ClassLinker is ready, we can find the various Class*, Field*, and Method*s we need.
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-
- Class* Thread_class = FindClassOrDie(class_linker, "Ljava/lang/Thread;");
- Class* UncaughtExceptionHandler_class = FindClassOrDie(class_linker, "Ljava/lang/Thread$UncaughtExceptionHandler;");
- gThreadGroup = FindClassOrDie(class_linker, "Ljava/lang/ThreadGroup;");
- gThreadLock = FindClassOrDie(class_linker, "Ljava/lang/ThreadLock;");
-
- gThread_daemon = FindFieldOrDie(Thread_class, "daemon", "Z");
- gThread_group = FindFieldOrDie(Thread_class, "group", "Ljava/lang/ThreadGroup;");
- gThread_lock = FindFieldOrDie(Thread_class, "lock", "Ljava/lang/ThreadLock;");
- gThread_name = FindFieldOrDie(Thread_class, "name", "Ljava/lang/String;");
- gThread_priority = FindFieldOrDie(Thread_class, "priority", "I");
- gThread_uncaughtHandler = FindFieldOrDie(Thread_class, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
- gThread_vmData = FindFieldOrDie(Thread_class, "vmData", "I");
- gThreadGroup_name = FindFieldOrDie(gThreadGroup, "name", "Ljava/lang/String;");
- gThreadGroup_mMain = FindStaticFieldOrDie(gThreadGroup, "mMain", "Ljava/lang/ThreadGroup;");
- gThreadGroup_mSystem = FindStaticFieldOrDie(gThreadGroup, "mSystem", "Ljava/lang/ThreadGroup;");
- gThreadLock_thread = FindFieldOrDie(gThreadLock, "thread", "Ljava/lang/Thread;");
-
- gThread_run = FindMethodOrDie(Thread_class, "run", "()V");
- gThreadGroup_removeThread = FindMethodOrDie(gThreadGroup, "removeThread", "(Ljava/lang/Thread;)V");
- gUncaughtExceptionHandler_uncaughtException = FindMethodOrDie(UncaughtExceptionHandler_class,
- "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
-
// Finish attaching the main thread.
+ ScopedThreadStateChange tsc(self, kRunnable);
Thread::Current()->CreatePeer("main", false, Thread::GetMainThreadGroup());
InitBoxingMethods();
- class_linker->RunRootClinits();
+ Runtime::Current()->GetClassLinker()->RunRootClinits();
}
void Thread::Shutdown() {
@@ -860,14 +795,16 @@ void Thread::Shutdown() {
}
uint32_t Thread::LockOwnerFromThreadLock(Object* thread_lock) {
- if (thread_lock == NULL || thread_lock->GetClass() != gThreadLock) {
+ if (thread_lock == NULL || thread_lock->GetClass() != WellKnownClasses::ToClass(WellKnownClasses::java_lang_ThreadLock)) {
return ThreadList::kInvalidId;
}
- Object* managed_thread = gThreadLock_thread->GetObject(thread_lock);
+ Field* thread_field = DecodeField(WellKnownClasses::java_lang_ThreadLock_thread);
+ Object* managed_thread = thread_field->GetObject(thread_lock);
if (managed_thread == NULL) {
return ThreadList::kInvalidId;
}
- uintptr_t vmData = static_cast<uintptr_t>(gThread_vmData->GetInt(managed_thread));
+ Field* vmData_field = DecodeField(WellKnownClasses::java_lang_Thread_vmData);
+ uintptr_t vmData = static_cast<uintptr_t>(vmData_field->GetInt(managed_thread));
Thread* thread = reinterpret_cast<Thread*>(vmData);
if (thread == NULL) {
return ThreadList::kInvalidId;
@@ -949,7 +886,7 @@ void Thread::Destroy() {
// Thread.join() is implemented as an Object.wait() on the Thread.lock
// object. Signal anyone who is waiting.
- Object* lock = gThread_lock->GetObject(peer_);
+ Object* lock = DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(peer_);
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != NULL) {
lock->MonitorEnter(self);
@@ -989,14 +926,15 @@ void Thread::HandleUncaughtExceptions() {
ClearException();
// If the thread has its own handler, use that.
- Object* handler = gThread_uncaughtHandler->GetObject(peer_);
+ Object* handler = DecodeField(WellKnownClasses::java_lang_Thread_uncaughtHandler)->GetObject(peer_);
if (handler == NULL) {
// Otherwise use the thread group's default handler.
handler = GetThreadGroup();
}
// Call the handler.
- Method* m = handler->GetClass()->FindVirtualMethodForVirtualOrInterface(gUncaughtExceptionHandler_uncaughtException);
+ jmethodID mid = WellKnownClasses::java_lang_Thread$UncaughtExceptionHandler_uncaughtException;
+ Method* m = handler->GetClass()->FindVirtualMethodForVirtualOrInterface(DecodeMethod(mid));
JValue args[2];
args[0].SetL(peer_);
args[1].SetL(exception);
@@ -1007,7 +945,7 @@ void Thread::HandleUncaughtExceptions() {
}
Object* Thread::GetThreadGroup() const {
- return gThread_group->GetObject(peer_);
+ return DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(peer_);
}
void Thread::RemoveFromThreadGroup() {
@@ -1015,7 +953,8 @@ void Thread::RemoveFromThreadGroup() {
// group can be null if we're in the compiler or a test.
Object* group = GetThreadGroup();
if (group != NULL) {
- Method* m = group->GetClass()->FindVirtualMethodForVirtualOrInterface(gThreadGroup_removeThread);
+ jmethodID mid = WellKnownClasses::java_lang_ThreadGroup_removeThread;
+ Method* m = group->GetClass()->FindVirtualMethodForVirtualOrInterface(DecodeMethod(mid));
JValue args[1];
args[0].SetL(peer_);
m->Invoke(this, group, args, NULL);
@@ -1863,7 +1802,7 @@ bool Thread::HoldsLock(Object* object) {
}
bool Thread::IsDaemon() {
- return gThread_daemon->GetBoolean(peer_);
+ return DecodeField(WellKnownClasses::java_lang_Thread_daemon)->GetBoolean(peer_);
}
#if !defined(ART_USE_LLVM_COMPILER)
diff --git a/src/well_known_classes.cc b/src/well_known_classes.cc
index 7e21a66..c89771a 100644
--- a/src/well_known_classes.cc
+++ b/src/well_known_classes.cc
@@ -20,6 +20,7 @@
#include "logging.h"
#include "ScopedLocalRef.h"
+#include "thread.h"
namespace art {
@@ -34,6 +35,9 @@ jclass WellKnownClasses::java_lang_reflect_Method;
jclass WellKnownClasses::java_lang_reflect_Proxy;
jclass WellKnownClasses::java_lang_reflect_UndeclaredThrowableException;
jclass WellKnownClasses::java_lang_Thread;
+jclass WellKnownClasses::java_lang_Thread$UncaughtExceptionHandler;
+jclass WellKnownClasses::java_lang_ThreadGroup;
+jclass WellKnownClasses::java_lang_ThreadLock;
jclass WellKnownClasses::java_nio_ReadWriteDirectByteBuffer;
jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk;
jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer;
@@ -44,10 +48,24 @@ jmethodID WellKnownClasses::java_lang_Daemons_requestHeapTrim;
jmethodID WellKnownClasses::java_lang_Daemons_start;
jmethodID WellKnownClasses::java_lang_reflect_InvocationHandler_invoke;
jmethodID WellKnownClasses::java_lang_Thread_init;
+jmethodID WellKnownClasses::java_lang_Thread_run;
+jmethodID WellKnownClasses::java_lang_Thread$UncaughtExceptionHandler_uncaughtException;
+jmethodID WellKnownClasses::java_lang_ThreadGroup_removeThread;
jmethodID WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_init;
jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
+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_uncaughtHandler;
+jfieldID WellKnownClasses::java_lang_Thread_vmData;
+jfieldID WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup;
+jfieldID WellKnownClasses::java_lang_ThreadGroup_name;
+jfieldID WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
+jfieldID WellKnownClasses::java_lang_ThreadLock_thread;
jfieldID WellKnownClasses::java_lang_reflect_Proxy_h;
jfieldID WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_capacity;
jfieldID WellKnownClasses::java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress;
@@ -64,8 +82,8 @@ static jclass CacheClass(JNIEnv* env, const char* jni_class_name) {
return reinterpret_cast<jclass>(env->NewGlobalRef(c.get()));
}
-static jfieldID CacheField(JNIEnv* env, jclass c, const char* name, const char* signature) {
- jfieldID fid = env->GetFieldID(c, name, signature);
+static jfieldID CacheField(JNIEnv* env, jclass c, bool is_static, const char* name, const char* signature) {
+ jfieldID fid = is_static ? env->GetStaticFieldID(c, name, signature) : env->GetFieldID(c, name, signature);
if (fid == NULL) {
LOG(FATAL) << "Couldn't find field \"" << name << "\" with signature \"" << signature << "\"";
}
@@ -92,6 +110,9 @@ void WellKnownClasses::Init(JNIEnv* env) {
java_lang_reflect_Proxy = CacheClass(env, "java/lang/reflect/Proxy");
java_lang_reflect_UndeclaredThrowableException = CacheClass(env, "java/lang/reflect/UndeclaredThrowableException");
java_lang_Thread = CacheClass(env, "java/lang/Thread");
+ java_lang_Thread$UncaughtExceptionHandler = CacheClass(env, "java/lang/Thread$UncaughtExceptionHandler");
+ java_lang_ThreadGroup = CacheClass(env, "java/lang/ThreadGroup");
+ java_lang_ThreadLock = CacheClass(env, "java/lang/ThreadLock");
java_nio_ReadWriteDirectByteBuffer = CacheClass(env, "java/nio/ReadWriteDirectByteBuffer");
org_apache_harmony_dalvik_ddmc_Chunk = CacheClass(env, "org/apache/harmony/dalvik/ddmc/Chunk");
org_apache_harmony_dalvik_ddmc_DdmServer = CacheClass(env, "org/apache/harmony/dalvik/ddmc/DdmServer");
@@ -102,17 +123,35 @@ void WellKnownClasses::Init(JNIEnv* env) {
java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V");
java_lang_reflect_InvocationHandler_invoke = CacheMethod(env, java_lang_reflect_InvocationHandler, false, "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
java_lang_Thread_init = CacheMethod(env, java_lang_Thread, false, "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
+ java_lang_Thread_run = CacheMethod(env, java_lang_Thread, false, "run", "()V");
+ java_lang_Thread$UncaughtExceptionHandler_uncaughtException = CacheMethod(env, java_lang_Thread$UncaughtExceptionHandler, false, "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
+ java_lang_ThreadGroup_removeThread = CacheMethod(env, java_lang_ThreadGroup, false, "removeThread", "(Ljava/lang/Thread;)V");
java_nio_ReadWriteDirectByteBuffer_init = CacheMethod(env, java_nio_ReadWriteDirectByteBuffer, false, "<init>", "(II)V");
org_apache_harmony_dalvik_ddmc_DdmServer_broadcast = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "broadcast", "(I)V");
org_apache_harmony_dalvik_ddmc_DdmServer_dispatch = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;");
- java_lang_reflect_Proxy_h = CacheField(env, java_lang_reflect_Proxy, "h", "Ljava/lang/reflect/InvocationHandler;");
- java_nio_ReadWriteDirectByteBuffer_capacity = CacheField(env, java_nio_ReadWriteDirectByteBuffer, "capacity", "I");
- java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress = CacheField(env, java_nio_ReadWriteDirectByteBuffer, "effectiveDirectAddress", "I");
- org_apache_harmony_dalvik_ddmc_Chunk_data = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, "data", "[B");
- org_apache_harmony_dalvik_ddmc_Chunk_length = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, "length", "I");
- org_apache_harmony_dalvik_ddmc_Chunk_offset = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, "offset", "I");
- org_apache_harmony_dalvik_ddmc_Chunk_type = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, "type", "I");
+ java_lang_Thread_daemon = CacheField(env, java_lang_Thread, 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/ThreadLock;");
+ 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_uncaughtHandler = CacheField(env, java_lang_Thread, false, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
+ java_lang_Thread_vmData = CacheField(env, java_lang_Thread, false, "vmData", "I");
+ java_lang_ThreadGroup_mainThreadGroup = CacheField(env, java_lang_ThreadGroup, true, "mainThreadGroup", "Ljava/lang/ThreadGroup;");
+ java_lang_ThreadGroup_name = CacheField(env, java_lang_ThreadGroup, false, "name", "Ljava/lang/String;");
+ java_lang_ThreadGroup_systemThreadGroup = CacheField(env, java_lang_ThreadGroup, true, "systemThreadGroup", "Ljava/lang/ThreadGroup;");
+ java_lang_ThreadLock_thread = CacheField(env, java_lang_ThreadLock, false, "thread", "Ljava/lang/Thread;");
+ java_lang_reflect_Proxy_h = CacheField(env, java_lang_reflect_Proxy, false, "h", "Ljava/lang/reflect/InvocationHandler;");
+ java_nio_ReadWriteDirectByteBuffer_capacity = CacheField(env, java_nio_ReadWriteDirectByteBuffer, false, "capacity", "I");
+ java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress = CacheField(env, java_nio_ReadWriteDirectByteBuffer, false, "effectiveDirectAddress", "I");
+ org_apache_harmony_dalvik_ddmc_Chunk_data = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "data", "[B");
+ org_apache_harmony_dalvik_ddmc_Chunk_length = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "length", "I");
+ org_apache_harmony_dalvik_ddmc_Chunk_offset = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "offset", "I");
+ org_apache_harmony_dalvik_ddmc_Chunk_type = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "type", "I");
+}
+
+Class* WellKnownClasses::ToClass(jclass global_jclass) {
+ return reinterpret_cast<Class*>(Thread::Current()->DecodeJObject(global_jclass));
}
} // namespace art
diff --git a/src/well_known_classes.h b/src/well_known_classes.h
index 5d45938..613c47e 100644
--- a/src/well_known_classes.h
+++ b/src/well_known_classes.h
@@ -21,6 +21,8 @@
namespace art {
+class Class;
+
// Various classes used in JNI. We cache them so we don't have to keep looking
// them up. Similar to libcore's JniConstants (except there's no overlap, so
// we keep them separate).
@@ -28,6 +30,8 @@ namespace art {
struct WellKnownClasses {
static void Init(JNIEnv* env);
+ static Class* ToClass(jclass global_jclass);
+
static jclass com_android_dex_Dex;
static jclass java_lang_ClassLoader;
static jclass java_lang_ClassNotFoundException;
@@ -39,6 +43,9 @@ struct WellKnownClasses {
static jclass java_lang_reflect_Proxy;
static jclass java_lang_reflect_UndeclaredThrowableException;
static jclass java_lang_Thread;
+ static jclass java_lang_ThreadGroup;
+ static jclass java_lang_ThreadLock;
+ static jclass java_lang_Thread$UncaughtExceptionHandler;
static jclass java_nio_ReadWriteDirectByteBuffer;
static jclass org_apache_harmony_dalvik_ddmc_Chunk;
static jclass org_apache_harmony_dalvik_ddmc_DdmServer;
@@ -49,11 +56,25 @@ struct WellKnownClasses {
static jmethodID java_lang_Daemons_start;
static jmethodID java_lang_reflect_InvocationHandler_invoke;
static jmethodID java_lang_Thread_init;
+ static jmethodID java_lang_Thread_run;
+ static jmethodID java_lang_Thread$UncaughtExceptionHandler_uncaughtException;
+ static jmethodID java_lang_ThreadGroup_removeThread;
static jmethodID java_nio_ReadWriteDirectByteBuffer_init;
static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_dispatch;
static jfieldID java_lang_reflect_Proxy_h;
+ 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_uncaughtHandler;
+ static jfieldID java_lang_Thread_vmData;
+ static jfieldID java_lang_ThreadGroup_mainThreadGroup;
+ static jfieldID java_lang_ThreadGroup_name;
+ static jfieldID java_lang_ThreadGroup_systemThreadGroup;
+ static jfieldID java_lang_ThreadLock_thread;
static jfieldID java_nio_ReadWriteDirectByteBuffer_capacity;
static jfieldID java_nio_ReadWriteDirectByteBuffer_effectiveDirectAddress;
static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_data;