[wasm-gc][liftoff] Optimize final-type checks
This is a follow-up to crrev.com/c/v8/v8/+/4096478. Similarly to Turbofan, we reduce type-checks for final types in Liftoff to type identity. Bug: v8:7748 Change-Id: I095880a7718bd2d675dd119f1f14869c97d641b7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4128522 Reviewed-by: Matthias Liedtke <mliedtke@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#85135}
This commit is contained in:
parent
521a399d35
commit
0ab8a7a111
@ -5943,44 +5943,50 @@ class LiftoffCompiler {
|
|||||||
__ LoadMap(tmp1, obj_reg);
|
__ LoadMap(tmp1, obj_reg);
|
||||||
// {tmp1} now holds the object's map.
|
// {tmp1} now holds the object's map.
|
||||||
|
|
||||||
// Check for rtt equality, and if not, check if the rtt is a struct/array
|
if (module->types[rtt_type.ref_index()].is_final) {
|
||||||
// rtt.
|
// In this case, simply check for map equality.
|
||||||
__ emit_cond_jump(kEqual, &match, rtt_type.kind(), tmp1, rtt_reg, frozen);
|
__ emit_cond_jump(kUnequal, no_match, rtt_type.kind(), tmp1, rtt_reg,
|
||||||
|
frozen);
|
||||||
|
} else {
|
||||||
|
// Check for rtt equality, and if not, check if the rtt is a struct/array
|
||||||
|
// rtt.
|
||||||
|
__ emit_cond_jump(kEqual, &match, rtt_type.kind(), tmp1, rtt_reg, frozen);
|
||||||
|
|
||||||
if (is_cast_from_any) {
|
if (is_cast_from_any) {
|
||||||
// Check for map being a map for a wasm object (struct, array, func).
|
// Check for map being a map for a wasm object (struct, array, func).
|
||||||
__ Load(LiftoffRegister(scratch2), tmp1, no_reg,
|
__ Load(LiftoffRegister(scratch2), tmp1, no_reg,
|
||||||
wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset),
|
wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset),
|
||||||
LoadType::kI32Load16U);
|
LoadType::kI32Load16U);
|
||||||
__ emit_i32_subi(scratch2, scratch2, FIRST_WASM_OBJECT_TYPE);
|
__ emit_i32_subi(scratch2, scratch2, FIRST_WASM_OBJECT_TYPE);
|
||||||
__ emit_i32_cond_jumpi(kUnsignedGreaterThan, no_match, scratch2,
|
__ emit_i32_cond_jumpi(kUnsignedGreaterThan, no_match, scratch2,
|
||||||
LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE,
|
LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE,
|
||||||
frozen);
|
frozen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constant-time subtyping check: load exactly one candidate RTT from the
|
// Constant-time subtyping check: load exactly one candidate RTT from the
|
||||||
// supertypes list.
|
// supertypes list.
|
||||||
// Step 1: load the WasmTypeInfo into {tmp1}.
|
// Step 1: load the WasmTypeInfo into {tmp1}.
|
||||||
constexpr int kTypeInfoOffset = wasm::ObjectAccess::ToTagged(
|
constexpr int kTypeInfoOffset = wasm::ObjectAccess::ToTagged(
|
||||||
Map::kConstructorOrBackPointerOrNativeContextOffset);
|
Map::kConstructorOrBackPointerOrNativeContextOffset);
|
||||||
__ LoadTaggedPointer(tmp1, tmp1, no_reg, kTypeInfoOffset);
|
__ LoadTaggedPointer(tmp1, tmp1, no_reg, kTypeInfoOffset);
|
||||||
// Step 2: check the list's length if needed.
|
// Step 2: check the list's length if needed.
|
||||||
uint32_t rtt_depth = GetSubtypingDepth(module, rtt_type.ref_index());
|
uint32_t rtt_depth = GetSubtypingDepth(module, rtt_type.ref_index());
|
||||||
if (rtt_depth >= kMinimumSupertypeArraySize) {
|
if (rtt_depth >= kMinimumSupertypeArraySize) {
|
||||||
LiftoffRegister list_length(scratch2);
|
LiftoffRegister list_length(scratch2);
|
||||||
int offset =
|
int offset =
|
||||||
ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesLengthOffset);
|
ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesLengthOffset);
|
||||||
__ LoadSmiAsInt32(list_length, tmp1, offset);
|
__ LoadSmiAsInt32(list_length, tmp1, offset);
|
||||||
__ emit_i32_cond_jumpi(kUnsignedLessEqual, no_match, list_length.gp(),
|
__ emit_i32_cond_jumpi(kUnsignedLessEqual, no_match, list_length.gp(),
|
||||||
rtt_depth, frozen);
|
rtt_depth, frozen);
|
||||||
|
}
|
||||||
|
// Step 3: load the candidate list slot into {tmp1}, and compare it.
|
||||||
|
__ LoadTaggedPointer(
|
||||||
|
tmp1, tmp1, no_reg,
|
||||||
|
ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesOffset +
|
||||||
|
rtt_depth * kTaggedSize));
|
||||||
|
__ emit_cond_jump(kUnequal, no_match, rtt_type.kind(), tmp1, rtt_reg,
|
||||||
|
frozen);
|
||||||
}
|
}
|
||||||
// Step 3: load the candidate list slot into {tmp1}, and compare it.
|
|
||||||
__ LoadTaggedPointer(
|
|
||||||
tmp1, tmp1, no_reg,
|
|
||||||
ObjectAccess::ToTagged(WasmTypeInfo::kSupertypesOffset +
|
|
||||||
rtt_depth * kTaggedSize));
|
|
||||||
__ emit_cond_jump(kUnequal, no_match, rtt_type.kind(), tmp1, rtt_reg,
|
|
||||||
frozen);
|
|
||||||
|
|
||||||
// Fall through to {match}.
|
// Fall through to {match}.
|
||||||
__ bind(&match);
|
__ bind(&match);
|
||||||
|
Loading…
Reference in New Issue
Block a user