[wasm] Add a fast path for MemoryAccessImmediate
The memory access immediate consists of two LEB-encoded integers. Both are mostly single-byte values. Hence add a fast path that checks for that, and avoids the general LEB-decoding logic otherwise. This saves a few dynamic branches, in particular it is independent of the {memory64} flag. R=dlehmann@chromium.org Bug: v8:13565, v8:13673 Change-Id: Iee981dd451f8acb001aa36f1dd3c8103839d01aa Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4198137 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Daniel Lehmann <dlehmann@chromium.org> Cr-Commit-Position: refs/heads/main@{#85538}
This commit is contained in:
parent
ed8cd96a9d
commit
171587e66b
@ -705,12 +705,19 @@ struct MemoryAccessImmediate {
|
|||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
|
|
||||||
template <typename ValidationTag>
|
template <typename ValidationTag>
|
||||||
MemoryAccessImmediate(Decoder* decoder, const byte* pc,
|
V8_INLINE MemoryAccessImmediate(Decoder* decoder, const byte* pc,
|
||||||
uint32_t max_alignment, bool is_memory64,
|
uint32_t max_alignment, bool is_memory64,
|
||||||
ValidationTag = {}) {
|
ValidationTag = {}) {
|
||||||
uint32_t alignment_length;
|
// Check for the fast path (two single-byte LEBs).
|
||||||
alignment =
|
const bool two_bytes = !ValidationTag::validate || decoder->end() - pc >= 2;
|
||||||
decoder->read_u32v<ValidationTag>(pc, &alignment_length, "alignment");
|
const bool use_fast_path = two_bytes && !((pc[0] | pc[1]) & 0x80);
|
||||||
|
if (V8_LIKELY(use_fast_path)) {
|
||||||
|
alignment = pc[0];
|
||||||
|
offset = pc[1];
|
||||||
|
length = 2;
|
||||||
|
} else {
|
||||||
|
ConstructSlow<ValidationTag>(decoder, pc, max_alignment, is_memory64);
|
||||||
|
}
|
||||||
if (!VALIDATE(alignment <= max_alignment)) {
|
if (!VALIDATE(alignment <= max_alignment)) {
|
||||||
DecodeError<ValidationTag>(
|
DecodeError<ValidationTag>(
|
||||||
decoder, pc,
|
decoder, pc,
|
||||||
@ -718,6 +725,17 @@ struct MemoryAccessImmediate {
|
|||||||
"actual alignment is %u",
|
"actual alignment is %u",
|
||||||
max_alignment, alignment);
|
max_alignment, alignment);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename ValidationTag>
|
||||||
|
V8_NOINLINE V8_PRESERVE_MOST void ConstructSlow(Decoder* decoder,
|
||||||
|
const byte* pc,
|
||||||
|
uint32_t max_alignment,
|
||||||
|
bool is_memory64) {
|
||||||
|
uint32_t alignment_length;
|
||||||
|
alignment =
|
||||||
|
decoder->read_u32v<ValidationTag>(pc, &alignment_length, "alignment");
|
||||||
uint32_t offset_length;
|
uint32_t offset_length;
|
||||||
offset = is_memory64 ? decoder->read_u64v<ValidationTag>(
|
offset = is_memory64 ? decoder->read_u64v<ValidationTag>(
|
||||||
pc + alignment_length, &offset_length, "offset")
|
pc + alignment_length, &offset_length, "offset")
|
||||||
@ -2933,8 +2951,8 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryAccessImmediate MakeMemoryAccessImmediate(uint32_t pc_offset,
|
V8_INLINE MemoryAccessImmediate
|
||||||
uint32_t max_alignment) {
|
MakeMemoryAccessImmediate(uint32_t pc_offset, uint32_t max_alignment) {
|
||||||
return MemoryAccessImmediate(this, this->pc_ + pc_offset, max_alignment,
|
return MemoryAccessImmediate(this, this->pc_ + pc_offset, max_alignment,
|
||||||
this->module_->is_memory64, validate);
|
this->module_->is_memory64, validate);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user