} \
} 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,
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;
}
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();