Commit 2b5f7205 authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Improve fastpath for getting simple opcode signature

This CL improves the parsing and validation speed of WASM bytecode by
eliminating a call to get the "simple opcode signature" on the fast
path. It introduces a byte-indexed array that points directly to a
FunctionSig*. By declaring the array in the  wasm-opcodes.h header file
and initializing (constexpr) in the wasm-opcodes.cc file, the decoder
can use this array directly in its first test. (Note that constexpr
obviates the need for LazyInitialize in previous iterations of this
mechanism).

There are two more calls on this fast path that can be simplified,
WasmOpcodes::IsSignExtensionOpcode() and WasmOpcodes::IsAnyRefOpcode().
These calls are needed to check for a feature flag and can be
implemented differently in a followup CL.

R=mstarzinger@chromium.org

Change-Id: Ibb4adb1134932c7e0b6a35facec4d8dd8c998c56
Reviewed-on: https://chromium-review.googlesource.com/1075276Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53391}
parent f32878dc
...@@ -1403,7 +1403,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1403,7 +1403,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
#define TRACE_PART(...) #define TRACE_PART(...)
#endif #endif
FunctionSig* sig = WasmOpcodes::Signature(opcode); FunctionSig* sig = const_cast<FunctionSig*>(kSimpleOpcodeSigs[opcode]);
if (sig) { if (sig) {
BuildSimpleOperator(opcode, sig); BuildSimpleOperator(opcode, sig);
} else { } else {
......
...@@ -415,6 +415,14 @@ struct GetOpcodeSigIndex { ...@@ -415,6 +415,14 @@ struct GetOpcodeSigIndex {
} }
}; };
struct GetSimpleOpcodeSig {
constexpr const FunctionSig* operator()(byte opcode) const {
#define CASE(name, opc, sig) opcode == opc ? &kSig_##sig:
return FOREACH_SIMPLE_OPCODE(CASE) nullptr;
#undef CASE
}
};
struct GetAsmJsOpcodeSigIndex { struct GetAsmJsOpcodeSigIndex {
constexpr WasmOpcodeSig operator()(byte opcode) const { constexpr WasmOpcodeSig operator()(byte opcode) const {
#define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig: #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
...@@ -460,6 +468,9 @@ constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable = ...@@ -460,6 +468,9 @@ constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
} // namespace } // namespace
const std::array<const FunctionSig*, 256> kSimpleOpcodeSigs =
base::make_array<256>(GetSimpleOpcodeSig{});
FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) { FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
switch (opcode >> 8) { switch (opcode >> 8) {
case kSimdPrefix: case kSimdPrefix:
......
...@@ -571,6 +571,8 @@ enum TrapReason { ...@@ -571,6 +571,8 @@ enum TrapReason {
#undef DECLARE_ENUM #undef DECLARE_ENUM
}; };
extern const std::array<const FunctionSig*, 256> kSimpleOpcodeSigs;
// A collection of opcode-related static methods. // A collection of opcode-related static methods.
class V8_EXPORT_PRIVATE WasmOpcodes { class V8_EXPORT_PRIVATE WasmOpcodes {
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment