Commit 63b78f2b authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Optimize bounds checking bounds

For bounds checking, we have a special path which avoids one conditional
branch. This path can actually be one value wider, which will avoid some
unneeded code if that case it hit. This will in particular be the case
for single-byte loads at offset 0 with a minimum memory size of 0.

R=jkummerow@chromium.org

Bug: v8:10949
Change-Id: Id16af8debc38c56c520183aec81a48249979ec96
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2595290Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71822}
parent 8f02ad40
...@@ -3804,13 +3804,13 @@ Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index, ...@@ -3804,13 +3804,13 @@ Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index,
// - checking that {index < effective_size}. // - checking that {index < effective_size}.
Node* mem_size = instance_cache_->mem_size; Node* mem_size = instance_cache_->mem_size;
if (end_offset >= env_->min_memory_size) { if (end_offset > env_->min_memory_size) {
// The end offset is larger than the smallest memory. // The end offset is larger than the smallest memory.
// Dynamically check the end offset against the dynamic memory size. // Dynamically check the end offset against the dynamic memory size.
Node* cond = gasm_->UintLessThan(end_offset_node, mem_size); Node* cond = gasm_->UintLessThan(end_offset_node, mem_size);
TrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); TrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position);
} else { } else {
// The end offset is smaller than the smallest memory, so only one check is // The end offset is <= the smallest memory, so only one check is
// required. Check to see if the index is also a constant. // required. Check to see if the index is also a constant.
UintPtrMatcher match(index); UintPtrMatcher match(index);
if (match.HasResolvedValue()) { if (match.HasResolvedValue()) {
...@@ -3823,7 +3823,7 @@ Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index, ...@@ -3823,7 +3823,7 @@ Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index,
} }
} }
// This produces a positive number, since {end_offset < min_size <= mem_size}. // This produces a positive number since {end_offset <= min_size <= mem_size}.
Node* effective_size = gasm_->IntSub(mem_size, end_offset_node); Node* effective_size = gasm_->IntSub(mem_size, end_offset_node);
// Introduce the actual bounds check. // Introduce the actual bounds check.
......
...@@ -2257,13 +2257,14 @@ class LiftoffCompiler { ...@@ -2257,13 +2257,14 @@ class LiftoffCompiler {
__ LoadConstant(end_offset_reg, WasmValue::ForUintPtr(end_offset)); __ LoadConstant(end_offset_reg, WasmValue::ForUintPtr(end_offset));
if (end_offset >= env_->min_memory_size) { if (end_offset > env_->min_memory_size) {
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label, __ emit_cond_jump(kUnsignedGreaterEqual, trap_label,
LiftoffAssembler::kWasmIntPtr, end_offset_reg.gp(), LiftoffAssembler::kWasmIntPtr, end_offset_reg.gp(),
mem_size); mem_size);
} }
// Just reuse the end_offset register for computing the effective size. // Just reuse the end_offset register for computing the effective size
// (which is >= 0 because of the check above).
LiftoffRegister effective_size_reg = end_offset_reg; LiftoffRegister effective_size_reg = end_offset_reg;
__ emit_ptrsize_sub(effective_size_reg.gp(), mem_size, end_offset_reg.gp()); __ emit_ptrsize_sub(effective_size_reg.gp(), mem_size, end_offset_reg.gp());
......
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