Revert "Don't install instrumentation stubs for single thread deopts"

This reverts commit e32c970b47587e47697a3dab1c329f071d506643.

Reason for revert: Breaks
https://ci.chromium.org/ui/p/art/builders/ci/walleye-armv7-poison-debug/2094/overview
https://ci.chromium.org/ui/p/art/builders/ci/host-x86_64-ndebug/15133/overview

Change-Id: I2371089f753aadf9878990f403830adee9cf1ff1
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index 312a797..a15e667 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -460,7 +460,15 @@
   art::ScopedThreadStateChange stsc(self, art::ThreadState::kSuspended);
   deoptimization_status_lock_.ExclusiveLock(self);
   deopter_count_++;
-  deoptimization_status_lock_.ExclusiveUnlock(self);
+  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);
+  }
 }
 
 void DeoptManager::DeoptimizeThread(art::Thread* target) {
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 2c05a4b..c4dbc8c 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -367,7 +367,7 @@
     return;
   }
 
-  if (UNLIKELY(IsForcedInterpretOnly() || IsDeoptimized(method))) {
+  if (UNLIKELY(IsForcedInterpretOnly())) {
     UpdateEntryPoints(
         method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
     return;
@@ -889,6 +889,11 @@
   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;
 }
@@ -910,9 +915,7 @@
   Locks::mutator_lock_->AssertExclusiveHeld(self);
   Runtime::Current()->GetThreadList()->ForEach([&](Thread* t) NO_THREAD_SAFETY_ANALYSIS {
     no_remaining_deopts =
-        no_remaining_deopts &&
-        !t->IsForceInterpreter() &&
-        !t->HasDebuggerShadowFrames() &&
+        no_remaining_deopts && !t->IsForceInterpreter() &&
         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 ee106bf..48401f2 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -541,6 +541,13 @@
   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