Ensure that OSR doesn't break local-variable get/set

We had a bug where we would on-stack replace a method with a modified
local variable. Thanks to inlining & load-store elimination of local
variable values this could cause the change to the variable to be lost.
We fixed this by giving plugins a way to notify the runtime they are
interested in a particular method.

Bug: 66959663
Bug: 66933582

Test: while ./test/run-test --host --prebuild -O --jit 1935; do; done
Test: ./test.py --host -j50
Change-Id: Ic001b8a9d8d0bd9ce292e807752c86a505f85d36
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 6daec72..b021ff1 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -324,6 +324,7 @@
 bool Dbg::gDebuggerActive = false;
 bool Dbg::gDisposed = false;
 ObjectRegistry* Dbg::gRegistry = nullptr;
+DebuggerActiveMethodInspectionCallback Dbg::gDebugActiveCallback;
 
 // Deoptimization support.
 std::vector<DeoptimizationRequest> Dbg::deoptimization_requests_;
@@ -341,6 +342,10 @@
 Dbg::DbgThreadLifecycleCallback Dbg::thread_lifecycle_callback_;
 Dbg::DbgClassLoadCallback Dbg::class_load_callback_;
 
+bool DebuggerActiveMethodInspectionCallback::IsMethodBeingInspected(ArtMethod* m ATTRIBUTE_UNUSED) {
+  return Dbg::IsDebuggerActive();
+}
+
 // Breakpoints.
 static std::vector<Breakpoint> gBreakpoints GUARDED_BY(Locks::breakpoint_lock_);
 
@@ -652,6 +657,7 @@
   }
   instrumentation_events_ = 0;
   gDebuggerActive = true;
+  Runtime::Current()->GetRuntimeCallbacks()->AddMethodInspectionCallback(&gDebugActiveCallback);
   LOG(INFO) << "Debugger is active";
 }
 
@@ -689,6 +695,8 @@
         runtime->GetInstrumentation()->DisableDeoptimization(kDbgInstrumentationKey);
       }
       gDebuggerActive = false;
+      Runtime::Current()->GetRuntimeCallbacks()->RemoveMethodInspectionCallback(
+          &gDebugActiveCallback);
     }
   }