diff options
Diffstat (limited to 'openjdkjvmti/ti_thread.cc')
-rw-r--r-- | openjdkjvmti/ti_thread.cc | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc index a138c69945..5c0c3854a4 100644 --- a/openjdkjvmti/ti_thread.cc +++ b/openjdkjvmti/ti_thread.cc @@ -193,7 +193,7 @@ void ThreadUtil::CacheData() { art::Thread* self = art::Thread::Current(); art::ScopedObjectAccess soa(self); art::ObjPtr<art::mirror::Class> thread_class = - soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread); + art::WellKnownClasses::java_lang_Thread_init->GetDeclaringClass(); CHECK(thread_class != nullptr); context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader", "Ljava/lang/ClassLoader;"); @@ -236,7 +236,9 @@ bool ThreadUtil::GetNativeThread(jthread thread, if (thread == nullptr) { *thr = art::Thread::Current(); return true; - } else if (!soa.Env()->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { + } + art::ObjPtr<art::mirror::Object> othread = soa.Decode<art::mirror::Object>(thread); + if (!othread->InstanceOf(art::WellKnownClasses::java_lang_Thread_init->GetDeclaringClass())) { *err = ERR(INVALID_THREAD); return false; } else { @@ -618,7 +620,7 @@ jvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED, // Need to read the Java "started" field to know whether this is starting or terminated. art::Handle<art::mirror::Object> peer(hs.NewHandle(soa.Decode<art::mirror::Object>(thread))); art::ObjPtr<art::mirror::Class> thread_klass = - soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread); + art::WellKnownClasses::java_lang_Thread_init->GetDeclaringClass(); if (!thread_klass->IsAssignableFrom(peer->GetClass())) { return ERR(INVALID_THREAD); } @@ -815,39 +817,44 @@ jvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { return ERR(INVALID_PRIORITY); } - JNIEnv* env = art::Thread::Current()->GetJniEnv(); - if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { + if (thread == nullptr) { return ERR(INVALID_THREAD); } - if (proc == nullptr) { - return ERR(NULL_POINTER); - } - + art::Runtime* runtime = art::Runtime::Current(); + art::Thread* self = art::Thread::Current(); + std::unique_ptr<AgentData> data; { - art::Runtime* runtime = art::Runtime::Current(); - art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_); - if (runtime->IsShuttingDownLocked()) { - // The runtime is shutting down so we cannot create new threads. - // TODO It's not fully clear from the spec what we should do here. We aren't yet in - // JVMTI_PHASE_DEAD so we cannot return ERR(WRONG_PHASE) but creating new threads is now - // impossible. Existing agents don't seem to generally do anything with this return value so - // it doesn't matter too much. We could do something like sending a fake ThreadStart event - // even though code is never actually run. - return ERR(INTERNAL); + art::ScopedObjectAccess soa(self); + art::ObjPtr<art::mirror::Object> othread = soa.Decode<art::mirror::Object>(thread); + if (!othread->InstanceOf(art::WellKnownClasses::java_lang_Thread_init->GetDeclaringClass())) { + return ERR(INVALID_THREAD); + } + if (proc == nullptr) { + return ERR(NULL_POINTER); } - runtime->StartThreadBirth(); - } - std::unique_ptr<AgentData> data(new AgentData); - data->arg = arg; - data->proc = proc; - // We need a global ref for Java objects, as local refs will be invalid. - data->thread = env->NewGlobalRef(thread); - data->java_vm = art::Runtime::Current()->GetJavaVM(); - data->jvmti_env = jvmti_env; - data->priority = priority; - { - art::ScopedObjectAccess soa(env); + { + art::MutexLock mu(soa.Self(), *art::Locks::runtime_shutdown_lock_); + if (runtime->IsShuttingDownLocked()) { + // The runtime is shutting down so we cannot create new threads. + // TODO It's not fully clear from the spec what we should do here. We aren't yet in + // JVMTI_PHASE_DEAD so we cannot return ERR(WRONG_PHASE) but creating new threads is now + // impossible. Existing agents don't seem to generally do anything with this return value so + // it doesn't matter too much. We could do something like sending a fake ThreadStart event + // even though code is never actually run. + return ERR(INTERNAL); + } + runtime->StartThreadBirth(); + } + + data.reset(new AgentData); + data->arg = arg; + data->proc = proc; + // We need a global ref for Java objects, as local refs will be invalid. + data->thread = runtime->GetJavaVM()->AddGlobalRef(soa.Self(), othread); + data->java_vm = runtime->GetJavaVM(); + data->jvmti_env = jvmti_env; + data->priority = priority; art::ObjPtr<art::mirror::Object> name = art::WellKnownClasses::java_lang_Thread_name->GetObject( soa.Decode<art::mirror::Object>(thread)); @@ -865,8 +872,7 @@ jvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, reinterpret_cast<void*>(data.get())); if (pthread_create_result != 0) { // If the create succeeded the other thread will call EndThreadBirth. - art::Runtime* runtime = art::Runtime::Current(); - art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_); + art::MutexLock mu(self, *art::Locks::runtime_shutdown_lock_); runtime->EndThreadBirth(); return ERR(INTERNAL); } |