Replace instrumention id with stack pointers.
Replace instrumentation ids for instrumentation frames, which are
inherently broken (see b/72608560), and use stack addresses instead
to properly identify which frames to pop / unwind.
Bug: 72608560
Bug: 148166031
Test: ./art/test/testrunner/testrunner.py --trace --debuggable --ndebuggable --optimizing --interpreter --jit --debug --ndebug -j32
Test: run-libjdwp-tests.sh
Test: 2011-stack-walk-concurrent-instrument
Test: ./art/test/run-test --host --dev --runtime-option -verbose:deopt,plugin --prebuild --compact-dex-level fast --jit --no-relocate --create-runner --runtime-option -Xcheck:jni 1965-get-set-local-primitive-no-tables
art/tools/parallel_run.py -j80 /tmp/path/to/runit.sh --out failure.txt
Change-Id: I71f6e55b9da608796cd3142b147f7b50bbd292ec
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 1049c5d..1304c0d 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -358,12 +358,16 @@
}
}
- // For the given quick ref and args quick frame, return the caller's PC.
- static uintptr_t GetCallingPc(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) {
+ static uint8_t* GetCallingPcAddr(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK((*sp)->IsCalleeSaveMethod());
uint8_t* return_adress_spill =
reinterpret_cast<uint8_t*>(sp) + kQuickCalleeSaveFrame_RefAndArgs_ReturnPcOffset;
- return *reinterpret_cast<uintptr_t*>(return_adress_spill);
+ return return_adress_spill;
+ }
+
+ // For the given quick ref and args quick frame, return the caller's PC.
+ static uintptr_t GetCallingPc(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return *reinterpret_cast<uintptr_t*>(GetCallingPcAddr(sp));
}
QuickArgumentVisitor(ArtMethod** sp, bool is_static, const char* shorty,
@@ -1156,6 +1160,8 @@
instrumentation->PushInstrumentationStackFrame(self,
is_static ? nullptr : this_object,
method,
+ reinterpret_cast<uintptr_t>(
+ QuickArgumentVisitor::GetCallingPcAddr(sp)),
QuickArgumentVisitor::GetCallingPc(sp),
interpreter_entry);
@@ -1181,9 +1187,9 @@
// Compute address of return PC and sanity check that it currently holds 0.
constexpr size_t return_pc_offset =
RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveEverything);
- uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) +
- return_pc_offset);
- CHECK_EQ(*return_pc, 0U);
+ uintptr_t* return_pc_addr = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) +
+ return_pc_offset);
+ CHECK_EQ(*return_pc_addr, 0U);
// Pop the frame filling in the return pc. The low half of the return value is 0 when
// deoptimization shouldn't be performed with the high-half having the return address. When
@@ -1191,7 +1197,7 @@
// deoptimization entry point.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
TwoWordReturn return_or_deoptimize_pc = instrumentation->PopInstrumentationStackFrame(
- self, return_pc, gpr_result, fpr_result);
+ self, return_pc_addr, gpr_result, fpr_result);
if (self->IsExceptionPending() || self->ObserveAsyncException()) {
return GetTwoWordFailureValue();
}