diff options
author | 2019-03-04 15:08:04 -0800 | |
---|---|---|
committer | 2019-03-08 04:07:45 +0000 | |
commit | 334630ee9dffdd1932c1ee641d938f25362a4c1a (patch) | |
tree | 81957d634aa76967d97c89014eb69158682b0128 /openjdkjvmti/deopt_manager.cc | |
parent | 5b76c16cca1984209e838ada4d79e370d7fda431 (diff) |
Remove Global deopt requirement for several jvmti events
The JVMTI_EVENT_SINGLE_STEP, JVMTI_EVENT_FIELD_MODIFICATION,
JVMTI_EVENT_METHOD_EXIT, JVMTI_EVENT_SINGLE_FIELD_ACCESS, and
JVMTI_EVENT_FRAME_POP events would all deoptimize all threads in all
cases when enabled. This changes the behavior to instead only
deoptimize individual threads when possible. This should make some
debugger interactions faster.
Test: ./test.py --host -j72
Test: ./art/tools/run-libjdwp-tests.sh --mode=host
Change-Id: I42513cb17fd1144aeb03ca11afd3e3b05e918ce2
Diffstat (limited to 'openjdkjvmti/deopt_manager.cc')
-rw-r--r-- | openjdkjvmti/deopt_manager.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc index d456d83368..ee77b7bb77 100644 --- a/openjdkjvmti/deopt_manager.cc +++ b/openjdkjvmti/deopt_manager.cc @@ -49,6 +49,7 @@ #include "nativehelper/scoped_local_ref.h" #include "runtime_callbacks.h" #include "scoped_thread_state_change-inl.h" +#include "scoped_thread_state_change.h" #include "thread-current-inl.h" #include "thread_list.h" #include "ti_phase.h" @@ -356,6 +357,47 @@ void DeoptManager::PerformGlobalUndeoptimization(art::Thread* self) { kDeoptManagerInstrumentationKey); } +jvmtiError DeoptManager::AddDeoptimizeThreadMethods(art::ScopedObjectAccessUnchecked& soa, jthread jtarget) { + art::Locks::thread_list_lock_->ExclusiveLock(soa.Self()); + art::Thread* target = nullptr; + jvmtiError err = OK; + if (!ThreadUtil::GetNativeThread(jtarget, soa, &target, &err)) { + art::Locks::thread_list_lock_->ExclusiveUnlock(soa.Self()); + return err; + } + // We don't need additional locking here because we hold the Thread_list_lock_. + target->SetForceInterpreterCount(target->ForceInterpreterCount() + 1); + if (target->ForceInterpreterCount() == 1) { + struct DeoptClosure : public art::Closure { + public: + explicit DeoptClosure(DeoptManager* man) : man_(man) {} + void Run(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) { + man_->DeoptimizeThread(self); + } + + private: + DeoptManager* man_; + }; + DeoptClosure c(this); + target->RequestSynchronousCheckpoint(&c); + } else { + art::Locks::thread_list_lock_->ExclusiveUnlock(soa.Self()); + } + return OK; +} + +jvmtiError DeoptManager::RemoveDeoptimizeThreadMethods(art::ScopedObjectAccessUnchecked& soa, jthread jtarget) { + art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); + art::Thread* target = nullptr; + jvmtiError err = OK; + if (!ThreadUtil::GetNativeThread(jtarget, soa, &target, &err)) { + return err; + } + // We don't need additional locking here because we hold the Thread_list_lock_. + DCHECK_GT(target->ForceInterpreterCount(), 0u); + target->DecrementForceInterpreterCount(); + return OK; +} void DeoptManager::RemoveDeoptimizationRequester() { art::Thread* self = art::Thread::Current(); |