LibWasm: Move the interpreter IP out of the configuration object

This, along with moving the sources and destination out of the config
object, makes it so we don't have to double-deref to get to them on each
instruction, leading to a ~15% perf improvement on dispatch.
This commit is contained in:
Ali Mohammad Pur 2025-08-22 17:11:25 +02:00 committed by Ali Mohammad Pur
commit 22448b0c35
Notes: github-actions[bot] 2025-08-26 13:21:41 +00:00
11 changed files with 2182 additions and 2172 deletions

View file

@ -13,6 +13,14 @@
namespace Wasm {
union SourcesAndDestination {
struct {
Dispatch::RegisterOrStack sources[3];
Dispatch::RegisterOrStack destination;
};
u32 sources_and_destination;
};
struct WASM_API BytecodeInterpreter final : public Interpreter {
explicit BytecodeInterpreter(StackInfo const& stack_info)
: m_stack_info(stack_info)
@ -57,37 +65,37 @@ struct WASM_API BytecodeInterpreter final : public Interpreter {
void interpret_impl(Configuration&, Expression const&);
protected:
void branch_to_label(Configuration&, LabelIndex);
InstructionPointer branch_to_label(Configuration&, LabelIndex);
template<typename ReadT, typename PushT>
bool load_and_push(Configuration&, Instruction const&);
bool load_and_push(Configuration&, Instruction const&, SourcesAndDestination const&);
template<typename PopT, typename StoreT>
bool pop_and_store(Configuration&, Instruction const&);
bool pop_and_store(Configuration&, Instruction const&, SourcesAndDestination const&);
template<typename StoreT>
bool store_value(Configuration&, Instruction const&, StoreT, size_t address_source);
bool store_value(Configuration&, Instruction const&, StoreT, size_t address_source, SourcesAndDestination const&);
template<size_t N>
bool pop_and_store_lane_n(Configuration&, Instruction const&);
bool pop_and_store_lane_n(Configuration&, Instruction const&, SourcesAndDestination const&);
template<size_t M, size_t N, template<typename> typename SetSign>
bool load_and_push_mxn(Configuration&, Instruction const&);
bool load_and_push_mxn(Configuration&, Instruction const&, SourcesAndDestination const&);
template<size_t N>
bool load_and_push_lane_n(Configuration&, Instruction const&);
bool load_and_push_lane_n(Configuration&, Instruction const&, SourcesAndDestination const&);
template<size_t N>
bool load_and_push_zero_n(Configuration&, Instruction const&);
bool load_and_push_zero_n(Configuration&, Instruction const&, SourcesAndDestination const&);
template<size_t M>
bool load_and_push_m_splat(Configuration&, Instruction const&);
bool load_and_push_m_splat(Configuration&, Instruction const&, SourcesAndDestination const&);
template<size_t M, template<size_t> typename NativeType>
void set_top_m_splat(Configuration&, NativeType<M>);
void set_top_m_splat(Configuration&, NativeType<M>, SourcesAndDestination const&);
template<size_t M, template<size_t> typename NativeType>
void pop_and_push_m_splat(Configuration&, Instruction const&);
void pop_and_push_m_splat(Configuration&, Instruction const&, SourcesAndDestination const&);
template<typename M, template<typename> typename SetSign, typename VectorType = Native128ByteVectorOf<M, SetSign>>
VectorType pop_vector(Configuration&, size_t source);
VectorType pop_vector(Configuration&, size_t source, SourcesAndDestination const&);
bool store_to_memory(Configuration&, Instruction::MemoryArgument const&, ReadonlyBytes data, u32 base);
bool call_address(Configuration&, FunctionAddress, CallAddressSource = CallAddressSource::DirectCall);
template<typename PopTypeLHS, typename PushType, typename Operator, typename PopTypeRHS = PopTypeLHS, typename... Args>
bool binary_numeric_operation(Configuration&, Args&&...);
bool binary_numeric_operation(Configuration&, SourcesAndDestination const&, Args&&...);
template<typename PopType, typename PushType, typename Operator, typename... Args>
bool unary_operation(Configuration&, Args&&...);
bool unary_operation(Configuration&, SourcesAndDestination const&, Args&&...);
template<typename T>
T read_value(ReadonlyBytes data);