[wasm-gc] Skip null-check for casts of any to non-nullable type
We can skip explicit null check for casts from any to a non-nullable type as they have to perform an instance type check afterwards as part of the cast and trap if they encounter a non-wasm object (null is not a wasm object). The same is true for type checks which fail on null. Bug: v8:7748 Change-Id: I41ec225618a400feec5dab210fbf7c1bc2718c8f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3981859 Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Commit-Queue: Matthias Liedtke <mliedtke@chromium.org> Cr-Commit-Position: refs/heads/main@{#83950}
This commit is contained in:
parent
53e69521f4
commit
f1d16aebe4
@ -95,8 +95,12 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) {
|
||||
gasm_.InitializeEffectControl(effect_input, control_input);
|
||||
|
||||
auto end_label = gasm_.MakeLabel(MachineRepresentation::kWord32);
|
||||
bool is_cast_from_any = config.from.is_reference_to(wasm::HeapType::kAny);
|
||||
|
||||
if (object_can_be_null) {
|
||||
// Skip the null check if casting from any and if null results in check
|
||||
// failure. In that case the instance type check will identify null as not
|
||||
// being a wasm object and return 0 (failure).
|
||||
if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
|
||||
const int kResult = config.to.is_nullable() ? 1 : 0;
|
||||
gasm_.GotoIf(gasm_.TaggedEqual(object, Null()), &end_label,
|
||||
BranchHint::kFalse, gasm_.Int32Constant(kResult));
|
||||
@ -114,7 +118,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) {
|
||||
gasm_.Int32Constant(1));
|
||||
|
||||
// Check if map instance type identifies a wasm object.
|
||||
if (config.from.is_reference_to(wasm::HeapType::kAny)) {
|
||||
if (is_cast_from_any) {
|
||||
Node* is_wasm_obj = gasm_.IsDataRefMap(map);
|
||||
gasm_.GotoIfNot(is_wasm_obj, &end_label, BranchHint::kTrue,
|
||||
gasm_.Int32Constant(0));
|
||||
@ -166,8 +170,12 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) {
|
||||
gasm_.InitializeEffectControl(effect_input, control_input);
|
||||
|
||||
auto end_label = gasm_.MakeLabel();
|
||||
bool is_cast_from_any = config.from.is_reference_to(wasm::HeapType::kAny);
|
||||
|
||||
if (object_can_be_null) {
|
||||
// Skip the null check if casting from any and if null results in check
|
||||
// failure. In that case the instance type check will identify null as not
|
||||
// being a wasm object and trap.
|
||||
if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
|
||||
Node* is_null = gasm_.TaggedEqual(object, Null());
|
||||
if (config.to.is_nullable()) {
|
||||
gasm_.GotoIf(is_null, &end_label, BranchHint::kFalse);
|
||||
@ -187,7 +195,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) {
|
||||
gasm_.GotoIf(gasm_.TaggedEqual(map, rtt), &end_label, BranchHint::kTrue);
|
||||
|
||||
// Check if map instance type identifies a wasm object.
|
||||
if (config.from.is_reference_to(wasm::HeapType::kAny)) {
|
||||
if (is_cast_from_any) {
|
||||
Node* is_wasm_obj = gasm_.IsDataRefMap(map);
|
||||
gasm_.TrapUnless(is_wasm_obj, TrapId::kTrapIllegalCast);
|
||||
}
|
||||
|
@ -5848,8 +5848,12 @@ class LiftoffCompiler {
|
||||
NullSucceeds null_succeeds,
|
||||
const FreezeCacheState& frozen) {
|
||||
Label match;
|
||||
bool is_cast_from_any = obj_type.is_reference_to(HeapType::kAny);
|
||||
|
||||
if (obj_type.is_nullable()) {
|
||||
// Skip the null check if casting from any and not {null_succeeds}.
|
||||
// In that case the instance type check will identify null as not being a
|
||||
// wasm object and fail.
|
||||
if (obj_type.is_nullable() && (!is_cast_from_any || null_succeeds)) {
|
||||
__ emit_cond_jump(kEqual, null_succeeds ? &match : no_match,
|
||||
obj_type.kind(), obj_reg, scratch_null, frozen);
|
||||
}
|
||||
@ -5876,7 +5880,7 @@ class LiftoffCompiler {
|
||||
// rtt.
|
||||
__ emit_cond_jump(kEqual, &match, rtt_type.kind(), tmp1, rtt_reg, frozen);
|
||||
|
||||
if (obj_type.is_reference_to(HeapType::kAny)) {
|
||||
if (is_cast_from_any) {
|
||||
// Check for map being a map for a wasm object (struct, array, func).
|
||||
__ Load(LiftoffRegister(scratch2), tmp1, no_reg,
|
||||
wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset),
|
||||
|
Loading…
Reference in New Issue
Block a user