summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2022-05-11 11:23:55 -0700
committerGitHub <noreply@github.com>2022-05-11 11:23:55 -0700
commit57bef0d2f9a38a2add940e07fc422fd532574013 (patch)
tree0e93c4aaa08985d631ea87bfbee452825d93c405 /src
parentbad3f9e8f058cfdaefb3d7d76a93e842665f8435 (diff)
downloadbinaryen-57bef0d2f9a38a2add940e07fc422fd532574013.tar.gz
binaryen-57bef0d2f9a38a2add940e07fc422fd532574013.tar.bz2
binaryen-57bef0d2f9a38a2add940e07fc422fd532574013.zip
Add ref.cast_nop_static (#4656)
This unsafe experimental instruction is semantically equivalent to ref.cast_static, but V8 will unsafely turn it into a nop. This is meant to help us measure cast overhead more precisely than we can by globally turning all casts into nops.
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc14
-rw-r--r--src/passes/Print.cpp6
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-builder.h5
-rw-r--r--src/wasm-s-parser.h1
-rw-r--r--src/wasm.h5
-rw-r--r--src/wasm/wasm-binary.cpp7
-rw-r--r--src/wasm/wasm-s-parser.cpp8
-rw-r--r--src/wasm/wasm-stack.cpp6
9 files changed, 44 insertions, 9 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index d9505bcdd..411196986 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -3027,9 +3027,17 @@ switch (op[0]) {
case '\0':
if (strcmp(op, "ref.cast") == 0) { return makeRefCast(s); }
goto parse_error;
- case '_':
- if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); }
- goto parse_error;
+ case '_': {
+ switch (op[9]) {
+ case 'n':
+ if (strcmp(op, "ref.cast_nop_static") == 0) { return makeRefCastNopStatic(s); }
+ goto parse_error;
+ case 's':
+ if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 9a4235cbf..ce70f50fd 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1984,7 +1984,11 @@ struct PrintExpressionContents
if (curr->rtt) {
printMedium(o, "ref.cast");
} else {
- printMedium(o, "ref.cast_static ");
+ if (curr->safety == RefCast::Unsafe) {
+ printMedium(o, "ref.cast_nop_static ");
+ } else {
+ printMedium(o, "ref.cast_static ");
+ }
printHeapType(o, curr->intendedType, wasm);
}
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 12deeacab..58dcd2224 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1112,6 +1112,7 @@ enum ASTNodes {
RefCastStatic = 0x45,
BrOnCastStatic = 0x46,
BrOnCastStaticFail = 0x47,
+ RefCastNopStatic = 0x48,
RefIsFunc = 0x50,
RefIsData = 0x51,
RefIsI31 = 0x52,
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index de26886a4..86de1f7db 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -810,10 +810,13 @@ public:
ret->finalize();
return ret;
}
- RefCast* makeRefCast(Expression* ref, HeapType intendedType) {
+
+ RefCast*
+ makeRefCast(Expression* ref, HeapType intendedType, RefCast::Safety safety) {
auto* ret = wasm.allocator.alloc<RefCast>();
ret->ref = ref;
ret->intendedType = intendedType;
+ ret->safety = safety;
ret->finalize();
return ret;
}
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index d6f3b2f4e..61383f084 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -282,6 +282,7 @@ private:
Expression* makeRefTestStatic(Element& s);
Expression* makeRefCast(Element& s);
Expression* makeRefCastStatic(Element& s);
+ Expression* makeRefCastNopStatic(Element& s);
Expression* makeBrOn(Element& s, BrOnOp op);
Expression* makeBrOnStatic(Element& s, BrOnOp op);
Expression* makeRttCanon(Element& s);
diff --git a/src/wasm.h b/src/wasm.h
index 3b736fcbc..b8e3d6704 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1457,6 +1457,11 @@ public:
Expression* rtt = nullptr;
HeapType intendedType;
+ // Support the unsafe `ref.cast_nop_static` to enable precise cast overhead
+ // measurements.
+ enum Safety { Safe, Unsafe };
+ Safety safety;
+
void finalize();
// Returns the type we intend to cast to.
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 60a4bad77..9cd7e79a7 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -6712,10 +6712,13 @@ bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) {
auto* ref = popNonVoidExpression();
out = Builder(wasm).makeRefCast(ref, rtt);
return true;
- } else if (code == BinaryConsts::RefCastStatic) {
+ } else if (code == BinaryConsts::RefCastStatic ||
+ code == BinaryConsts::RefCastNopStatic) {
auto intendedType = getIndexedHeapType();
auto* ref = popNonVoidExpression();
- out = Builder(wasm).makeRefCast(ref, intendedType);
+ auto safety =
+ code == BinaryConsts::RefCastNopStatic ? RefCast::Unsafe : RefCast::Safe;
+ out = Builder(wasm).makeRefCast(ref, intendedType, safety);
return true;
}
return false;
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 02da4f909..8680ff8cc 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2702,7 +2702,13 @@ Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {
Expression* SExpressionWasmBuilder::makeRefCastStatic(Element& s) {
auto heapType = parseHeapType(*s[1]);
auto* ref = parseExpression(*s[2]);
- return Builder(wasm).makeRefCast(ref, heapType);
+ return Builder(wasm).makeRefCast(ref, heapType, RefCast::Safe);
+}
+
+Expression* SExpressionWasmBuilder::makeRefCastNopStatic(Element& s) {
+ auto heapType = parseHeapType(*s[1]);
+ auto* ref = parseExpression(*s[2]);
+ return Builder(wasm).makeRefCast(ref, heapType, RefCast::Unsafe);
}
Expression* SExpressionWasmBuilder::makeBrOn(Element& s, BrOnOp op) {
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 8afeb6779..8588a049f 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2051,7 +2051,11 @@ void BinaryInstWriter::visitRefCast(RefCast* curr) {
if (curr->rtt) {
o << U32LEB(BinaryConsts::RefCast);
} else {
- o << U32LEB(BinaryConsts::RefCastStatic);
+ if (curr->safety == RefCast::Unsafe) {
+ o << U32LEB(BinaryConsts::RefCastNopStatic);
+ } else {
+ o << U32LEB(BinaryConsts::RefCastStatic);
+ }
parent.writeIndexedHeapType(curr->intendedType);
}
}