From 1d8a9741d2979d09a21942fbf9107d212ce2511b Mon Sep 17 00:00:00 2001 From: Alex Light Date: Thu, 17 Aug 2017 11:12:06 -0700 Subject: Fix interaction of VMInit and ThreadStart events. Real world agents require that one is able to create, and run, new threads while the VMInit event is still being executed. Further, these require that ThreadStart events can occur concurrently with the VMInit event. This CL enables this behavior and adds a test for the interaction of these two events. Test: ./test.py --host -j50 Bug: 62821960 Bug: 34415266 Change-Id: I305f1ce3f1df9bf5a7e33027e0724f5fbac5c0f1 --- openjdkjvmti/ti_thread.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'openjdkjvmti/ti_thread.cc') diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc index 6fa73f8a8c..b0a1a8556a 100644 --- a/openjdkjvmti/ti_thread.cc +++ b/openjdkjvmti/ti_thread.cc @@ -57,13 +57,14 @@ namespace openjdkjvmti { art::ArtField* ThreadUtil::context_class_loader_ = nullptr; -struct ThreadCallback : public art::ThreadLifecycleCallback, public art::RuntimePhaseCallback { +struct ThreadCallback : public art::ThreadLifecycleCallback { jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { if (self->GetPeer() == nullptr) { return nullptr; } return self->GetJniEnv()->AddLocalReference(self->GetPeer()); } + template void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { DCHECK_EQ(self, art::Thread::Current()); @@ -96,15 +97,6 @@ struct ThreadCallback : public art::ThreadLifecycleCallback, public art::Runtime Post(self); } - void NextRuntimePhase(RuntimePhase phase) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { - if (phase == RuntimePhase::kInit) { - // We moved to VMInit. Report the main thread as started (it was attached early, and must - // not be reported until Init. - started = true; - Post(art::Thread::Current()); - } - } - EventHandler* event_handler = nullptr; bool started = false; }; @@ -121,10 +113,19 @@ void ThreadUtil::Register(EventHandler* handler) { art::ThreadState::kWaitingForDebuggerToAttach); art::ScopedSuspendAll ssa("Add thread callback"); runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback); - runtime->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gThreadCallback); +} + +void ThreadUtil::VMInitEventSent() { + // We should have already started. + DCHECK(gThreadCallback.started); + // We moved to VMInit. Report the main thread as started (it was attached early, and must not be + // reported until Init. + gThreadCallback.Post(art::Thread::Current()); } void ThreadUtil::CacheData() { + // We must have started since it is now safe to cache our data; + gThreadCallback.started = true; art::ScopedObjectAccess soa(art::Thread::Current()); art::ObjPtr thread_class = soa.Decode(art::WellKnownClasses::java_lang_Thread); @@ -140,7 +141,6 @@ void ThreadUtil::Unregister() { art::ScopedSuspendAll ssa("Remove thread callback"); art::Runtime* runtime = art::Runtime::Current(); runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback); - runtime->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&gThreadCallback); } jvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) { -- cgit v1.2.3-59-g8ed1b