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/runtime_callbacks.h b/runtime/runtime_callbacks.h
index fa686d3..c936049 100644
--- a/runtime/runtime_callbacks.h
+++ b/runtime/runtime_callbacks.h
@@ -94,6 +94,18 @@
   virtual ~MonitorCallback() {}
 };
 
+// A callback to let parts of the runtime note that they are currently relying on a particular
+// method remaining in it's current state. Users should not rely on always being called. If multiple
+// callbacks are added the runtime will short-circuit when the first one returns 'true'.
+class MethodInspectionCallback {
+ public:
+  virtual ~MethodInspectionCallback() {}
+
+  // Returns true if the method is being inspected currently and the runtime should not modify it in
+  // potentially dangerous ways (i.e. replace with compiled version, JIT it, etc).
+  virtual bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
+};
+
 class RuntimeCallbacks {
  public:
   void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
@@ -151,6 +163,15 @@
   void AddMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
   void RemoveMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Returns true if some MethodInspectionCallback indicates the method is being inspected/depended
+  // on by some code.
+  bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
+
+  void AddMethodInspectionCallback(MethodInspectionCallback* cb)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+  void RemoveMethodInspectionCallback(MethodInspectionCallback* cb)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
  private:
   std::vector<ThreadLifecycleCallback*> thread_callbacks_
       GUARDED_BY(Locks::mutator_lock_);
@@ -164,6 +185,8 @@
       GUARDED_BY(Locks::mutator_lock_);
   std::vector<MonitorCallback*> monitor_callbacks_
       GUARDED_BY(Locks::mutator_lock_);
+  std::vector<MethodInspectionCallback*> method_inspection_callbacks_
+      GUARDED_BY(Locks::mutator_lock_);
 };
 
 }  // namespace art