diff options
| author | 2017-06-28 14:41:07 +0100 | |
|---|---|---|
| committer | 2017-06-29 20:17:20 +0100 | |
| commit | 4b4c0f1c002adda5ae02f03d3a3cbad22e23a27e (patch) | |
| tree | 7be19439cd73b403975357ca8294c7d9630d434d /runtime/interpreter/interpreter_switch_impl.cc | |
| parent | 1fb4a7b5d1c2a315b8cffcc56c9b66c77b71b24b (diff) | |
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
Diffstat (limited to 'runtime/interpreter/interpreter_switch_impl.cc')
| -rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index b191dd79a1..dcfe25b80d 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -196,7 +196,20 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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; |