// 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;
JValue result;
};
// The actual internal implementation of the switch interpreter. template<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, constvoid* impl, const uint16_t* dexpc)
REQUIRES_SHARED(Locks::mutator_lock_);
// Wrapper around the switch interpreter which ensures we can unwind through it.
ALWAYS_INLINE inline JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
ShadowFrame& shadow_frame,
JValue result_register, constvoid* switch_impl_cpp)
REQUIRES_SHARED(Locks::mutator_lock_) {
SwitchImplContext ctx {
.self = self,
.accessor = accessor,
.shadow_frame = shadow_frame,
.result_register = result_register,
.result = JValue(),
}; const uint16_t* dex_pc = ctx.accessor.Insns();
ExecuteSwitchImplAsm(&ctx, switch_impl_cpp, dex_pc); return ctx.result;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.