diff options
Diffstat (limited to 'runtime/interpreter/interpreter_switch_impl.h')
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.h | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/runtime/interpreter/interpreter_switch_impl.h b/runtime/interpreter/interpreter_switch_impl.h index 50db337f03..9fc4239d05 100644 --- a/runtime/interpreter/interpreter_switch_impl.h +++ b/runtime/interpreter/interpreter_switch_impl.h @@ -20,23 +20,59 @@ #include "base/macros.h" #include "base/mutex.h" #include "dex/dex_file.h" +#include "dex/code_item_accessors.h" #include "jvalue.h" #include "obj_ptr.h" namespace art { -class CodeItemDataAccessor; class ShadowFrame; class Thread; namespace interpreter { +// Group all the data that is needed in the switch interpreter. +// We need to pass it to the hand-written assembly and back, +// so it is easier to pass it through a single pointer. +// Similarly, returning the JValue type would be non-trivial. +struct SwitchImplContext { + Thread* self; + const CodeItemDataAccessor& accessor; + ShadowFrame& shadow_frame; + JValue& result_register; + bool interpret_one_instruction; + JValue result; +}; + +// The actual internal implementation of the switch interpreter. +template<bool do_access_check, bool transaction_active> +void ExecuteSwitchImplCpp(SwitchImplContext* ctx) + REQUIRES_SHARED(Locks::mutator_lock_); + +// Hand-written assembly method which wraps the C++ implementation, +// while defining the DEX PC in the CFI so that libunwind can resolve it. +extern "C" void ExecuteSwitchImplAsm(SwitchImplContext* ctx, void* impl, const uint16_t* dexpc) + REQUIRES_SHARED(Locks::mutator_lock_); + +// Wrapper around the switch interpreter which ensures we can unwind through it. 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) REQUIRES_SHARED(Locks::mutator_lock_); +ALWAYS_INLINE JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor, + ShadowFrame& shadow_frame, JValue result_register, + bool interpret_one_instruction) + REQUIRES_SHARED(Locks::mutator_lock_) { + SwitchImplContext ctx { + .self = self, + .accessor = accessor, + .shadow_frame = shadow_frame, + .result_register = result_register, + .interpret_one_instruction = interpret_one_instruction, + .result = JValue(), + }; + void* impl = reinterpret_cast<void*>(&ExecuteSwitchImplCpp<do_access_check, transaction_active>); + const uint16_t* dex_pc = ctx.accessor.Insns(); + ExecuteSwitchImplAsm(&ctx, impl, dex_pc); + return ctx.result; +} } // namespace interpreter } // namespace art |