Fix an issue of partial fragment deoptimization
If the interpreter bridge returns to the instrumentation exit stub,
we need to let the stub makes the decision whether the calling code
is deoptimizeable or not since the stub knows the real return pc.
Bug: 28769520
Change-Id: I262d1222e50a1ccbcb3675d05dcab414dc242a28
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 25b0ef5..03771aa 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -755,7 +755,10 @@
// Request a stack deoptimization if needed
ArtMethod* caller = QuickArgumentVisitor::GetCallingMethod(sp);
uintptr_t caller_pc = QuickArgumentVisitor::GetCallingPc(sp);
- if (UNLIKELY(Dbg::IsForcedInterpreterNeededForUpcall(self, caller) &&
+ // If caller_pc is the instrumentation exit stub, the stub will check to see if deoptimization
+ // should be done and it knows the real return pc.
+ if (UNLIKELY(caller_pc != reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()) &&
+ Dbg::IsForcedInterpreterNeededForUpcall(self, caller) &&
Runtime::Current()->IsDeoptimizeable(caller_pc))) {
// Push the context of the deoptimization stack so we can restore the return value and the
// exception before executing the deoptimized frames.