Diff
Modified: trunk/JSTests/ChangeLog (245764 => 245765)
--- trunk/JSTests/ChangeLog 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/JSTests/ChangeLog 2019-05-25 00:51:21 UTC (rev 245765)
@@ -1,3 +1,22 @@
+2019-05-24 Justin Michaud <[email protected]>
+
+ [WASM-References] Support Anyref in globals
+ https://bugs.webkit.org/show_bug.cgi?id=198102
+
+ Reviewed by Saam Barati.
+
+ Add test for anyrefs in globals, as well as adding a new RefNull initExpr for Builder.
+
+ * wasm/Builder.js:
+ (export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):
+ * wasm/Builder_WebAssemblyBinary.js:
+ (const.putInitExpr):
+ * wasm/references/anyref_globals.js: Added.
+ (GetGlobal.0.End.End.WebAssembly):
+ (5.doGCSet):
+ (doGCTest):
+ (doGCSet.doGCTest.let.count.0.doBarrierSet):
+
2019-05-23 Tadeu Zagallo <[email protected]>
DFG::OSREntry should not perform arity check
Modified: trunk/JSTests/wasm/Builder.js (245764 => 245765)
--- trunk/JSTests/wasm/Builder.js 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/JSTests/wasm/Builder.js 2019-05-25 00:51:21 UTC (rev 245765)
@@ -535,6 +535,10 @@
GetGlobal: (type, initValue, mutability) => {
s.data.push({ type, op: "get_global", mutability: _normalizeMutability(mutability), initValue });
return _errorHandlingProxyFor(globalBuilder);
+ },
+ RefNull: (type, mutability) => {
+ s.data.push({ type, op: "ref.null", mutability: _normalizeMutability(mutability) });
+ return _errorHandlingProxyFor(globalBuilder);
}
};
for (let op of WASM.description.value_type) {
Modified: trunk/JSTests/wasm/Builder_WebAssemblyBinary.js (245764 => 245765)
--- trunk/JSTests/wasm/Builder_WebAssemblyBinary.js 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/JSTests/wasm/Builder_WebAssemblyBinary.js 2019-05-25 00:51:21 UTC (rev 245765)
@@ -90,7 +90,10 @@
};
const putInitExpr = (bin, expr) => {
- putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.initValue], arguments: [] });
+ if (expr.op == "ref.null")
+ putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [], arguments: [] });
+ else
+ putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.initValue], arguments: [] });
putOp(bin, { value: WASM.description.opcode.end.value, name: "end", immediates: [], arguments: [] });
};
Added: trunk/JSTests/wasm/references/anyref_globals.js (0 => 245765)
--- trunk/JSTests/wasm/references/anyref_globals.js (rev 0)
+++ trunk/JSTests/wasm/references/anyref_globals.js 2019-05-25 00:51:21 UTC (rev 245765)
@@ -0,0 +1,112 @@
+import * as assert from '../assert.js';
+import Builder from '../Builder.js';
+
+fullGC()
+gc()
+
+const $1 = new WebAssembly.Instance(new WebAssembly.Module((new Builder())
+ .Type().End()
+ .Import()
+ .Global().Anyref("imp", "ref", "immutable").End()
+ .End()
+ .Function().End()
+ .Global()
+ .RefNull("anyref", "mutable")
+ .RefNull("anyref", "immutable")
+ .GetGlobal("anyref", 0, "mutable")
+ .End()
+ .Export()
+ .Function("set_glob")
+ .Function("get_glob")
+ .Function("glob_is_null")
+ .Function("set_glob_null")
+ .Function("get_import")
+ .Global("expglob", 2)
+ .Global("expglob2", 0)
+ .End()
+ .Code()
+ .Function("set_glob", { params: ["anyref"], ret: "void" })
+ .GetLocal(0)
+ .SetGlobal(1)
+ .End()
+
+ .Function("get_glob", { params: [], ret: "anyref" })
+ .GetGlobal(1)
+ .End()
+
+ .Function("glob_is_null", { params: [], ret: "i32" })
+ .Call(1)
+ .RefIsNull()
+ .End()
+
+ .Function("set_glob_null", { params: [], ret: "void" })
+ .RefNull()
+ .Call(0)
+ .End()
+
+ .Function("get_import", { params: [], ret: "anyref" })
+ .GetGlobal(0)
+ .End()
+ .End().WebAssembly().get()), { imp: { ref: "hi" } });
+
+assert.eq($1.exports.get_import(), "hi")
+assert.eq($1.exports.expglob, null)
+assert.eq($1.exports.expglob2, "hi")
+assert.eq($1.exports.get_glob(), null)
+
+const obj = { test: "hi" }
+
+$1.exports.set_glob(obj); assert.eq($1.exports.get_glob(), obj);
+$1.exports.set_glob(5); assert.eq($1.exports.get_glob(), 5)
+$1.exports.set_glob(null); assert.eq($1.exports.get_glob(), null)
+$1.exports.set_glob("hi"); assert.eq($1.exports.get_glob(), "hi")
+$1.exports.set_glob(undefined); assert.eq($1.exports.get_glob(), undefined)
+assert.eq($1.exports.glob_is_null(), 0)
+$1.exports.set_glob_null(); assert.eq($1.exports.get_glob(), null)
+assert.eq($1.exports.glob_is_null(), 1)
+
+const obj2 = { test: 21 }
+$1.exports.set_glob(obj2); assert.eq($1.exports.get_glob(), obj2)
+
+$1.exports.get_glob(obj2).test = 5;
+assert.eq($1.exports.get_glob().test, 5)
+assert.eq(obj2.test, 5)
+
+function doGCSet() {
+ fullGC()
+ $1.exports.set_glob({ test: -1 })
+ fullGC()
+}
+
+function doGCTest() {
+ for (let i=0; i<1000; ++i) {
+ assert.eq($1.exports.get_glob().test, -1)
+ fullGC()
+ }
+}
+
+doGCSet()
+doGCTest()
+
+let count = 0
+
+function doBarrierSet() {
+ ++count
+ $1.exports.set_glob({ test: -count })
+}
+
+function doBarrierTest() {
+ let garbage = { val: "hi", val2: 5, arr: [] }
+ for (let i=0; i<100; ++i) garbage.arr += ({ field: i })
+
+ for (let j=0; j<1000; ++j) {
+ assert.eq($1.exports.get_glob().test, -count)
+ edenGC()
+ }
+}
+
+for (let i=0; i<5; ++i) {
+ doBarrierSet()
+ doBarrierTest()
+ doBarrierTest()
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (245764 => 245765)
--- trunk/Source/_javascript_Core/ChangeLog 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-05-25 00:51:21 UTC (rev 245765)
@@ -1,3 +1,38 @@
+2019-05-24 Justin Michaud <[email protected]>
+
+ [WASM-References] Support Anyref in globals
+ https://bugs.webkit.org/show_bug.cgi?id=198102
+
+ Reviewed by Saam Barati.
+
+ Support anyref for globals, imports and exports. This adds code in B3 and Air to emit a write barrier
+ on the JSWebAssemblyWrapper whenever an anyref global is set. This also fixes a small bug in emitCCall
+ for air where it adds code to the wrong block.
+
+ * wasm/WasmAirIRGenerator.cpp:
+ (JSC::Wasm::AirIRGenerator::emitCCall):
+ (JSC::Wasm::AirIRGenerator::moveOpForValueType):
+ (JSC::Wasm::AirIRGenerator::setGlobal):
+ (JSC::Wasm::AirIRGenerator::emitWriteBarrierForJSWrapper):
+ * wasm/WasmB3IRGenerator.cpp:
+ (JSC::Wasm::B3IRGenerator::setGlobal):
+ (JSC::Wasm::B3IRGenerator::emitWriteBarrierForJSWrapper):
+ * wasm/WasmInstance.cpp:
+ (JSC::Wasm::Instance::Instance):
+ (JSC::Wasm::Instance::setGlobal):
+ * wasm/WasmInstance.h:
+ (JSC::Wasm::Instance::loadI32Global const):
+ (JSC::Wasm::Instance::loadI64Global const):
+ (JSC::Wasm::Instance::setGlobal):
+ (JSC::Wasm::Instance::shouldMarkGlobal):
+ (JSC::Wasm::Instance::numGlobals const):
+ * wasm/WasmSectionParser.cpp:
+ (JSC::Wasm::SectionParser::parseInitExpr):
+ * wasm/js/JSWebAssemblyInstance.cpp:
+ (JSC::JSWebAssemblyInstance::visitChildren):
+ * wasm/js/WebAssemblyModuleRecord.cpp:
+ (JSC::WebAssemblyModuleRecord::link):
+
2019-05-23 Devin Rousso <[email protected]>
Web Inspector: Overlay: rulers/guides should be shown whenever element selection is enabled
Modified: trunk/Source/_javascript_Core/runtime/VM.h (245764 => 245765)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-05-25 00:51:21 UTC (rev 245765)
@@ -687,6 +687,16 @@
return OBJECT_OFFSETOF(VM, topEntryFrame);
}
+ static ptrdiff_t offsetOfHeapBarrierThreshold()
+ {
+ return OBJECT_OFFSETOF(VM, heap) + OBJECT_OFFSETOF(Heap, m_barrierThreshold);
+ }
+
+ static ptrdiff_t offsetOfHeapMutatorShouldBeFenced()
+ {
+ return OBJECT_OFFSETOF(VM, heap) + OBJECT_OFFSETOF(Heap, m_mutatorShouldBeFenced);
+ }
+
void restorePreviousException(Exception* exception) { setException(exception); }
void clearLastException() { m_lastException = nullptr; }
Modified: trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -42,6 +42,7 @@
#include "BinarySwitch.h"
#include "DisallowMacroScratchRegisterUsage.h"
#include "JSCInlines.h"
+#include "JSWebAssemblyInstance.h"
#include "ScratchRegisterAllocator.h"
#include "VirtualRegister.h"
#include "WasmCallingConvention.h"
@@ -529,7 +530,7 @@
Inst inst(CCall, origin);
Tmp callee = g64();
- append(Move, Arg::immPtr(tagCFunctionPtr<void*>(func, B3CCallPtrTag)), callee);
+ append(block, Move, Arg::immPtr(tagCFunctionPtr<void*>(func, B3CCallPtrTag)), callee);
inst.args.append(callee);
if (result)
@@ -547,6 +548,7 @@
case Type::I32:
return Move32;
case Type::I64:
+ case Type::Anyref:
return Move;
case Type::F32:
return MoveFloat;
@@ -561,6 +563,7 @@
void emitTierUpCheck(uint32_t decrementCount, B3::Origin);
+ void emitWriteBarrierForJSWrapper();
ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
ExpressionType emitLoadOp(LoadOpType, ExpressionType pointer, uint32_t offset);
void emitStoreOp(StoreOpType, ExpressionType pointer, ExpressionType value, uint32_t offset);
@@ -1059,9 +1062,60 @@
append(moveOpForValueType(type), value, Arg::addr(temp));
}
+ if (type == Anyref)
+ emitWriteBarrierForJSWrapper();
+
return { };
}
+inline void AirIRGenerator::emitWriteBarrierForJSWrapper()
+{
+ auto cell = g64();
+ auto vm = g64();
+ auto cellState = g32();
+ auto threshold = g32();
+
+ BasicBlock* fenceCheckPath = m_code.addBlock();
+ BasicBlock* fencePath = m_code.addBlock();
+ BasicBlock* doSlowPath = m_code.addBlock();
+ BasicBlock* continuation = m_code.addBlock();
+
+ append(Move, Arg::addr(instanceValue(), Instance::offsetOfOwner()), cell);
+ append(Move, Arg::addr(cell, JSWebAssemblyInstance::offsetOfVM()), vm);
+ append(Load8, Arg::addr(cell, JSCell::cellStateOffset()), cellState);
+ append(Move32, Arg::addr(vm, VM::offsetOfHeapBarrierThreshold()), threshold);
+
+ append(Branch32, Arg::relCond(MacroAssembler::Above), cellState, threshold);
+ m_currentBlock->setSuccessors(continuation, fenceCheckPath);
+ m_currentBlock = fenceCheckPath;
+
+ append(Load8, Arg::addr(vm, VM::offsetOfHeapMutatorShouldBeFenced()), threshold);
+ append(BranchTest32, Arg::resCond(MacroAssembler::Zero), threshold, threshold);
+ m_currentBlock->setSuccessors(doSlowPath, fencePath);
+ m_currentBlock = fencePath;
+
+ auto* doFence = addPatchpoint(B3::Void);
+ doFence->setGenerator([] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+ jit.memoryFence();
+ });
+ emitPatchpoint(doFence, Tmp());
+
+ append(Load8, Arg::addr(cell, JSCell::cellStateOffset()), cellState);
+ append(Branch32, Arg::relCond(MacroAssembler::Above), cellState, Arg::imm(blackThreshold));
+ m_currentBlock->setSuccessors(continuation, doSlowPath);
+ m_currentBlock = doSlowPath;
+
+ void (*writeBarrier)(JSWebAssemblyInstance*, VM*) = [] (JSWebAssemblyInstance* cell, VM* vm) -> void {
+ ASSERT(cell);
+ ASSERT(vm);
+ vm->heap.writeBarrierSlowPath(cell);
+ };
+ emitCCall(writeBarrier, TypedTmp(), cell, vm);
+ append(Jump);
+ m_currentBlock->setSuccessors(continuation);
+ m_currentBlock = continuation;
+}
+
inline AirIRGenerator::ExpressionType AirIRGenerator::emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOperation)
{
ASSERT(m_memoryBaseGPR);
Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -49,6 +49,7 @@
#include "B3WasmBoundsCheckValue.h"
#include "DisallowMacroScratchRegisterUsage.h"
#include "JSCInlines.h"
+#include "JSWebAssemblyInstance.h"
#include "ScratchRegisterAllocator.h"
#include "VirtualRegister.h"
#include "WasmCallingConvention.h"
@@ -239,6 +240,7 @@
void emitTierUpCheck(uint32_t decrementCount, Origin);
+ void emitWriteBarrierForJSWrapper();
ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
B3::Kind memoryKind(B3::Opcode memoryOp);
ExpressionType emitLoadOp(LoadOpType, ExpressionType pointer, uint32_t offset);
@@ -641,9 +643,65 @@
ASSERT(toB3Type(m_info.globals[index].type) == value->type());
Value* globalsArray = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfGlobals()));
m_currentBlock->appendNew<MemoryValue>(m_proc, Store, origin(), value, globalsArray, safeCast<int32_t>(index * sizeof(Register)));
+
+ if (m_info.globals[index].type == Anyref)
+ emitWriteBarrierForJSWrapper();
+
return { };
}
+inline void B3IRGenerator::emitWriteBarrierForJSWrapper()
+{
+ Value* cell = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfOwner()));
+ Value* cellState = m_currentBlock->appendNew<MemoryValue>(m_proc, Load8Z, Int32, origin(), cell, safeCast<int32_t>(JSCell::cellStateOffset()));
+ Value* vm = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), cell, safeCast<int32_t>(JSWebAssemblyInstance::offsetOfVM()));
+ Value* threshold = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), vm, safeCast<int32_t>(VM::offsetOfHeapBarrierThreshold()));
+
+ BasicBlock* fenceCheckPath = m_proc.addBlock();
+ BasicBlock* fencePath = m_proc.addBlock();
+ BasicBlock* doSlowPath = m_proc.addBlock();
+ BasicBlock* continuation = m_proc.addBlock();
+
+ m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
+ m_currentBlock->appendNew<Value>(m_proc, Above, origin(), cellState, threshold),
+ FrequentedBlock(continuation), FrequentedBlock(fenceCheckPath, FrequencyClass::Rare));
+ fenceCheckPath->addPredecessor(m_currentBlock);
+ continuation->addPredecessor(m_currentBlock);
+ m_currentBlock = fenceCheckPath;
+
+ Value* shouldFence = m_currentBlock->appendNew<MemoryValue>(m_proc, Load8Z, Int32, origin(), vm, safeCast<int32_t>(VM::offsetOfHeapMutatorShouldBeFenced()));
+ m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
+ shouldFence,
+ FrequentedBlock(fencePath), FrequentedBlock(doSlowPath));
+ fencePath->addPredecessor(m_currentBlock);
+ doSlowPath->addPredecessor(m_currentBlock);
+ m_currentBlock = fencePath;
+
+ B3::PatchpointValue* doFence = m_currentBlock->appendNew<B3::PatchpointValue>(m_proc, B3::Void, origin());
+ doFence->setGenerator([] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+ jit.memoryFence();
+ });
+
+ Value* cellStateLoadAfterFence = m_currentBlock->appendNew<MemoryValue>(m_proc, Load8Z, Int32, origin(), cell, safeCast<int32_t>(JSCell::cellStateOffset()));
+ m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
+ m_currentBlock->appendNew<Value>(m_proc, Above, origin(), cellStateLoadAfterFence, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), blackThreshold)),
+ FrequentedBlock(continuation), FrequentedBlock(doSlowPath, FrequencyClass::Rare));
+ doSlowPath->addPredecessor(m_currentBlock);
+ continuation->addPredecessor(m_currentBlock);
+ m_currentBlock = doSlowPath;
+
+ void (*writeBarrier)(JSWebAssemblyInstance*, VM*) = [] (JSWebAssemblyInstance* cell, VM* vm) -> void {
+ vm->heap.writeBarrierSlowPath(cell);
+ };
+
+ Value* writeBarrierAddress = m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunctionPtr<void*>(writeBarrier, B3CCallPtrTag));
+ m_currentBlock->appendNew<CCallValue>(m_proc, B3::Void, origin(), writeBarrierAddress, cell, vm);
+ m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), continuation);
+
+ continuation->addPredecessor(m_currentBlock);
+ m_currentBlock = continuation;
+}
+
inline Value* B3IRGenerator::emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOperation)
{
ASSERT(m_memoryBaseGPR);
Modified: trunk/Source/_javascript_Core/wasm/WasmInstance.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/WasmInstance.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/WasmInstance.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -28,6 +28,8 @@
#if ENABLE(WEBASSEMBLY)
+#include "JSCInlines.h"
+#include "JSWebAssemblyInstance.h"
#include "Register.h"
#include "WasmModuleInformation.h"
#include <wtf/CheckedArithmetic.h>
@@ -44,7 +46,8 @@
Instance::Instance(Context* context, Ref<Module>&& module, EntryFrame** pointerToTopEntryFrame, void** pointerToActualStackLimit, StoreTopCallFrameCallback&& storeTopCallFrame)
: m_context(context)
, m_module(WTFMove(module))
- , m_globals(MallocPtr<uint64_t>::malloc(globalMemoryByteSize(m_module.get())))
+ , m_globals(MallocPtr<GlobalValue>::malloc(globalMemoryByteSize(m_module.get())))
+ , m_globalsToMark(m_module.get().moduleInformation().globals.size())
, m_pointerToTopEntryFrame(pointerToTopEntryFrame)
, m_pointerToActualStackLimit(pointerToActualStackLimit)
, m_storeTopCallFrame(WTFMove(storeTopCallFrame))
@@ -52,6 +55,11 @@
{
for (unsigned i = 0; i < m_numImportFunctions; ++i)
new (importFunctionInfo(i)) ImportFunctionInfo();
+ memset(m_globals.get(), 0, globalMemoryByteSize(m_module.get()));
+ for (unsigned i = 0; i < m_module->moduleInformation().globals.size(); ++i) {
+ if (m_module.get().moduleInformation().globals[i].type == Anyref)
+ m_globalsToMark.set(i);
+ }
}
Ref<Instance> Instance::create(Context* context, Ref<Module>&& module, EntryFrame** pointerToTopEntryFrame, void** pointerToActualStackLimit, StoreTopCallFrameCallback&& storeTopCallFrame)
@@ -66,6 +74,12 @@
return globalMemoryByteSize(m_module.get()) + allocationSize(m_numImportFunctions);
}
+void Instance::setGlobal(unsigned i, JSValue value)
+{
+ ASSERT(m_owner);
+ m_globals.get()[i].anyref.set(*owner<JSWebAssemblyInstance>()->vm(), owner<JSWebAssemblyInstance>(), value);
+}
+
} } // namespace JSC::Wasm
#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WasmInstance.h (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/WasmInstance.h 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/WasmInstance.h 2019-05-25 00:51:21 UTC (rev 245765)
@@ -31,6 +31,8 @@
#include "WasmMemory.h"
#include "WasmModule.h"
#include "WasmTable.h"
+#include "WriteBarrier.h"
+#include <wtf/BitVector.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSafeRefCounted.h>
@@ -82,11 +84,13 @@
}
void setTable(Ref<Table>&& table) { m_table = WTFMove(table); }
- int32_t loadI32Global(unsigned i) const { return m_globals.get()[i]; }
- int64_t loadI64Global(unsigned i) const { return m_globals.get()[i]; }
+ int32_t loadI32Global(unsigned i) const { return m_globals.get()[i].primitive; }
+ int64_t loadI64Global(unsigned i) const { return m_globals.get()[i].primitive; }
float loadF32Global(unsigned i) const { return bitwise_cast<float>(loadI32Global(i)); }
double loadF64Global(unsigned i) const { return bitwise_cast<double>(loadI64Global(i)); }
- void setGlobal(unsigned i, int64_t bits) { m_globals.get()[i] = bits; }
+ void setGlobal(unsigned i, int64_t bits) { m_globals.get()[i].primitive = bits; }
+ void setGlobal(unsigned, JSValue);
+ const BitVector& globalsToMark() { return m_globalsToMark; }
static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Instance, m_memory); }
static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(Instance, m_globals); }
@@ -149,7 +153,13 @@
RefPtr<CodeBlock> m_codeBlock;
RefPtr<Memory> m_memory;
RefPtr<Table> m_table;
- MallocPtr<uint64_t> m_globals;
+
+ union GlobalValue {
+ WriteBarrier<Unknown> anyref;
+ uint64_t primitive;
+ };
+ MallocPtr<GlobalValue> m_globals;
+ BitVector m_globalsToMark;
EntryFrame** m_pointerToTopEntryFrame { nullptr };
void** m_pointerToActualStackLimit { nullptr };
void* m_cachedStackLimit { bitwise_cast<void*>(std::numeric_limits<uintptr_t>::max()) };
Modified: trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -476,6 +476,12 @@
break;
}
+ case RefNull: {
+ resultType = Anyref;
+ bitsOrImportNumber = JSValue::encode(jsNull());
+ break;
+ }
+
default:
WASM_PARSER_FAIL_IF(true, "unknown init_expr opcode ", opcode);
}
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -52,6 +52,7 @@
JSWebAssemblyInstance::JSWebAssemblyInstance(VM& vm, Structure* structure, Ref<Wasm::Instance>&& instance)
: Base(vm, structure)
, m_instance(WTFMove(instance))
+ , m_vm(&vm)
{
for (unsigned i = 0; i < this->instance().numImportFunctions(); ++i)
new (this->instance().importFunction<WriteBarrier<JSObject>>(i)) WriteBarrier<JSObject>();
@@ -89,6 +90,12 @@
visitor.reportExtraMemoryVisited(thisObject->m_instance->extraMemoryAllocated());
for (unsigned i = 0; i < thisObject->instance().numImportFunctions(); ++i)
visitor.append(*thisObject->instance().importFunction<WriteBarrier<JSObject>>(i)); // This also keeps the functions' JSWebAssemblyInstance alive.
+
+ for (size_t i : thisObject->instance().globalsToMark()) {
+ // FIXME: We need to box wasm Funcrefs once they are supported here.
+ // <https://bugs.webkit.org/show_bug.cgi?id=198157>
+ visitor.appendUnbarriered(JSValue::decode(thisObject->instance().loadI64Global(i)));
+ }
}
void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock, JSObject* importObject, Wasm::CreationMode creationMode)
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h 2019-05-25 00:51:21 UTC (rev 245765)
@@ -82,6 +82,7 @@
static size_t offsetOfInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); }
static size_t offsetOfCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
+ static size_t offsetOfVM() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_vm); }
protected:
JSWebAssemblyInstance(VM&, Structure*, Ref<Wasm::Instance>&&);
@@ -91,6 +92,7 @@
private:
Ref<Wasm::Instance> m_instance;
+ VM* m_vm;
WriteBarrier<JSWebAssemblyModule> m_module;
WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlock;
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (245764 => 245765)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2019-05-25 00:51:21 UTC (rev 245765)
@@ -235,10 +235,13 @@
// ii. If the global_type of i is i64 or Type(v) is not Number, throw a WebAssembly.LinkError.
if (moduleInformation.globals[import.kindIndex].type == Wasm::I64)
return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "imported global", "cannot be an i64")));
- if (!value.isNumber())
+ if (moduleInformation.globals[import.kindIndex].type != Wasm::Anyref && !value.isNumber())
return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "imported global", "must be a number")));
// iii. Append ToWebAssemblyValue(v) to imports.
switch (moduleInformation.globals[import.kindIndex].type) {
+ case Wasm::Anyref:
+ m_instance->instance().setGlobal(import.kindIndex, value);
+ break;
case Wasm::I32:
m_instance->instance().setGlobal(import.kindIndex, value.toInt32(exec));
break;
@@ -379,6 +382,12 @@
ASSERT(global.mutability == Wasm::Global::Immutable);
// Return ToJSValue(v).
switch (global.type) {
+ case Wasm::Anyref:
+ // FIXME: We need to box wasm Funcrefs once they are supported here.
+ // <https://bugs.webkit.org/show_bug.cgi?id=198157>
+ exportedValue = JSValue::decode(m_instance->instance().loadI64Global(exp.kindIndex));
+ break;
+
case Wasm::I32:
exportedValue = JSValue(m_instance->instance().loadI32Global(exp.kindIndex));
break;
Modified: trunk/Tools/Scripts/run-jsc-stress-tests (245764 => 245765)
--- trunk/Tools/Scripts/run-jsc-stress-tests 2019-05-25 00:40:39 UTC (rev 245764)
+++ trunk/Tools/Scripts/run-jsc-stress-tests 2019-05-25 00:51:21 UTC (rev 245765)
@@ -1081,6 +1081,7 @@
run("wasm-no-tls-context", "-m", "--useFastTLSForWasmContext=false", *FTL_OPTIONS)
run("wasm-slow-memory", "-m", "--useWebAssemblyFastMemory=false", *FTL_OPTIONS)
run("wasm-no-air", "-m", "--wasmBBQUsesAir=false", *FTL_OPTIONS)
+ run("wasm-collect-continuously", "-m", "--collectContinuously=true", *FTL_OPTIONS)
end
end
@@ -1098,6 +1099,7 @@
run("wasm-no-tls-context", "-m", "--useFastTLSForWasmContext=false", *FTL_OPTIONS)
run("wasm-slow-memory", "-m", "--useWebAssemblyFastMemory=false", *FTL_OPTIONS)
run("wasm-no-air", "-m", "--wasmBBQUsesAir=false", *FTL_OPTIONS)
+ run("wasm-collect-continuously", "-m", "--collectContinuously=true", *FTL_OPTIONS)
end
end
@@ -1117,6 +1119,7 @@
run("wasm-no-call-ic", "--useCallICsForWebAssemblyToJSCalls=false", *FTL_OPTIONS)
run("wasm-no-tls-context", "--useFastTLSForWasmContext=false", *FTL_OPTIONS)
run("wasm-no-air", "--wasmBBQUsesAir=false", *FTL_OPTIONS)
+ run("wasm-collect-continuously", "--collectContinuously=true", *FTL_OPTIONS)
end
end
@@ -1142,6 +1145,7 @@
runWithOutputHandler("wasm-no-call-ic", noisyOutputHandler, "../spec-harness.js", "--useCallICsForWebAssemblyToJSCalls=false", *FTL_OPTIONS)
runWithOutputHandler("wasm-no-tls-context", noisyOutputHandler, "../spec-harness.js", "--useFastTLSForWasmContext=false", *FTL_OPTIONS)
runWithOutputHandler("wasm-no-air", noisyOutputHandler, "../spec-harness.js", "--wasmBBQUsesAir=false", *FTL_OPTIONS)
+ runWithOutputHandler("wasm-collect-continuously", noisyOutputHandler, "../spec-harness.js", "--collectContinuously=true", *FTL_OPTIONS)
end
end