diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2019-12-10 10:17:23 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2019-12-18 06:50:39 +0000 |
commit | 00391824f4ee89f9fbed178a1ee32bc29fa77b3b (patch) | |
tree | aea6bc5e49801c5b4816257ab16a97181ef0d911 /runtime/quick_exception_handler.cc | |
parent | 001e5b33ba7065dde0b85450830b605733ae1685 (diff) |
Add an implementation of Nterp for x64.
And enable it on x64 when runtime and ArtMethod requirements are met
(see nterp.cc).
Test: test.py
Bug: 112676029
Change-Id: I772cd20a20fdc0ff99529df7495801d773091584
Diffstat (limited to 'runtime/quick_exception_handler.cc')
-rw-r--r-- | runtime/quick_exception_handler.cc | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 0e04b7b696..910b389cf3 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -437,7 +437,11 @@ class DeoptimizeStackVisitor final : public StackVisitor { updated_vregs = GetThread()->GetUpdatedVRegFlags(frame_id); DCHECK(updated_vregs != nullptr); } - HandleOptimizingDeoptimization(method, new_frame, updated_vregs); + if (GetCurrentOatQuickMethodHeader()->IsNterpMethodHeader()) { + HandleNterpDeoptimization(method, new_frame, updated_vregs); + } else { + HandleOptimizingDeoptimization(method, new_frame, updated_vregs); + } if (updated_vregs != nullptr) { // Calling Thread::RemoveDebuggerShadowFrameMapping will also delete the updated_vregs // array so this must come after we processed the frame. @@ -467,6 +471,35 @@ class DeoptimizeStackVisitor final : public StackVisitor { } private: + void HandleNterpDeoptimization(ArtMethod* m, + ShadowFrame* new_frame, + const bool* updated_vregs) + REQUIRES_SHARED(Locks::mutator_lock_) { + ArtMethod** cur_quick_frame = GetCurrentQuickFrame(); + StackReference<mirror::Object>* vreg_ref_base = + reinterpret_cast<StackReference<mirror::Object>*>(NterpGetReferenceArray(cur_quick_frame)); + int32_t* vreg_int_base = + reinterpret_cast<int32_t*>(NterpGetRegistersArray(cur_quick_frame)); + CodeItemDataAccessor accessor(m->DexInstructionData()); + const uint16_t num_regs = accessor.RegistersSize(); + // An nterp frame has two arrays: a dex register array and a reference array + // that shadows the dex register array but only containing references + // (non-reference dex registers have nulls). See nterp_helpers.cc. + for (size_t reg = 0; reg < num_regs; ++reg) { + if (updated_vregs != nullptr && updated_vregs[reg]) { + // Keep the value set by debugger. + continue; + } + StackReference<mirror::Object>* ref_addr = vreg_ref_base + reg; + mirror::Object* ref = ref_addr->AsMirrorPtr(); + if (ref != nullptr) { + new_frame->SetVRegReference(reg, ref); + } else { + new_frame->SetVReg(reg, vreg_int_base[reg]); + } + } + } + void HandleOptimizingDeoptimization(ArtMethod* m, ShadowFrame* new_frame, const bool* updated_vregs) |