Bug 1804310: Add wasm memory control pref. r=rhunt

Differential Revision: https://phabricator.services.mozilla.com/D168485
This commit is contained in:
Ben Visness 2023-02-14 19:27:54 +00:00
parent a2dbc1c182
commit 3bb963d741
11 changed files with 111 additions and 7 deletions

View File

@ -958,6 +958,36 @@ def wasm_memory64(value, simulator, target):
set_config("ENABLE_WASM_MEMORY64", wasm_memory64)
set_define("ENABLE_WASM_MEMORY64", wasm_memory64)
# Support for WebAssembly memory control.
# ===========================
@depends(milestone.is_nightly)
def default_wasm_memory_control(is_nightly):
if is_nightly:
return True
option(
"--enable-wasm-memory-control",
default=default_wasm_memory_control,
help="{Enable|Disable} WebAssembly fine-grained memory control instructions",
)
@depends("--enable-wasm-memory-control")
def wasm_memory_control(value):
if not value:
return
return True
set_config("ENABLE_WASM_MEMORY_CONTROL", wasm_memory_control)
set_define("ENABLE_WASM_MEMORY_CONTROL", wasm_memory_control)
# Options for generating the shell as a script
# ============================================
option("--with-qemu-exe", nargs=1, help="Use path as an arm emulator on host platforms")

View File

@ -85,6 +85,11 @@
#else
# define WASM_MEMORY64_ENABLED 0
#endif
#ifdef ENABLE_WASM_MEMORY_CONTROL
# define WASM_MEMORY_CONTROL_ENABLED 1
#else
# define WASM_MEMORY_CONTROL_ENABLED 0
#endif
#ifdef ENABLE_WASM_MOZ_INTGEMM
# define WASM_MOZ_INTGEMM_ENABLED 1
#else
@ -138,6 +143,14 @@
/* flag predicate */ true, \
/* shell flag */ "memory64", \
/* preference name */ "memory64") \
EXPERIMENTAL( \
/* capitalized name */ MemoryControl, \
/* lower case name */ memoryControl, \
/* compile predicate */ WASM_MEMORY_CONTROL_ENABLED, \
/* compiler predicate */ BaselineAvailable(cx) || IonAvailable(cx), \
/* flag predicate */ true, \
/* shell flag */ "memory-control", \
/* preference name */ "memory_control") \
EXPERIMENTAL(/* capitalized name */ MozIntGemm, \
/* lower case name */ mozIntGemm, \
/* compile predicate */ WASM_MOZ_INTGEMM_ENABLED, \

View File

@ -1 +1 @@
|jit-test| test-also=--wasm-compiler=optimizing; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemorySupported(); test-also=--wasm-test-serialization; test-also=--wasm-compiler=optimizing --no-avx; skip-variant-if: --wasm-compiler=optimizing --no-avx, !getBuildConfiguration().x86 && !getBuildConfiguration().x64 || getBuildConfiguration().simulator; include:wasm.js
|jit-test| include:wasm.js; test-also=--wasm-compiler=optimizing --wasm-memory-control; test-also=--wasm-compiler=baseline --wasm-memory-control; test-also=--wasm-compiler=optimizing --no-wasm-memory64 --wasm-memory-control; test-also=--wasm-compiler=baseline --no-wasm-memory64 --wasm-memory-control

View File

@ -0,0 +1,18 @@
// |jit-test| skip-if: wasmMemoryControlEnabled()
const { validate } = WebAssembly;
const UNRECOGNIZED_OPCODE = /unrecognized opcode/;
let simpleTests = [
"(module (func (memory.discard (i32.const 0) (i32.const 65536))))",
];
for (let src of simpleTests) {
let bin = wasmTextToBinary(src);
assertEq(validate(bin), false);
wasmCompilationShouldFail(bin, UNRECOGNIZED_OPCODE);
}
const mem = new WebAssembly.Memory({ initial: 1 });
assertEq(mem.discard, undefined);

View File

@ -1,4 +1,4 @@
// |jit-test| test-also=--wasm-memory64; test-also=--no-wasm-memory64
// |jit-test| skip-if: !wasmMemoryControlEnabled(); test-also=--wasm-memory64; test-also=--no-wasm-memory64
// This tests memory.discard and WebAssembly.Memory.discard() by placing data
// (the alphabet) halfway across a page boundary, then discarding the first

View File

@ -10243,8 +10243,14 @@ bool BaseCompiler::emitBody() {
CHECK_NEXT(emitDataOrElemDrop(/*isData=*/true));
case uint32_t(MiscOp::MemoryFill):
CHECK_NEXT(emitMemFill());
case uint32_t(MiscOp::MemoryDiscard):
#ifdef ENABLE_WASM_MEMORY_CONTROL
case uint32_t(MiscOp::MemoryDiscard): {
if (!moduleEnv_.memoryControlEnabled()) {
return iter_.unrecognizedOpcode(&op);
}
CHECK_NEXT(emitMemDiscard());
}
#endif
case uint32_t(MiscOp::MemoryInit):
CHECK_NEXT(emitMemInit());
case uint32_t(MiscOp::TableCopy):

View File

@ -8108,8 +8108,14 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
CHECK(EmitMemOrTableInit(f, /*isMem=*/false));
case uint32_t(MiscOp::TableFill):
CHECK(EmitTableFill(f));
case uint32_t(MiscOp::MemoryDiscard):
#if ENABLE_WASM_MEMORY_CONTROL
case uint32_t(MiscOp::MemoryDiscard): {
if (!f.moduleEnv().memoryControlEnabled()) {
return f.iter().unrecognizedOpcode(&op);
}
CHECK(EmitMemDiscard(f));
}
#endif
case uint32_t(MiscOp::TableGrow):
CHECK(EmitTableGrow(f));
case uint32_t(MiscOp::TableSize):

View File

@ -2506,9 +2506,24 @@ const JSClass& WasmMemoryObject::protoClass_ = PlainObject::class_;
static constexpr char WasmMemoryName[] = "Memory";
static JSObject* CreateWasmMemoryPrototype(JSContext* cx, JSProtoKey key) {
RootedObject proto(cx, GlobalObject::createBlankPrototype(
cx, cx->global(), &WasmMemoryObject::protoClass_));
if (!proto) {
return nullptr;
}
if (MemoryControlAvailable(cx)) {
if (!JS_DefineFunctions(cx, proto,
WasmMemoryObject::memoryControlMethods)) {
return nullptr;
}
}
return proto;
}
const ClassSpec WasmMemoryObject::classSpec_ = {
CreateWasmConstructor<WasmMemoryObject, WasmMemoryName>,
GenericCreatePrototype<WasmMemoryObject>,
CreateWasmMemoryPrototype,
WasmMemoryObject::static_methods,
nullptr,
WasmMemoryObject::methods,
@ -2727,7 +2742,9 @@ const JSFunctionSpec WasmMemoryObject::methods[] = {
#ifdef ENABLE_WASM_TYPE_REFLECTIONS
JS_FN("type", WasmMemoryObject::type, 0, JSPROP_ENUMERATE),
#endif
JS_FN("grow", WasmMemoryObject::grow, 1, JSPROP_ENUMERATE),
JS_FN("grow", WasmMemoryObject::grow, 1, JSPROP_ENUMERATE), JS_FS_END};
const JSFunctionSpec WasmMemoryObject::memoryControlMethods[] = {
JS_FN("discard", WasmMemoryObject::discard, 2, JSPROP_ENUMERATE),
JS_FS_END};

View File

@ -390,6 +390,7 @@ class WasmMemoryObject : public NativeObject {
static const JSClass& protoClass_;
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec memoryControlMethods[];
static const JSFunctionSpec static_methods[];
static bool construct(JSContext*, unsigned, Value*);

View File

@ -1148,8 +1148,14 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
CHECK(iter.readTableFill(&unusedTableIndex, &nothing, &nothing,
&nothing));
}
case uint32_t(MiscOp::MemoryDiscard):
#ifdef ENABLE_WASM_MEMORY_CONTROL
case uint32_t(MiscOp::MemoryDiscard): {
if (!env.memoryControlEnabled()) {
return iter.unrecognizedOpcode(&op);
}
CHECK(iter.readMemDiscard(&nothing, &nothing));
}
#endif
case uint32_t(MiscOp::TableGrow): {
uint32_t unusedTableIndex;
CHECK(iter.readTableGrow(&unusedTableIndex, &nothing, &nothing));

View File

@ -7662,6 +7662,13 @@
mirror: always
#endif // defined(ENABLE_WASM_GC)
#if defined(ENABLE_WASM_MEMORY_CONTROL)
- name: javascript.options.wasm_memory_control
type: bool
value: false
mirror: always
#endif // defined(ENABLE_WASM_MEMORY_CONTROL)
#if defined(ENABLE_WASM_SIMD)
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
# Enables AVX instructions support on X86/X64 platforms.