summaryrefslogtreecommitdiff
path: root/openjdkjvmti/ti_phase.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2017-11-17 16:39:01 -0800
committer Alex Light <allight@google.com> 2017-11-20 10:58:30 -0800
commite5a2ae30bdbe379695dc886861b23dce57de0825 (patch)
tree41efa0e726e23607557fe7d8bbc03854cf06ea0f /openjdkjvmti/ti_phase.cc
parent8acd00f9e65078f0f9d3c6fa7fea19ee0c17567a (diff)
Make JVMTI DisposeEnvironment and GetEnv thread safe.
Previously we were relying on the mutator lock to keep these safe but it turns out this was not sufficient. We give the list of active jvmtiEnv's it's own lock to synchronize access. We also changed it so that during events we would collect all the environments and callbacks prior to actually calling any of them. This is required for making sure that we don't hold locks across user code or potentially miss any environments. This does have implications for when one is last able to prevent an environment from getting an event but since the spec is vague about this anyway this is not an issue. Doing this required a major re-write of our event-dispatch system. Test: ./test.py --host -j50 Test: ./art/tools/run-libjdwp-tests.sh --mode=host Bug: 69465262 Change-Id: I170950db6c6e43b5f3c8bdca1b8d087937070496
Diffstat (limited to 'openjdkjvmti/ti_phase.cc')
-rw-r--r--openjdkjvmti/ti_phase.cc11
1 files changed, 4 insertions, 7 deletions
diff --git a/openjdkjvmti/ti_phase.cc b/openjdkjvmti/ti_phase.cc
index 23df27fbda..7157974c13 100644
--- a/openjdkjvmti/ti_phase.cc
+++ b/openjdkjvmti/ti_phase.cc
@@ -57,6 +57,7 @@ struct PhaseUtil::PhaseCallback : public art::RuntimePhaseCallback {
}
void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
+ art::Thread* self = art::Thread::Current();
switch (phase) {
case RuntimePhase::kInitialAgents:
PhaseUtil::current_phase_ = JVMTI_PHASE_PRIMORDIAL;
@@ -64,8 +65,7 @@ struct PhaseUtil::PhaseCallback : public art::RuntimePhaseCallback {
case RuntimePhase::kStart:
{
PhaseUtil::current_phase_ = JVMTI_PHASE_START;
- art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative);
- event_handler->DispatchEvent<ArtJvmtiEvent::kVmStart>(nullptr, GetJniEnv());
+ event_handler->DispatchEvent<ArtJvmtiEvent::kVmStart>(self, GetJniEnv());
}
break;
case RuntimePhase::kInit:
@@ -74,9 +74,7 @@ struct PhaseUtil::PhaseCallback : public art::RuntimePhaseCallback {
PhaseUtil::current_phase_ = JVMTI_PHASE_LIVE;
{
ScopedLocalRef<jthread> thread(GetJniEnv(), GetCurrentJThread());
- art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative);
- event_handler->DispatchEvent<ArtJvmtiEvent::kVmInit>(
- nullptr, GetJniEnv(), thread.get());
+ event_handler->DispatchEvent<ArtJvmtiEvent::kVmInit>(self, GetJniEnv(), thread.get());
}
// We need to have these events be ordered to match behavior expected by some real-world
// agents. The spec does not really require this but compatibility is a useful property to
@@ -86,8 +84,7 @@ struct PhaseUtil::PhaseCallback : public art::RuntimePhaseCallback {
break;
case RuntimePhase::kDeath:
{
- art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative);
- event_handler->DispatchEvent<ArtJvmtiEvent::kVmDeath>(nullptr, GetJniEnv());
+ event_handler->DispatchEvent<ArtJvmtiEvent::kVmDeath>(self, GetJniEnv());
PhaseUtil::current_phase_ = JVMTI_PHASE_DEAD;
}
// TODO: Block events now.