ART: Make switch back-edge suspension point consistent
Both compiled code and mterp attribute a back-edge suspend point
to the target. Make switch consistent by proactively updating
the frame's dex PC in that case.
Add another macro for reuse.
Bug: 31684812
Test: m test-art-host-run-test-911-get-stack-trace
Test: m ART_TEST_INTERPRETER=true ART_TEST_JIT=true ART_TEST_TRACE=true test-art-host
Change-Id: I9969cc4ffbc34cf1d8849938a1cd7e2c9aec462d
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 52eacd5..b0d7fb2 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -92,6 +92,16 @@
} \
} while (false)
+#define HANDLE_BACKWARD_BRANCH(offset) \
+ do { \
+ if (IsBackwardBranch(offset)) { \
+ HOTNESS_UPDATE(); \
+ /* Record new dex pc early to have consistent suspend point at loop header. */ \
+ shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
+ self->AllowThreadSuspension(); \
+ } \
+ } while (false)
+
template<bool do_access_check, bool transaction_active>
JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
ShadowFrame& shadow_frame, JValue result_register,
@@ -594,55 +604,40 @@
PREAMBLE();
int8_t offset = inst->VRegA_10t(inst_data);
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
break;
}
case Instruction::GOTO_16: {
PREAMBLE();
int16_t offset = inst->VRegA_20t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
break;
}
case Instruction::GOTO_32: {
PREAMBLE();
int32_t offset = inst->VRegA_30t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
break;
}
case Instruction::PACKED_SWITCH: {
PREAMBLE();
int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
break;
}
case Instruction::SPARSE_SWITCH: {
PREAMBLE();
int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
break;
}
@@ -739,11 +734,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -756,11 +748,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -773,11 +762,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -790,11 +776,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -807,11 +790,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -824,11 +804,8 @@
shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
int16_t offset = inst->VRegC_22t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -840,11 +817,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -856,11 +830,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -872,11 +843,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -888,11 +856,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -904,11 +869,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();
@@ -920,11 +882,8 @@
if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
int16_t offset = inst->VRegB_21t();
BRANCH_INSTRUMENTATION(offset);
- if (IsBackwardBranch(offset)) {
- HOTNESS_UPDATE();
- self->AllowThreadSuspension();
- }
inst = inst->RelativeAt(offset);
+ HANDLE_BACKWARD_BRANCH(offset);
} else {
BRANCH_INSTRUMENTATION(2);
inst = inst->Next_2xx();