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