summaryrefslogtreecommitdiff
path: root/runtime/quick_exception_handler.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2019-12-10 10:17:23 +0000
committerNicolas Geoffray <ngeoffray@google.com>2019-12-18 06:50:39 +0000
commit00391824f4ee89f9fbed178a1ee32bc29fa77b3b (patch)
treeaea6bc5e49801c5b4816257ab16a97181ef0d911 /runtime/quick_exception_handler.cc
parent001e5b33ba7065dde0b85450830b605733ae1685 (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.cc35
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)