summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_switch_impl.cc
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2018-03-09 17:23:01 +0000
committer David Srbecky <dsrbecky@google.com> 2018-03-15 14:59:21 +0000
commit946bb09a5adc7d591498b4504aa5d9354457953e (patch)
tree3f1931a9117856c806b8371987700b5646a7d195 /runtime/interpreter/interpreter_switch_impl.cc
parent68f0680e83179cfe0127fda54a8e02a8552bf619 (diff)
Support unwinding though the switch interpreter.
Wrap the switch interpreter in small assembly method which defines DEX PC in CFI and thus it allows libunwind to backtrace through it. Bug: 22414682 Test: testrunner.py --host -t 137 Test: testrunner.py --target -t 137 Change-Id: I31dad9f0fb446151baaa99234b64f25c8ca2fa87
Diffstat (limited to 'runtime/interpreter/interpreter_switch_impl.cc')
-rw-r--r--runtime/interpreter/interpreter_switch_impl.cc54
1 files changed, 29 insertions, 25 deletions
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index e35d80f724..283885e522 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -39,7 +39,8 @@ namespace interpreter {
/* Signal mterp to return to caller */ \
shadow_frame.SetDexPC(dex::kDexNoIndex); \
} \
- return JValue(); /* Handled in caller. */ \
+ ctx->result = JValue(); /* Handled in caller. */ \
+ return; \
} else { \
int32_t displacement = \
static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
@@ -96,7 +97,8 @@ namespace interpreter {
/* OSR has completed execution of the method. Signal mterp to return to caller */ \
shadow_frame.SetDexPC(dex::kDexNoIndex); \
} \
- return result; \
+ ctx->result = result; \
+ return; \
} \
} while (false)
@@ -193,13 +195,17 @@ NO_INLINE static bool SendMethodExitEvents(Thread* self,
}
template<bool do_access_check, bool transaction_active>
-JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction) {
+void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
+ Thread* self = ctx->self;
+ const CodeItemDataAccessor& accessor = ctx->accessor;
+ ShadowFrame& shadow_frame = ctx->shadow_frame;
+ JValue result_register = ctx->result_register;
+ bool interpret_one_instruction = ctx->interpret_one_instruction;
constexpr bool do_assignability_check = do_access_check;
if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
LOG(FATAL) << "Invalid shadow frame for interpreter use";
- return JValue();
+ ctx->result = JValue();
+ return;
}
self->VerifyStack();
@@ -317,7 +323,8 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_VOID: {
PREAMBLE();
@@ -339,7 +346,8 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN: {
PREAMBLE();
@@ -362,7 +370,8 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_WIDE: {
PREAMBLE();
@@ -384,7 +393,8 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::RETURN_OBJECT: {
PREAMBLE();
@@ -428,7 +438,8 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
/* Signal mterp to return to caller */
shadow_frame.SetDexPC(dex::kDexNoIndex);
}
- return result;
+ ctx->result = result;
+ return;
}
case Instruction::CONST_4: {
PREAMBLE();
@@ -2487,26 +2498,19 @@ JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
} while (!interpret_one_instruction);
// Record where we stopped.
shadow_frame.SetDexPC(inst->GetDexPc(insns));
- return result_register;
+ ctx->result = result_register;
+ return;
} // NOLINT(readability/fn_size)
-// Explicit definitions of ExecuteSwitchImpl.
+// Explicit definitions of ExecuteSwitchImplCpp.
template HOT_ATTR
-JValue ExecuteSwitchImpl<true, false>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<true, false>(SwitchImplContext* ctx);
template HOT_ATTR
-JValue ExecuteSwitchImpl<false, false>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<false, false>(SwitchImplContext* ctx);
template
-JValue ExecuteSwitchImpl<true, true>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<true, true>(SwitchImplContext* ctx);
template
-JValue ExecuteSwitchImpl<false, true>(Thread* self, const CodeItemDataAccessor& accessor,
- ShadowFrame& shadow_frame, JValue result_register,
- bool interpret_one_instruction);
+void ExecuteSwitchImplCpp<false, true>(SwitchImplContext* ctx);
} // namespace interpreter
} // namespace art