Title: [245765] trunk
Revision
245765
Author
[email protected]
Date
2019-05-24 17:51:21 -0700 (Fri, 24 May 2019)

Log Message

[WASM-References] Support Anyref in globals
https://bugs.webkit.org/show_bug.cgi?id=198102

Reviewed by Saam Barati.

JSTests:

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):

Source/_javascript_Core:

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):

Modified Paths

Added Paths

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
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to