From: Andreas Gampe Date: Tue, 13 Dec 2016 22:43:58 +0000 (-0800) Subject: ART: Make switch back-edge suspension point consistent X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f4f7637ef078cbd0812432f5a4051858c80f6309;p=android-x86%2Fart.git 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 52eacd564..b0d7fb247 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -92,6 +92,16 @@ namespace interpreter { } \ } 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 JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, JValue result_register, @@ -594,55 +604,40 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, 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();