diff options
author | 2023-01-10 15:11:19 +0000 | |
---|---|---|
committer | 2023-01-12 10:01:31 +0000 | |
commit | 1725f649ec7f8995cded711baa03e000a9c9dfc2 (patch) | |
tree | 06b7b696792cd6fe2cb85c9f4fb54040e9957a2e | |
parent | 5f4d33f1b825b2de08bbbf402c9f4bfc763b5de2 (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.cc | 9 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 5 | ||||
-rw-r--r-- | runtime/instrumentation.h | 5 |
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(); } |