diff options
author | Sebastien Hertz <shertz@google.com> | 2013-09-09 16:53:14 +0200 |
---|---|---|
committer | Sebastien Hertz <shertz@google.com> | 2013-09-09 18:11:15 +0200 |
commit | 1eda2268e84d384256814cb6c2ba2440a848f9ed (patch) | |
tree | b005fcb72a3ce69784ac43e176464ca1b8f49d8a /runtime/interpreter | |
parent | 7095c6546e03eba2076edcf628b947179c975cb3 (diff) | |
download | art-1eda2268e84d384256814cb6c2ba2440a848f9ed.zip art-1eda2268e84d384256814cb6c2ba2440a848f9ed.tar.gz art-1eda2268e84d384256814cb6c2ba2440a848f9ed.tar.bz2 |
Move thread suspend check at safepoints.
Move CheckSuspend on backward branch, return and exception handling.
Bug: 10603072
Change-Id: Ic6c2c5066f133a345323d46edca7afde350849d8
Diffstat (limited to 'runtime/interpreter')
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 4 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 76 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 151 |
3 files changed, 206 insertions, 25 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 4d9317f..8cd526a 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -510,6 +510,10 @@ static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruc } } +static inline bool IsBackwardBranch(int32_t branch_offset) { + return branch_offset <= 0; +} + } // namespace interpreter } // namespace art diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index f76fbfb..67517ea 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -36,9 +36,6 @@ namespace interpreter { inst = inst->RelativeAt(disp); \ dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \ shadow_frame.SetDexPC(dex_pc); \ - if (UNLIKELY(self->TestAllFlags())) { \ - CheckSuspend(self); \ - } \ TraceExecution(shadow_frame, inst, dex_pc, mh); \ goto *currentHandlersTable[inst->Opcode()]; \ } while (false) @@ -64,10 +61,6 @@ namespace interpreter { #define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels) #define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK() -static inline bool IsBackwardBranch(int32_t branch_offset) { - return branch_offset <= 0; -} - template<bool do_access_check> JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, JValue result_register) { @@ -204,6 +197,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(RETURN_VOID) { JValue result; + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc, @@ -216,6 +212,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(RETURN_VOID_BARRIER) { ANDROID_MEMBAR_STORE(); JValue result; + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc, @@ -229,6 +228,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* JValue result; result.SetJ(0); result.SetI(shadow_frame.GetVReg(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc, @@ -241,6 +243,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(RETURN_WIDE) { JValue result; result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc, @@ -254,6 +259,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* JValue result; result.SetJ(0); result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc, @@ -507,6 +515,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(GOTO) { int8_t offset = inst->VRegA_10t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -520,6 +531,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(GOTO_16) { int16_t offset = inst->VRegA_20t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -533,6 +547,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(GOTO_32) { int32_t offset = inst->VRegA_30t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -546,6 +563,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(PACKED_SWITCH) { int32_t offset = DoPackedSwitch(inst, shadow_frame); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -559,6 +579,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(SPARSE_SWITCH) { int32_t offset = DoSparseSwitch(inst, shadow_frame); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -653,6 +676,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -670,6 +696,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -687,6 +716,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -704,6 +736,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -721,6 +756,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -738,6 +776,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) { int16_t offset = inst->VRegC_22t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -755,6 +796,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -772,6 +816,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -789,6 +836,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -806,6 +856,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -823,6 +876,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -840,6 +896,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) { int16_t offset = inst->VRegB_21t(); if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasDexPcListeners())) { currentHandlersTable = instrumentationHandlersTable; } else { @@ -2307,6 +2366,9 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* exception_pending_label: { CHECK(self->IsExceptionPending()); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc, this_object_ref, instrumentation); diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index ee2aaf6..2f0b5e9 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -22,6 +22,9 @@ namespace interpreter { #define HANDLE_PENDING_EXCEPTION() \ do { \ CHECK(self->IsExceptionPending()); \ + if (UNLIKELY(self->TestAllFlags())) { \ + CheckSuspend(self); \ + } \ uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \ inst->GetDexPc(insns), \ this_object_ref, \ @@ -73,9 +76,6 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C while (true) { dex_pc = inst->GetDexPc(insns); shadow_frame.SetDexPC(dex_pc); - if (UNLIKELY(self->TestAllFlags())) { - CheckSuspend(self); - } if (UNLIKELY(instrumentation->HasDexPcListeners())) { instrumentation->DexPcMovedEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), dex_pc); @@ -166,6 +166,9 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::RETURN_VOID: { PREAMBLE(); JValue result; + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), inst->GetDexPc(insns), @@ -177,6 +180,9 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C PREAMBLE(); ANDROID_MEMBAR_STORE(); JValue result; + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), inst->GetDexPc(insns), @@ -189,6 +195,9 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C JValue result; result.SetJ(0); result.SetI(shadow_frame.GetVReg(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), inst->GetDexPc(insns), @@ -200,6 +209,9 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C PREAMBLE(); JValue result; result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), inst->GetDexPc(insns), @@ -212,6 +224,9 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C JValue result; result.SetJ(0); result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x())); + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, this_object_ref.get(), shadow_frame.GetMethod(), inst->GetDexPc(insns), @@ -461,28 +476,56 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C } case Instruction::GOTO: { PREAMBLE(); - inst = inst->RelativeAt(inst->VRegA_10t()); + int8_t offset = inst->VRegA_10t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); break; } case Instruction::GOTO_16: { PREAMBLE(); - inst = inst->RelativeAt(inst->VRegA_20t()); + int16_t offset = inst->VRegA_20t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); break; } case Instruction::GOTO_32: { PREAMBLE(); - inst = inst->RelativeAt(inst->VRegA_30t()); + int32_t offset = inst->VRegA_30t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); break; } case Instruction::PACKED_SWITCH: { PREAMBLE(); int32_t offset = DoPackedSwitch(inst, shadow_frame); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } inst = inst->RelativeAt(offset); break; } case Instruction::SPARSE_SWITCH: { PREAMBLE(); int32_t offset = DoSparseSwitch(inst, shadow_frame); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } inst = inst->RelativeAt(offset); break; } @@ -570,7 +613,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_EQ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -579,7 +628,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_NE: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -588,7 +643,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_LT: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -597,7 +658,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_GE: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -606,7 +673,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_GT: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -615,7 +688,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_LE: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) { - inst = inst->RelativeAt(inst->VRegC_22t()); + int16_t offset = inst->VRegC_22t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -624,7 +703,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_EQZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -633,7 +718,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_NEZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -642,7 +733,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_LTZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -651,7 +748,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_GEZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -660,7 +763,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_GTZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } @@ -669,7 +778,13 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C case Instruction::IF_LEZ: { PREAMBLE(); if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) { - inst = inst->RelativeAt(inst->VRegB_21t()); + int16_t offset = inst->VRegB_21t(); + if (IsBackwardBranch(offset)) { + if (UNLIKELY(self->TestAllFlags())) { + CheckSuspend(self); + } + } + inst = inst->RelativeAt(offset); } else { inst = inst->Next_2xx(); } |