Interpreter: Save and restore object result register.

Save and restore object result register when there is a PC listener,
to avoid moving GC issues.

bug: 63088506
bug: 15126502

Test: TBD

(cherry picked from commit ef43805b0e80015645a5fc52e53b93ad178f60e3)

Change-Id: I67c7c23291afba6974a46c382e31ce6a44345b15
(cherry picked from commit 4b4c0f1c002adda5ae02f03d3a3cbad22e23a27e)
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index b191dd7..dcfe25b 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -196,7 +196,20 @@
         inst = inst->Next_1xx();
         break;
       case Instruction::MOVE_RESULT_OBJECT:
-        PREAMBLE();
+        if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+          // Special case the preamble to save and restore the result object. It could move
+          // during DexPcMovedEvent.
+          // Note that ideally we should have the result object be visible to GC as soon as it
+          // is returned, but that involves pretty heave surgery to the interpreter and the runtime
+          // that it may not be worth it. The way it is currently written, there is an implicit
+          // assumption the result register is updated last in the leaf method, and all methods
+          // in-between just return.
+          StackHandleScope<1> hs(self);
+          Handle<mirror::Object> result_object(hs.NewHandle(result_register.GetL()));
+          instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+                                           shadow_frame.GetMethod(), dex_pc);
+          result_register.SetL(result_object.Get());
+        }
         shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
         inst = inst->Next_1xx();
         break;