summaryrefslogtreecommitdiff
path: root/openjdkjvmti/deopt_manager.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2019-03-04 15:08:04 -0800
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-03-08 04:07:45 +0000
commit334630ee9dffdd1932c1ee641d938f25362a4c1a (patch)
tree81957d634aa76967d97c89014eb69158682b0128 /openjdkjvmti/deopt_manager.cc
parent5b76c16cca1984209e838ada4d79e370d7fda431 (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.cc42
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();