Commit 8fbefa47 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[wasm-gc] Experiment: ref.cast_nop_static

This adds a non-standard, unsafe instruction for performance
experiments: ref.cast_nop_static behaves like ref.cast_static
as far as static types are concerned, but emits no code.

Bug: v8:7748
Change-Id: Ic5797a941146a06d7c6ff249d8e29919145d8ea1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3639206Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80471}
parent a62c0404
...@@ -1881,6 +1881,7 @@ class WasmDecoder : public Decoder { ...@@ -1881,6 +1881,7 @@ class WasmDecoder : public Decoder {
case kExprRttCanon: case kExprRttCanon:
case kExprRefTestStatic: case kExprRefTestStatic:
case kExprRefCastStatic: case kExprRefCastStatic:
case kExprRefCastNopStatic:
case kExprBrOnCastStatic: case kExprBrOnCastStatic:
case kExprBrOnCastStaticFail: { case kExprBrOnCastStaticFail: {
IndexImmediate<validate> imm(decoder, pc + length, "type index"); IndexImmediate<validate> imm(decoder, pc + length, "type index");
...@@ -2053,6 +2054,7 @@ class WasmDecoder : public Decoder { ...@@ -2053,6 +2054,7 @@ class WasmDecoder : public Decoder {
case kExprArrayLen: case kExprArrayLen:
case kExprRefTestStatic: case kExprRefTestStatic:
case kExprRefCastStatic: case kExprRefCastStatic:
case kExprRefCastNopStatic:
case kExprBrOnCastStatic: case kExprBrOnCastStatic:
case kExprBrOnCastStaticFail: case kExprBrOnCastStaticFail:
return {1, 1}; return {1, 1};
...@@ -4500,6 +4502,35 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -4500,6 +4502,35 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(value); Push(value);
return opcode_length; return opcode_length;
} }
case kExprRefCastNopStatic: {
// Temporary non-standard instruction, for performance experiments.
if (!VALIDATE(this->enabled_.has_ref_cast_nop())) {
this->DecodeError(
"Invalid opcode 0xfb48 (enable with "
"--experimental-wasm-ref-cast-nop)");
return 0;
}
IndexImmediate<validate> imm(this, this->pc_ + opcode_length,
"type index");
if (!this->ValidateType(this->pc_ + opcode_length, imm)) return 0;
opcode_length += imm.length;
Value obj = Peek(0);
if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) ||
IsSubtypeOf(obj.type,
ValueType::Ref(HeapType::kData, kNullable),
this->module_) ||
obj.type.is_bottom())) {
PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)");
return 0;
}
Value value = CreateValue(ValueType::Ref(
imm.index,
obj.type.is_bottom() ? kNonNullable : obj.type.nullability()));
CALL_INTERFACE_IF_OK_AND_REACHABLE(Forward, obj, &value);
Drop(obj);
Push(value);
return opcode_length;
}
case kExprRefCast: case kExprRefCast:
case kExprRefCastStatic: { case kExprRefCastStatic: {
NON_CONST_ONLY NON_CONST_ONLY
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
"assume ref.cast always succeeds and skip the related type check " \ "assume ref.cast always succeeds and skip the related type check " \
"(unsafe)", \ "(unsafe)", \
false) \ false) \
V(ref_cast_nop, "enable unsafe ref.cast_nop instruction", false) \
V(skip_null_checks, \ V(skip_null_checks, \
"skip null checks for call.ref and array and struct operations (unsafe)", \ "skip null checks for call.ref and array and struct operations (unsafe)", \
false) \ false) \
......
...@@ -422,6 +422,7 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { ...@@ -422,6 +422,7 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_OP(RefTestStatic, "ref.test_static") CASE_OP(RefTestStatic, "ref.test_static")
CASE_OP(RefCast, "ref.cast") CASE_OP(RefCast, "ref.cast")
CASE_OP(RefCastStatic, "ref.cast_static") CASE_OP(RefCastStatic, "ref.cast_static")
CASE_OP(RefCastNopStatic, "ref.cast_nop_static")
CASE_OP(BrOnCast, "br_on_cast") CASE_OP(BrOnCast, "br_on_cast")
CASE_OP(BrOnCastStatic, "br_on_cast_static") CASE_OP(BrOnCastStatic, "br_on_cast_static")
CASE_OP(BrOnCastFail, "br_on_cast_fail") CASE_OP(BrOnCastFail, "br_on_cast_fail")
......
...@@ -707,6 +707,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig, ...@@ -707,6 +707,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
V(RefCastStatic, 0xfb45, _) \ V(RefCastStatic, 0xfb45, _) \
V(BrOnCastStatic, 0xfb46, _) \ V(BrOnCastStatic, 0xfb46, _) \
V(BrOnCastStaticFail, 0xfb47, _) \ V(BrOnCastStaticFail, 0xfb47, _) \
V(RefCastNopStatic, 0xfb48, _) \
V(RefIsFunc, 0xfb50, _) \ V(RefIsFunc, 0xfb50, _) \
V(RefIsData, 0xfb51, _) \ V(RefIsData, 0xfb51, _) \
V(RefIsI31, 0xfb52, _) \ V(RefIsI31, 0xfb52, _) \
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-gc --experimental-wasm-ref-cast-nop
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
(function TestRefCastNop() {
var builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)]);
builder.addFunction("main", kSig_i_i)
.addLocals(wasmOptRefType(kWasmDataRef), 1)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStructNew, struct,
kExprLocalSet, 1,
kExprLocalGet, 1,
kGCPrefix, kExprRefCastNopStatic, struct,
kGCPrefix, kExprStructGet, struct, 0,
]).exportFunc();
var instance = builder.instantiate();
assertEquals(42, instance.exports.main(42));
})();
...@@ -505,6 +505,7 @@ let kExprRefTestStatic = 0x44; ...@@ -505,6 +505,7 @@ let kExprRefTestStatic = 0x44;
let kExprRefCastStatic = 0x45; let kExprRefCastStatic = 0x45;
let kExprBrOnCastStatic = 0x46; let kExprBrOnCastStatic = 0x46;
let kExprBrOnCastStaticFail = 0x47; let kExprBrOnCastStaticFail = 0x47;
let kExprRefCastNopStatic = 0x48;
let kExprRefIsFunc = 0x50; let kExprRefIsFunc = 0x50;
let kExprRefIsData = 0x51; let kExprRefIsData = 0x51;
let kExprRefIsI31 = 0x52; let kExprRefIsI31 = 0x52;
......
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