summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2023-01-10 15:11:19 +0000
committer Mythri Alle <mythria@google.com> 2023-01-12 10:01:31 +0000
commit1725f649ec7f8995cded711baa03e000a9c9dfc2 (patch)
tree06b7b696792cd6fe2cb85c9f4fb54040e9957a2e
parent5f4d33f1b825b2de08bbbf402c9f4bfc763b5de2 (diff)
Limited deopt request from jvmti should enable entry / exit hooks
When an event requires a limited deopt support we should enable entry / exit hooks. We only call this in debuggable runtimes and hence none of the entrypoints need to be updated but we still need to inform that entry / exit hooks have to be called and also record that we need entry / exit hooks corresponding to the deopt manager's instrumentation key. We didn't see a problem earlier, since limited deopt was only used only for setting breakpoints and breakpoints instrument the stack explicitly. This would be a problem when we extend other events like method entry / exit to use limited deopt support. Bug: 206029744 Test: art/test.py Change-Id: Ic0c19cf6da70b3c34fc2e9b67898d9e5e223e2b4
-rw-r--r--openjdkjvmti/deopt_manager.cc9
-rw-r--r--runtime/instrumentation.cc5
-rw-r--r--runtime/instrumentation.h5
3 files changed, 19 insertions, 0 deletions
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index 129aa0ff4a..99acb87257 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -496,6 +496,15 @@ void DeoptManager::AddDeoptimizationRequester() {
art::ScopedThreadStateChange stsc(self, art::ThreadState::kSuspended);
deoptimization_status_lock_.ExclusiveLock(self);
deopter_count_++;
+ if (deopter_count_ == 1) {
+ // When we add a deoptimization requester, we should enable entry / exit hooks. We only call
+ // this in debuggable runtimes and hence it won't be necessary to update entrypoints but we
+ // still need to inform instrumentation that we need to actually run entry / exit hooks. Though
+ // entrypoints are capable of running entry / exit hooks they won't run them unless enabled.
+ ScopedDeoptimizationContext sdc(self, this);
+ art::Runtime::Current()->GetInstrumentation()->EnableEntryExitHooks(kInstrumentationKey);
+ return;
+ }
deoptimization_status_lock_.ExclusiveUnlock(self);
}
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 0863ddf68a..87630c12a7 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -887,6 +887,11 @@ void Instrumentation::UpdateInstrumentationLevel(InstrumentationLevel requested_
instrumentation_level_ = requested_level;
}
+void Instrumentation::EnableEntryExitHooks(const char* key) {
+ DCHECK(Runtime::Current()->IsJavaDebuggable());
+ ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInstrumentationStubs);
+}
+
void Instrumentation::MaybeRestoreInstrumentationStack() {
// Restore stack only if there is no method currently deoptimized.
if (!IsDeoptimizedMethodsEmpty()) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index aecad1f6e6..f7e8aee499 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -243,6 +243,11 @@ class Instrumentation {
void DisableDeoptimization(const char* key)
REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_);
+ // Enables entry exit hooks support. This is called in preparation for debug requests that require
+ // calling method entry / exit hooks.
+ void EnableEntryExitHooks(const char* key)
+ REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_);
+
bool AreAllMethodsDeoptimized() const {
return InterpreterStubsInstalled();
}