Don't install instrumentation stubs for single thread deopts
Single thread deoptimization doesn't need anything special. Don't
install instrumentation stubs. This CL also have a couple of fixes
which were masked by this:
1. When initializing method's code, check if method was already deoptimized and install interpreter stubs for such methods
2. Also check for any debugger frames before restoring the
instrumentation stack.
Test: art/test.py
Bug: 234888286
Bug: 206029744
Change-Id: Ie9a9ca01e8f299391c8b22ecb7694ca90f934d5f
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index a15e667..312a797 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -460,15 +460,7 @@
art::ScopedThreadStateChange stsc(self, art::ThreadState::kSuspended);
deoptimization_status_lock_.ExclusiveLock(self);
deopter_count_++;
- if (deopter_count_ == 1) {
- ScopedDeoptimizationContext sdc(self, this);
- art::instrumentation::Instrumentation* instrumentation =
- art::Runtime::Current()->GetInstrumentation();
- // Tell instrumentation we will be deopting single threads.
- instrumentation->EnableSingleThreadDeopt(kInstrumentationKey);
- } else {
- deoptimization_status_lock_.ExclusiveUnlock(self);
- }
+ deoptimization_status_lock_.ExclusiveUnlock(self);
}
void DeoptManager::DeoptimizeThread(art::Thread* target) {
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index c4dbc8c..2c05a4b 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -367,7 +367,7 @@
return;
}
- if (UNLIKELY(IsForcedInterpretOnly())) {
+ if (UNLIKELY(IsForcedInterpretOnly() || IsDeoptimized(method))) {
UpdateEntryPoints(
method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
return;
@@ -889,11 +889,6 @@
UpdateStubs();
}
-void Instrumentation::EnableSingleThreadDeopt(const char* key) {
- // Prepare for single thread deopt by installing instrumentation stubs.
- ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInstrumentationStubs);
-}
-
void Instrumentation::UpdateInstrumentationLevel(InstrumentationLevel requested_level) {
instrumentation_level_ = requested_level;
}
@@ -915,7 +910,9 @@
Locks::mutator_lock_->AssertExclusiveHeld(self);
Runtime::Current()->GetThreadList()->ForEach([&](Thread* t) NO_THREAD_SAFETY_ANALYSIS {
no_remaining_deopts =
- no_remaining_deopts && !t->IsForceInterpreter() &&
+ no_remaining_deopts &&
+ !t->IsForceInterpreter() &&
+ !t->HasDebuggerShadowFrames() &&
std::all_of(t->GetInstrumentationStack()->cbegin(),
t->GetInstrumentationStack()->cend(),
[&](const auto& frame) REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 48401f2..ee106bf 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -541,13 +541,6 @@
void InstallStubsForMethod(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!GetDeoptimizedMethodsLock());
- // Sets up instrumentation to allow single thread deoptimization using ForceInterpreterCount.
- void EnableSingleThreadDeopt(const char* key)
- REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
- REQUIRES(!Locks::thread_list_lock_,
- !Locks::classlinker_classes_lock_,
- !GetDeoptimizedMethodsLock());
-
// Install instrumentation exit stub on every method of the stack of the given thread.
// This is used by:
// - the debugger to cause a deoptimization of the all frames in thread's stack (for