diff options
author | Brian Carlstrom <bdc@google.com> | 2011-10-28 01:16:28 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2011-10-28 12:34:54 -0700 |
commit | 00fae585c6e4a37b964c77f557fbf84f11e2d930 (patch) | |
tree | a4c392a07c0f19c388bfad90cf2f0f8540a9a86a /src | |
parent | fab62933853bf86275e683246f427cfe77205de3 (diff) | |
download | art-00fae585c6e4a37b964c77f557fbf84f11e2d930.zip art-00fae585c6e4a37b964c77f557fbf84f11e2d930.tar.gz art-00fae585c6e4a37b964c77f557fbf84f11e2d930.tar.bz2 |
Improved ClassLoader support for JNI FindClass, FieldFieldID, JNI_OnLoad
Also fix AttachCurrentThread to use the peer's thread name,
not the possibly null name from the arguments.
Change-Id: I12e612619d828734d8353a0dca44fb4f11ee0c66
Diffstat (limited to 'src')
-rw-r--r-- | src/jni_internal.cc | 15 | ||||
-rw-r--r-- | src/thread.cc | 31 |
2 files changed, 29 insertions, 17 deletions
diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 0982f83..5052773 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -310,6 +310,15 @@ jmethodID FindMethodID(ScopedJniThreadState& ts, jclass jni_class, const char* n return EncodeMethod(method); } +const ClassLoader* GetClassLoader(Thread* self) { + Frame frame = self->GetTopOfStack(); + Method* method = frame.GetMethod(); + if (method == NULL || PrettyMethod(method, false) == "java.lang.Runtime.nativeLoad") { + return self->GetClassLoaderOverride(); + } + return method->GetDeclaringClass()->GetClassLoader(); +} + jfieldID FindFieldID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) { Class* c = Decode<Class*>(ts, jni_class); if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true)) { @@ -320,8 +329,7 @@ jfieldID FindFieldID(ScopedJniThreadState& ts, jclass jni_class, const char* nam Class* field_type; ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); if (sig[1] != '\0') { - // TODO: need to get the appropriate ClassLoader. - const ClassLoader* cl = ts.Self()->GetClassLoaderOverride(); + const ClassLoader* cl = GetClassLoader(ts.Self()); field_type = class_linker->FindClass(sig, cl); } else { field_type = class_linker->FindPrimitiveClass(*sig); @@ -641,8 +649,7 @@ class JNI { std::string descriptor(NormalizeJniClassDescriptor(name)); Class* c = NULL; if (runtime->IsStarted()) { - // TODO: need to get the appropriate ClassLoader. - const ClassLoader* cl = ts.Self()->GetClassLoaderOverride(); + const ClassLoader* cl = GetClassLoader(ts.Self()); c = class_linker->FindClass(descriptor, cl); } else { c = class_linker->FindSystemClass(descriptor); diff --git a/src/thread.cc b/src/thread.cc index 6fdeefd..54d2e6c 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -164,10 +164,8 @@ void* Thread::CreateCallback(void* arg) { { CHECK_EQ(self->GetState(), Thread::kRunnable); - String* thread_name = reinterpret_cast<String*>(gThread_name->GetObject(self->peer_)); - if (thread_name != NULL) { - SetThreadName(thread_name->ToModifiedUtf8().c_str()); - } + SirtRef<String> thread_name(self->GetName()); + SetThreadName(thread_name->ToModifiedUtf8().c_str()); } Dbg::PostThreadStart(self); @@ -264,8 +262,6 @@ Thread* Thread::Attach(const Runtime* runtime, const char* name, bool as_daemon) self->SetState(Thread::kNative); - SetThreadName(name); - // If we're the main thread, ClassLinker won't be created until after we're attached, // so that thread needs a two-stage attach. Regular threads don't need this hack. if (self->thin_lock_id_ != ThreadList::kMainId) { @@ -300,13 +296,22 @@ void Thread::CreatePeer(const char* name, bool as_daemon) { peer_ = DecodeJObject(peer.get()); SetVmData(peer_, Thread::Current()); - // Because we mostly run without code available (in the compiler, in tests), we - // manually assign the fields the constructor should have set. - // TODO: lose this. - gThread_daemon->SetBoolean(peer_, thread_is_daemon); - gThread_group->SetObject(peer_, Decode<Object*>(env, thread_group.get())); - gThread_name->SetObject(peer_, Decode<Object*>(env, thread_name.get())); - gThread_priority->SetInt(peer_, thread_priority); + SirtRef<String> peer_thread_name(GetName()); + if (peer_thread_name.get() == NULL) { + // The Thread constructor should have set the Thread.name to a + // 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_, Decode<Object*>(env, thread_group.get())); + gThread_name->SetObject(peer_, Decode<Object*>(env, thread_name.get())); + gThread_priority->SetInt(peer_, thread_priority); + peer_thread_name.reset(GetName()); + } + // thread_name may have been null, so don't trust this to be non-null + if (peer_thread_name.get() != NULL) { + SetThreadName(GetName()->ToModifiedUtf8().c_str()); + } // Pre-allocate an OutOfMemoryError for the double-OOME case. ThrowNewException("Ljava/lang/OutOfMemoryError;", |