Changeset 269940 in webkit


Ignore:
Timestamp:
Nov 17, 2020 7:46:39 PM (20 months ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Implement WebAssembly.Memory with shared
https://bugs.webkit.org/show_bug.cgi?id=218693

Reviewed by Saam Barati.

JSTests:

  • wasm/function-tests/trap-load-shared.js: Added.

(wasmFrameCountFromError):

  • wasm/function-tests/trap-store-shared.js: Added.
  • wasm/js-api/test_memory.js:

(binaryShouldNotParse):

  • wasm/stress/shared-memory-errors.js: Added.

(assert.throws):

  • wasm/stress/shared-wasm-memory-buffer.js: Added.

LayoutTests/imported/w3c:

  • web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any.worker-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/grow.any-expected.txt:
  • web-platform-tests/wasm/jsapi/memory/grow.any.worker-expected.txt:
  • web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt:

Source/JavaScriptCore:

This patch implements shared WebAssembly.Memory. This can be shared between workers like SharedArrayBuffer.
The most interesting thing of shared WebAssembly.Memory is that it is growable. The memory can be grown in
one thread, and immediately, it should be accessible in the other threads.

To achieve that, shared WebAssembly.Memory leverages signaling even if bounds-checking is mainly used.
If the fast memory is enabled, we just use it so that mprotect can make memory grown easily. But if fast memory
is disabled, we allocates requested VA region and perform bounds-checking with this VA. Since WebAssembly.Memory
always requires "maximum" size of memory, we can first allocate VA and map active part of memory first. And
when growing, we perform mprotect to the rest of the memory. Since this VA is not 4GB, we still need to perform
bounds-checking, but we perform bounds-checking with VA size instead of active memory size. As a result, even if
shared WebAssembly.Memory is grown, we do not need to update (1) pointer and (2) bounds-checking size.
The shared bounds-checking WebAssembly.Memory is something like below.

<================================================ maximum ============================><------------ other memory, protected by bounds-checking --...
<======= active ==========><===================== not active yet =====================>
[ if we access this, fault handler will detect it]
pointer bounds checking size

These "growable bound-checking memory" is now managed by wasm memory-manager. And fault handler is used even if fast memory is disabled.
And fault handler also accepts signals from Wasm LLInt code since both bounds-checkings + signalings are required to confine memory access even in
Wasm LLInt. This patch also renamed memory-size and size-register to bounds-checking-size and bounds-checking-size-register since this is no longer
a size of memory.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • llint/LLIntPCRanges.h:

(JSC::LLInt::isWasmLLIntPC):

  • llint/LowLevelInterpreter.asm:
  • llint/WebAssembly.asm:
  • runtime/JSArrayBuffer.h:

(JSC::JSArrayBuffer::toWrappedAllowShared):

  • runtime/JSArrayBufferView.h:
  • runtime/JSArrayBufferViewInlines.h:

(JSC::JSArrayBufferView::toWrappedAllowShared):

  • runtime/JSGenericTypedArrayView.h:

(JSC::JSGenericTypedArrayView<Adaptor>::toWrappedAllowShared):

  • runtime/Options.cpp:

(JSC::overrideDefaults):
(JSC::Options::initialize):

  • wasm/WasmAirIRGenerator.cpp:

(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::AirIRGenerator::addCurrentMemory):
(JSC::Wasm::AirIRGenerator::emitCheckAndPreparePointer):
(JSC::Wasm::AirIRGenerator::addCall):
(JSC::Wasm::AirIRGenerator::addCallIndirect):

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
(JSC::Wasm::B3IRGenerator::emitCheckAndPreparePointer):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):

  • wasm/WasmBinding.cpp:

(JSC::Wasm::wasmToWasm):

  • wasm/WasmFaultSignalHandler.cpp:

(JSC::Wasm::trapHandler):
(JSC::Wasm::enableFastMemory):
(JSC::Wasm::prepareFastMemory):

  • wasm/WasmInstance.h:

(JSC::Wasm::Instance::cachedMemory const):
(JSC::Wasm::Instance::cachedBoundsCheckingSize const):
(JSC::Wasm::Instance::updateCachedMemory):
(JSC::Wasm::Instance::offsetOfCachedBoundsCheckingSize):
(JSC::Wasm::Instance::cachedMemorySize const): Deleted.
(JSC::Wasm::Instance::offsetOfCachedMemorySize): Deleted.

  • wasm/WasmMemory.cpp:

(JSC::Wasm::MemoryHandle::MemoryHandle):
(JSC::Wasm::MemoryHandle::~MemoryHandle):
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::tryCreate):
(JSC::Wasm::Memory::addressIsInGrowableOrFastMemory):
(JSC::Wasm::Memory::growShared):
(JSC::Wasm::Memory::grow):
(JSC::Wasm::Memory::dump const):
(JSC::Wasm::Memory::~Memory): Deleted.
(JSC::Wasm::Memory::addressIsInActiveFastMemory): Deleted.

  • wasm/WasmMemory.h:

(JSC::Wasm::Memory::addressIsInGrowableOrFastMemory):
(JSC::Wasm::Memory::operator bool const): Deleted.
(JSC::Wasm::Memory::memory const): Deleted.
(JSC::Wasm::Memory::size const): Deleted.
(JSC::Wasm::Memory::sizeInPages const): Deleted.
(JSC::Wasm::Memory::initial const): Deleted.
(JSC::Wasm::Memory::maximum const): Deleted.
(JSC::Wasm::Memory::mode const): Deleted.
(JSC::Wasm::Memory::check): Deleted.
(JSC::Wasm::Memory::offsetOfMemory): Deleted.
(JSC::Wasm::Memory::offsetOfSize): Deleted.
(JSC::Wasm::Memory::addressIsInActiveFastMemory): Deleted.

  • wasm/WasmMemoryInformation.cpp:

(JSC::Wasm::PinnedRegisterInfo::get):
(JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):

  • wasm/WasmMemoryInformation.h:

(JSC::Wasm::PinnedRegisterInfo::toSave const):

  • wasm/WasmMemoryMode.cpp:

(JSC::Wasm::makeString):

  • wasm/WasmMemoryMode.h:
  • wasm/js/JSToWasm.cpp:

(JSC::Wasm::createJSToWasmWrapper):

  • wasm/js/JSWebAssemblyInstance.cpp:

(JSC::JSWebAssemblyInstance::tryCreate):

  • wasm/js/JSWebAssemblyMemory.cpp:

(JSC::JSWebAssemblyMemory::buffer):
(JSC::JSWebAssemblyMemory::growSuccessCallback):

  • wasm/js/JSWebAssemblyMemory.h:
  • wasm/js/WebAssemblyFunction.cpp:

(JSC::WebAssemblyFunction::jsCallEntrypointSlow):

  • wasm/js/WebAssemblyMemoryConstructor.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • wasm/js/WebAssemblyMemoryPrototype.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • wasm/js/WebAssemblyModuleRecord.cpp:

(JSC::WebAssemblyModuleRecord::evaluate):

Source/WebCore:

In WebCore, we need three things.

  1. Shared WebAssembly.Memory serialization/deserialization

This patch adds structure-cloning for WebAssembly.Memory to pass it to the other workers. Cloning is available
only when the WebAssembly.Memory is shared mode. And it is only available when we are using it in postMessage.
So we cannot store WebAssembly.Memory in IndexedDB.

  1. WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread

Atomics.wait is usable only in Workers, and *not* usable in Service Workers. When creating VM, we pass WorkerThreadType
and make WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread return appropriate value.

  1. [AllowShared] support for WPT

WPT tests for this are broken, and tests are saying "PASS" while the feature is not implemented at all.
Now, the feature is actually implemented, and WPT tests start showing that [AllowShared] annotation in IDL
is not implemented. [AllowShared] is that, usually, DOM does not accept TypedArray originated from SharedArrayBuffer.
e.g. encodeInto(..., Uint8Array) DOM IDL throws an error if Uint8Array is backed by SharedArrayBuffer.
But in the limited places, we are explicitly allowing this. This is [AllowShared] annotation.
This patch implements that so that we keep passing TextEncoder / TextDecoder tests.

  • Headers.cmake:
  • Modules/indexeddb/server/IDBSerializationContext.cpp:

(WebCore::IDBServer::IDBSerializationContext::initializeVM):

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/IDLTypes.h:
  • bindings/js/CommonVM.cpp:

(WebCore::commonVMSlow):

  • bindings/js/JSDOMConvertBufferSource.h:

(WebCore::Detail::BufferSourceConverter::convert):
(WebCore::Converter<IDLArrayBuffer>::convert):
(WebCore::Converter<IDLDataView>::convert):
(WebCore::Converter<IDLInt8Array>::convert):
(WebCore::Converter<IDLInt16Array>::convert):
(WebCore::Converter<IDLInt32Array>::convert):
(WebCore::Converter<IDLUint8Array>::convert):
(WebCore::Converter<IDLUint16Array>::convert):
(WebCore::Converter<IDLUint32Array>::convert):
(WebCore::Converter<IDLUint8ClampedArray>::convert):
(WebCore::Converter<IDLFloat32Array>::convert):
(WebCore::Converter<IDLFloat64Array>::convert):
(WebCore::Converter<IDLArrayBufferView>::convert):
(WebCore::Converter<IDLAllowSharedAdaptor<T>>::convert):

  • bindings/js/JSDOMConvertUnion.h:
  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneSerializer::serialize):
(WebCore::CloneSerializer::CloneSerializer):
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::SerializedScriptValue::SerializedScriptValue):
(WebCore::SerializedScriptValue::computeMemoryCost const):
(WebCore::SerializedScriptValue::create):
(WebCore::SerializedScriptValue::deserialize):

  • bindings/js/SerializedScriptValue.h:
  • bindings/js/WebCoreJSClientData.cpp:

(WebCore::JSVMClientData::initNormalWorld):

  • bindings/js/WebCoreJSClientData.h:
  • bindings/js/WebCoreTypedArrayController.cpp:

(WebCore::WebCoreTypedArrayController::WebCoreTypedArrayController):
(WebCore::WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread):

  • bindings/js/WebCoreTypedArrayController.h:
  • bindings/scripts/CodeGeneratorJS.pm:

(IsAnnotatedType):
(GetAnnotatedIDLType):

  • bindings/scripts/IDLAttributes.json:
  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::JSTestObjDOMConstructor::construct):
(WebCore::jsTestObjPrototypeFunction_encodeIntoBody):
(WebCore::JSC_DEFINE_HOST_FUNCTION):

  • bindings/scripts/test/TestObj.idl:
  • dom/TextDecoder.idl:
  • dom/TextDecoderStreamDecoder.idl:
  • dom/TextEncoder.idl:
  • workers/DedicatedWorkerGlobalScope.cpp:

(WebCore::DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope):

  • workers/WorkerGlobalScope.cpp:

(WebCore::WorkerGlobalScope::WorkerGlobalScope):

  • workers/WorkerGlobalScope.h:
  • workers/WorkerOrWorkletGlobalScope.cpp:

(WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):

  • workers/WorkerOrWorkletGlobalScope.h:
  • workers/WorkerOrWorkletScriptController.cpp:

(WebCore::WorkerOrWorkletScriptController::WorkerOrWorkletScriptController):

  • workers/WorkerOrWorkletScriptController.h:
  • workers/WorkerThreadType.h: Added.
  • workers/service/ServiceWorkerGlobalScope.cpp:

(WebCore::ServiceWorkerGlobalScope::ServiceWorkerGlobalScope):

  • worklets/WorkletGlobalScope.cpp:

(WebCore::WorkletGlobalScope::WorkletGlobalScope):

LayoutTests:

  • js/dom/resources/webassembly-memory-normal-fail-worker.js: Added.
  • js/dom/resources/webassembly-memory-shared-worker.js: Added.

(onmessage):

  • js/dom/webassembly-memory-normal-fail-expected.txt: Added.
  • js/dom/webassembly-memory-normal-fail.html: Added.
  • js/dom/webassembly-memory-shared-basic-expected.txt: Added.
  • js/dom/webassembly-memory-shared-basic.html: Added.
  • js/dom/webassembly-memory-shared-fail-expected.txt: Added.
  • js/dom/webassembly-memory-shared-fail.html: Added.
  • platform/win/TestExpectations:
  • storage/indexeddb/resources/shared-memory-structured-clone.js: Added.

(prepareDatabase):
(async startTests):
(testSharedWebAssemblyMemory):

  • storage/indexeddb/shared-memory-structured-clone-expected.txt: Added.
  • storage/indexeddb/shared-memory-structured-clone.html: Added.
Location:
trunk
Files:
17 added
74 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r269939 r269940  
     12020-11-16  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement WebAssembly.Memory with shared
     4        https://bugs.webkit.org/show_bug.cgi?id=218693
     5
     6        Reviewed by Saam Barati.
     7
     8        * wasm/function-tests/trap-load-shared.js: Added.
     9        (wasmFrameCountFromError):
     10        * wasm/function-tests/trap-store-shared.js: Added.
     11        * wasm/js-api/test_memory.js:
     12        (binaryShouldNotParse):
     13        * wasm/stress/shared-memory-errors.js: Added.
     14        (assert.throws):
     15        * wasm/stress/shared-wasm-memory-buffer.js: Added.
     16
    1172020-11-17  Yusuke Suzuki  <ysuzuki@apple.com>
    218
  • trunk/JSTests/wasm/js-api/test_memory.js

    r217921 r269940  
    125125{
    126126    assert.throws(() => new WebAssembly.Memory(20), TypeError, "WebAssembly.Memory expects its first argument to be an object");
    127     assert.throws(() => new WebAssembly.Memory({}, {}), TypeError,  "WebAssembly.Memory expects exactly one argument");
     127    new WebAssembly.Memory({initial:1}, {});
    128128}
    129129
  • trunk/LayoutTests/ChangeLog

    r269929 r269940  
     12020-11-16  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement WebAssembly.Memory with shared
     4        https://bugs.webkit.org/show_bug.cgi?id=218693
     5
     6        Reviewed by Saam Barati.
     7
     8        * js/dom/resources/webassembly-memory-normal-fail-worker.js: Added.
     9        * js/dom/resources/webassembly-memory-shared-worker.js: Added.
     10        (onmessage):
     11        * js/dom/webassembly-memory-normal-fail-expected.txt: Added.
     12        * js/dom/webassembly-memory-normal-fail.html: Added.
     13        * js/dom/webassembly-memory-shared-basic-expected.txt: Added.
     14        * js/dom/webassembly-memory-shared-basic.html: Added.
     15        * js/dom/webassembly-memory-shared-fail-expected.txt: Added.
     16        * js/dom/webassembly-memory-shared-fail.html: Added.
     17        * platform/win/TestExpectations:
     18        * storage/indexeddb/resources/shared-memory-structured-clone.js: Added.
     19        (prepareDatabase):
     20        (async startTests):
     21        (testSharedWebAssemblyMemory):
     22        * storage/indexeddb/shared-memory-structured-clone-expected.txt: Added.
     23        * storage/indexeddb/shared-memory-structured-clone.html: Added.
     24
    1252020-11-17  Sergey Rubanov  <chi187@gmail.com>
    226
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r269875 r269940  
     12020-11-16  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement WebAssembly.Memory with shared
     4        https://bugs.webkit.org/show_bug.cgi?id=218693
     5
     6        Reviewed by Saam Barati.
     7
     8        * web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt:
     9        * web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any-expected.txt:
     10        * web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any.worker-expected.txt:
     11        * web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt:
     12        * web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt:
     13        * web-platform-tests/wasm/jsapi/memory/grow.any-expected.txt:
     14        * web-platform-tests/wasm/jsapi/memory/grow.any.worker-expected.txt:
     15        * web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt:
     16
    1172020-11-16  Alex Christensen  <achristensen@webkit.org>
    218
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt

    r269531 r269940  
    11
    2 FAIL [[CanBlock]] in a DedicatedWorkerGlobalScope Typed array for wait/notify must wrap a SharedArrayBuffer.
     2PASS [[CanBlock]] in a DedicatedWorkerGlobalScope
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any-expected.txt

    r269866 r269940  
    11
    2 FAIL Shared memory without maximum assert_throws_js: function "() => new WebAssembly.Memory({ "initial": 10, "shared": true })" did not throw
    3 FAIL Order of evaluation for descriptor (with shared) assert_array_equals: lengths differ, expected array ["initial", "initial valueOf", "maximum", "maximum valueOf", "shared"] length 5, got ["initial", "initial valueOf", "maximum", "maximum valueOf"] length 4
    4 FAIL Shared memory assert_equals: undefined: constructor expected true but got false
     2PASS Shared memory without maximum
     3PASS Order of evaluation for descriptor (with shared)
     4PASS Shared memory
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any.worker-expected.txt

    r269866 r269940  
    11
    2 FAIL Shared memory without maximum assert_throws_js: function "() => new WebAssembly.Memory({ "initial": 10, "shared": true })" did not throw
    3 FAIL Order of evaluation for descriptor (with shared) assert_array_equals: lengths differ, expected array ["initial", "initial valueOf", "maximum", "maximum valueOf", "shared"] length 5, got ["initial", "initial valueOf", "maximum", "maximum valueOf"] length 4
    4 FAIL Shared memory assert_equals: undefined: constructor expected true but got false
     2PASS Shared memory without maximum
     3PASS Order of evaluation for descriptor (with shared)
     4PASS Shared memory
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt

    r269866 r269940  
    2323PASS Zero initial
    2424PASS Non-zero initial
    25 FAIL Stray argument WebAssembly.Memory expects exactly one argument
     25PASS Stray argument
    2626
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt

    r269866 r269940  
    2323PASS Zero initial
    2424PASS Non-zero initial
    25 FAIL Stray argument WebAssembly.Memory expects exactly one argument
     25PASS Stray argument
    2626
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any-expected.txt

    r267649 r269940  
    1818PASS Out-of-range argument: object "[object Object]"
    1919PASS Stray argument
    20 FAIL Growing shared memory does not detach old buffer assert_equals: Buffer before growing: constructor expected true but got false
     20PASS Growing shared memory does not detach old buffer
    2121
  • trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any.worker-expected.txt

    r267649 r269940  
    1818PASS Out-of-range argument: object "[object Object]"
    1919PASS Stray argument
    20 FAIL Growing shared memory does not detach old buffer assert_equals: Buffer before growing: constructor expected true but got false
     20PASS Growing shared memory does not detach old buffer
    2121
  • trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt

    r267649 r269940  
    2020PASS   6: buffer.copyFromChannel(x, 0, 16) did not throw an exception.
    2121PASS   7: buffer.copyFromChannel(x, 3) threw IndexSizeError: "Not a valid channelNumber.".
    22 FAIL X 8: buffer.copyFromChannel(SharedArrayBuffer view, 0) did not throw an exception. assert_true: expected true got false
    23 FAIL X 9: buffer.copyFromChannel(SharedArrayBuffer view, 0, 0) did not throw an exception. assert_true: expected true got false
    24 FAIL < [copyFrom-exceptions] 2 out of 11 assertions were failed. assert_true: expected true got false
     22PASS   8: buffer.copyFromChannel(SharedArrayBuffer view, 0) threw TypeError: "Argument 1 ('destination') to AudioBuffer.copyFromChannel must be an instance of Float32Array".
     23PASS   9: buffer.copyFromChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Argument 1 ('destination') to AudioBuffer.copyFromChannel must be an instance of Float32Array".
     24PASS < [copyFrom-exceptions] All assertions passed. (total 11 assertions)
    2525PASS > [copyTo-exceptions]
    2626PASS   AudioBuffer.prototype.copyToChannel does exist.
     
    3232PASS   5: buffer.copyToChannel(x, 0, 16) did not throw an exception.
    3333PASS   6: buffer.copyToChannel(x, 3) threw IndexSizeError: "Not a valid channelNumber.".
    34 FAIL X 7: buffer.copyToChannel(SharedArrayBuffer view, 0) did not throw an exception. assert_true: expected true got false
    35 FAIL X 8: buffer.copyToChannel(SharedArrayBuffer view, 0, 0) did not throw an exception. assert_true: expected true got false
    36 FAIL < [copyTo-exceptions] 2 out of 10 assertions were failed. assert_true: expected true got false
     34PASS   7: buffer.copyToChannel(SharedArrayBuffer view, 0) threw TypeError: "Argument 1 ('source') to AudioBuffer.copyToChannel must be an instance of Float32Array".
     35PASS   8: buffer.copyToChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Argument 1 ('source') to AudioBuffer.copyToChannel must be an instance of Float32Array".
     36PASS < [copyTo-exceptions] All assertions passed. (total 10 assertions)
    3737PASS > [copyFrom-validate]
    3838PASS   buffer.copyFromChannel(dst8, 0) is identical to the array [1,2,3,4,5,6,7,8].
     
    6161PASS   buffer.copyToChannel(src10, 2, 5) is identical to the array [-1,-1,-1,-1,-1,1,2,3,4,5,6,7,8,9,10,-1...].
    6262PASS < [copyTo-validate] All assertions passed. (total 10 assertions)
    63 FAIL # AUDIT TASK RUNNER FINISHED: 2 out of 5 tasks were failed. assert_true: expected true got false
     63PASS # AUDIT TASK RUNNER FINISHED: 5 tasks ran successfully.
    6464
  • trunk/LayoutTests/platform/win/TestExpectations

    r269785 r269940  
    46014601webkit.org/b/218346 fast/text/canvas-color-fonts [ Pass ImageOnlyFailure ]
    46024602webkit.org/b/218346 http/tests/canvas/color-fonts [ Pass ImageOnlyFailure ]
     4603
     4604# WebAssembly is not enabled
     4605js/dom/webassembly-memory-shared-basic.html [ Skip ]
     4606js/dom/webassembly-memory-normal-fail.html [ Skip ]
     4607js/dom/webassembly-memory-shared-fail.html [ Skip ]
     4608storage/indexeddb/shared-memory-structured-clone.html [ Skip ]
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r269933 r269940  
    10901090
    10911091    wasm/js/JSWebAssembly.h
     1092    wasm/js/JSWebAssemblyMemory.h
    10921093    wasm/js/JSWebAssemblyModule.h
    10931094
  • trunk/Source/JavaScriptCore/ChangeLog

    r269939 r269940  
     12020-11-16  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement WebAssembly.Memory with shared
     4        https://bugs.webkit.org/show_bug.cgi?id=218693
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch implements shared WebAssembly.Memory. This can be shared between workers like SharedArrayBuffer.
     9        The most interesting thing of shared WebAssembly.Memory is that it is growable. The memory can be grown in
     10        one thread, and immediately, it should be accessible in the other threads.
     11
     12        To achieve that, shared WebAssembly.Memory leverages signaling even if bounds-checking is mainly used.
     13        If the fast memory is enabled, we just use it so that mprotect can make memory grown easily. But if fast memory
     14        is disabled, we allocates requested VA region and perform bounds-checking with this VA. Since WebAssembly.Memory
     15        always requires "maximum" size of memory, we can first allocate VA and map active part of memory first. And
     16        when growing, we perform mprotect to the rest of the memory. Since this VA is not 4GB, we still need to perform
     17        bounds-checking, but we perform bounds-checking with VA size instead of active memory size. As a result, even if
     18        shared WebAssembly.Memory is grown, we do not need to update (1) pointer and (2) bounds-checking size.
     19        The shared bounds-checking WebAssembly.Memory is something like below.
     20
     21        <================================================ maximum ============================><------------ other memory, protected by bounds-checking --...
     22        <======= active ==========><===================== not active yet =====================>
     23        ^                               [ if we access this, fault handler will detect it]    ^
     24        pointer                                                                               bounds checking size
     25
     26        These "growable bound-checking memory" is now managed by wasm memory-manager. And fault handler is used even if fast memory is disabled.
     27        And fault handler also accepts signals from Wasm LLInt code since both bounds-checkings + signalings are required to confine memory access even in
     28        Wasm LLInt. This patch also renamed memory-size and size-register to bounds-checking-size and bounds-checking-size-register since this is no longer
     29        a size of memory.
     30
     31        * CMakeLists.txt:
     32        * JavaScriptCore.xcodeproj/project.pbxproj:
     33        * llint/LLIntPCRanges.h:
     34        (JSC::LLInt::isWasmLLIntPC):
     35        * llint/LowLevelInterpreter.asm:
     36        * llint/WebAssembly.asm:
     37        * runtime/JSArrayBuffer.h:
     38        (JSC::JSArrayBuffer::toWrappedAllowShared):
     39        * runtime/JSArrayBufferView.h:
     40        * runtime/JSArrayBufferViewInlines.h:
     41        (JSC::JSArrayBufferView::toWrappedAllowShared):
     42        * runtime/JSGenericTypedArrayView.h:
     43        (JSC::JSGenericTypedArrayView<Adaptor>::toWrappedAllowShared):
     44        * runtime/Options.cpp:
     45        (JSC::overrideDefaults):
     46        (JSC::Options::initialize):
     47        * wasm/WasmAirIRGenerator.cpp:
     48        (JSC::Wasm::AirIRGenerator::AirIRGenerator):
     49        (JSC::Wasm::AirIRGenerator::restoreWebAssemblyGlobalState):
     50        (JSC::Wasm::AirIRGenerator::addCurrentMemory):
     51        (JSC::Wasm::AirIRGenerator::emitCheckAndPreparePointer):
     52        (JSC::Wasm::AirIRGenerator::addCall):
     53        (JSC::Wasm::AirIRGenerator::addCallIndirect):
     54        * wasm/WasmB3IRGenerator.cpp:
     55        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
     56        (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState):
     57        (JSC::Wasm::B3IRGenerator::addCurrentMemory):
     58        (JSC::Wasm::B3IRGenerator::emitCheckAndPreparePointer):
     59        (JSC::Wasm::B3IRGenerator::addCall):
     60        (JSC::Wasm::B3IRGenerator::addCallIndirect):
     61        * wasm/WasmBinding.cpp:
     62        (JSC::Wasm::wasmToWasm):
     63        * wasm/WasmFaultSignalHandler.cpp:
     64        (JSC::Wasm::trapHandler):
     65        (JSC::Wasm::enableFastMemory):
     66        (JSC::Wasm::prepareFastMemory):
     67        * wasm/WasmInstance.h:
     68        (JSC::Wasm::Instance::cachedMemory const):
     69        (JSC::Wasm::Instance::cachedBoundsCheckingSize const):
     70        (JSC::Wasm::Instance::updateCachedMemory):
     71        (JSC::Wasm::Instance::offsetOfCachedBoundsCheckingSize):
     72        (JSC::Wasm::Instance::cachedMemorySize const): Deleted.
     73        (JSC::Wasm::Instance::offsetOfCachedMemorySize): Deleted.
     74        * wasm/WasmMemory.cpp:
     75        (JSC::Wasm::MemoryHandle::MemoryHandle):
     76        (JSC::Wasm::MemoryHandle::~MemoryHandle):
     77        (JSC::Wasm::Memory::Memory):
     78        (JSC::Wasm::Memory::create):
     79        (JSC::Wasm::Memory::tryCreate):
     80        (JSC::Wasm::Memory::addressIsInGrowableOrFastMemory):
     81        (JSC::Wasm::Memory::growShared):
     82        (JSC::Wasm::Memory::grow):
     83        (JSC::Wasm::Memory::dump const):
     84        (JSC::Wasm::Memory::~Memory): Deleted.
     85        (JSC::Wasm::Memory::addressIsInActiveFastMemory): Deleted.
     86        * wasm/WasmMemory.h:
     87        (JSC::Wasm::Memory::addressIsInGrowableOrFastMemory):
     88        (JSC::Wasm::Memory::operator bool const): Deleted.
     89        (JSC::Wasm::Memory::memory const): Deleted.
     90        (JSC::Wasm::Memory::size const): Deleted.
     91        (JSC::Wasm::Memory::sizeInPages const): Deleted.
     92        (JSC::Wasm::Memory::initial const): Deleted.
     93        (JSC::Wasm::Memory::maximum const): Deleted.
     94        (JSC::Wasm::Memory::mode const): Deleted.
     95        (JSC::Wasm::Memory::check): Deleted.
     96        (JSC::Wasm::Memory::offsetOfMemory): Deleted.
     97        (JSC::Wasm::Memory::offsetOfSize): Deleted.
     98        (JSC::Wasm::Memory::addressIsInActiveFastMemory): Deleted.
     99        * wasm/WasmMemoryInformation.cpp:
     100        (JSC::Wasm::PinnedRegisterInfo::get):
     101        (JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
     102        * wasm/WasmMemoryInformation.h:
     103        (JSC::Wasm::PinnedRegisterInfo::toSave const):
     104        * wasm/WasmMemoryMode.cpp:
     105        (JSC::Wasm::makeString):
     106        * wasm/WasmMemoryMode.h:
     107        * wasm/js/JSToWasm.cpp:
     108        (JSC::Wasm::createJSToWasmWrapper):
     109        * wasm/js/JSWebAssemblyInstance.cpp:
     110        (JSC::JSWebAssemblyInstance::tryCreate):
     111        * wasm/js/JSWebAssemblyMemory.cpp:
     112        (JSC::JSWebAssemblyMemory::buffer):
     113        (JSC::JSWebAssemblyMemory::growSuccessCallback):
     114        * wasm/js/JSWebAssemblyMemory.h:
     115        * wasm/js/WebAssemblyFunction.cpp:
     116        (JSC::WebAssemblyFunction::jsCallEntrypointSlow):
     117        * wasm/js/WebAssemblyMemoryConstructor.cpp:
     118        (JSC::JSC_DEFINE_HOST_FUNCTION):
     119        * wasm/js/WebAssemblyMemoryPrototype.cpp:
     120        (JSC::JSC_DEFINE_HOST_FUNCTION):
     121        * wasm/js/WebAssemblyModuleRecord.cpp:
     122        (JSC::WebAssemblyModuleRecord::evaluate):
     123
    11242020-11-17  Yusuke Suzuki  <ysuzuki@apple.com>
    2125
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r269706 r269940  
    15751575                AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */; };
    15761576                AD2FCBE51DB58DAD00B3E736 /* JSWebAssemblyInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBA91DB58DA400B3E736 /* JSWebAssemblyInstance.h */; };
    1577                 AD2FCBE71DB58DAD00B3E736 /* JSWebAssemblyMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAB1DB58DA400B3E736 /* JSWebAssemblyMemory.h */; };
     1577                AD2FCBE71DB58DAD00B3E736 /* JSWebAssemblyMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAB1DB58DA400B3E736 /* JSWebAssemblyMemory.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15781578                AD2FCBE91DB58DAD00B3E736 /* JSWebAssemblyRuntimeError.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAD1DB58DA400B3E736 /* JSWebAssemblyRuntimeError.h */; };
    15791579                AD2FCBEB1DB58DAD00B3E736 /* JSWebAssemblyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAF1DB58DA400B3E736 /* JSWebAssemblyTable.h */; };
  • trunk/Source/JavaScriptCore/llint/LLIntPCRanges.h

    r268247 r269940  
    3636    void llintPCRangeStart();
    3737    void llintPCRangeEnd();
     38#if ENABLE(WEBASSEMBLY)
     39    void wasmLLIntPCRangeStart();
     40    void wasmLLIntPCRangeEnd();
     41#endif
    3842}
    3943
     
    4751}
    4852
     53#if ENABLE(WEBASSEMBLY)
     54ALWAYS_INLINE bool isWasmLLIntPC(void* pc)
     55{
     56    uintptr_t pcAsInt = bitwise_cast<uintptr_t>(pc);
     57    uintptr_t start = untagCodePtr<uintptr_t, CFunctionPtrTag>(wasmLLIntPCRangeStart);
     58    uintptr_t end = untagCodePtr<uintptr_t, CFunctionPtrTag>(wasmLLIntPCRangeEnd);
     59    RELEASE_ASSERT(start < end);
     60    return start <= pcAsInt && pcAsInt <= end;
     61}
     62#endif
     63
    4964#if !ENABLE(C_LOOP)
    5065static constexpr GPRReg LLIntPC = GPRInfo::regT4;
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r269929 r269940  
    24682468    include WebAssembly
    24692469end
     2470
     2471global _wasmLLIntPCRangeStart
     2472_wasmLLIntPCRangeStart:
    24702473wasmScope()
     2474global _wasmLLIntPCRangeEnd
     2475_wasmLLIntPCRangeEnd:
    24712476
    24722477else
  • trunk/Source/JavaScriptCore/llint/WebAssembly.asm

    r269929 r269940  
    4646const wasmInstance = csr0
    4747const memoryBase = csr3
    48 const memorySize = csr4
     48const boundsCheckingSize = csr4
    4949
    5050# This must match the definition in LowLevelInterpreter.asm
     
    188188
    189189macro preserveCalleeSavesUsedByWasm()
    190     # NOTE: We intentionally don't save memoryBase and memorySize here. See the comment
     190    # NOTE: We intentionally don't save memoryBase and boundsCheckingSize here. See the comment
    191191    # in restoreCalleeSavesUsedByWasm() below for why.
    192192    subp CalleeSaveSpaceStackAligned, sp
     
    202202
    203203macro restoreCalleeSavesUsedByWasm()
    204     # NOTE: We intentionally don't restore memoryBase and memorySize here. These are saved
     204    # NOTE: We intentionally don't restore memoryBase and boundsCheckingSize here. These are saved
    205205    # and restored when entering Wasm by the JSToWasm wrapper and changes to them are meant
    206206    # to be observable within the same Wasm module.
     
    241241macro reloadMemoryRegistersFromInstance(instance, scratch1, scratch2)
    242242    loadp Wasm::Instance::m_cachedMemory[instance], memoryBase
    243     loadi Wasm::Instance::m_cachedMemorySize[instance], memorySize
    244     cagedPrimitive(memoryBase, memorySize, scratch1, scratch2)
     243    loadi Wasm::Instance::m_cachedBoundsCheckingSize[instance], boundsCheckingSize
     244    cagedPrimitive(memoryBase, boundsCheckingSize, scratch1, scratch2)
    245245end
    246246
     
    857857
    858858wasmOp(current_memory, WasmCurrentMemory, macro(ctx)
    859     loadp Wasm::Instance::m_cachedMemorySize[wasmInstance], t0
     859    loadp Wasm::Instance::m_memory[wasmInstance], t0
     860    loadp Wasm::Memory::m_handle[t0], t0
     861    loadp Wasm::MemoryHandle::m_size[t0], t0
    860862    urshiftq 16, t0
    861863    returnq(ctx, t0)
     
    875877macro emitCheckAndPreparePointer(ctx, pointer, offset, size)
    876878    leap size - 1[pointer, offset], t5
    877     bpb t5, memorySize, .continuation
     879    bpb t5, boundsCheckingSize, .continuation
    878880    throwException(OutOfBoundsMemoryAccess)
    879881.continuation:
  • trunk/Source/JavaScriptCore/runtime/JSArrayBuffer.h

    r260415 r269940  
    5656    // This is the default DOM unwrapping. It calls toUnsharedArrayBuffer().
    5757    static ArrayBuffer* toWrapped(VM&, JSValue);
     58    static ArrayBuffer* toWrappedAllowShared(VM&, JSValue);
    5859   
    5960private:
     
    8788}
    8889
     90inline ArrayBuffer* JSArrayBuffer::toWrappedAllowShared(VM& vm, JSValue value)
     91{
     92    return toPossiblySharedArrayBuffer(vm, value);
     93}
     94
    8995} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.h

    r269832 r269940  
    205205   
    206206    static RefPtr<ArrayBufferView> toWrapped(VM&, JSValue);
     207    static RefPtr<ArrayBufferView> toWrappedAllowShared(VM&, JSValue);
    207208
    208209private:
  • trunk/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h

    r259069 r269940  
    130130}
    131131
     132inline RefPtr<ArrayBufferView> JSArrayBufferView::toWrappedAllowShared(VM& vm, JSValue value)
     133{
     134    if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, value))
     135        return view->possiblySharedImpl();
     136    return nullptr;
     137}
     138
     139
    132140} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h

    r269343 r269940  
    288288    // This is the default DOM unwrapping. It calls toUnsharedNativeTypedView().
    289289    static RefPtr<typename Adaptor::ViewType> toWrapped(VM&, JSValue);
     290    // [AllowShared] annotation allows accepting TypedArray originated from SharedArrayBuffer.
     291    static RefPtr<typename Adaptor::ViewType> toWrappedAllowShared(VM&, JSValue);
    290292   
    291293private:
     
    393395}
    394396
     397template<typename Adaptor>
     398RefPtr<typename Adaptor::ViewType> JSGenericTypedArrayView<Adaptor>::toWrappedAllowShared(VM& vm, JSValue value)
     399{
     400    return JSC::toPossiblySharedNativeTypedView<Adaptor>(vm, value);
     401}
     402
     403
    395404} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r269349 r269940  
    366366#endif
    367367
    368 #if !ENABLE(WEBASSEMBLY_FAST_MEMORY)
     368#if !ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    369369    Options::useWebAssemblyFastMemory() = false;
     370    Options::useSharedArrayBuffer() = false;
    370371#endif
    371372
     
    659660#endif
    660661
    661 #if ASAN_ENABLED && OS(LINUX) && ENABLE(WEBASSEMBLY_FAST_MEMORY)
    662             if (Options::useWebAssemblyFastMemory()) {
     662#if ASAN_ENABLED && OS(LINUX) && ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
     663            if (Options::useWebAssemblyFastMemory() || Options::useSharedArrayBuffer()) {
    663664                const char* asanOptions = getenv("ASAN_OPTIONS");
    664665                bool okToUseWebAssemblyFastMemory = asanOptions
    665666                    && (strstr(asanOptions, "allow_user_segv_handler=1") || strstr(asanOptions, "handle_segv=0"));
    666667                if (!okToUseWebAssemblyFastMemory) {
    667                     dataLogLn("WARNING: ASAN interferes with JSC signal handlers; useWebAssemblyFastMemory will be disabled.");
     668                    dataLogLn("WARNING: ASAN interferes with JSC signal handlers; useWebAssemblyFastMemory and useSharedArrayBuffer will be disabled.");
    668669                    Options::useWebAssemblyFastMemory() = false;
     670                    Options::useSharedArrayBuffer() = false;
    669671                }
    670672            }
  • trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp

    r269929 r269940  
    681681    Vector<UnlinkedWasmToWasmCall>& m_unlinkedWasmToWasmCalls; // List each call site and the function index whose address it should be patched with.
    682682    GPRReg m_memoryBaseGPR { InvalidGPRReg };
    683     GPRReg m_memorySizeGPR { InvalidGPRReg };
     683    GPRReg m_boundsCheckingSizeGPR { InvalidGPRReg };
    684684    GPRReg m_wasmContextInstanceGPR { InvalidGPRReg };
    685685    bool m_makesCalls { false };
     
    773773
    774774    if (mode != MemoryMode::Signaling) {
    775         m_memorySizeGPR = pinnedRegs.sizeRegister;
    776         m_code.pinRegister(m_memorySizeGPR);
     775        m_boundsCheckingSizeGPR = pinnedRegs.boundsCheckingSizeRegister;
     776        m_code.pinRegister(m_boundsCheckingSizeGPR);
    777777    }
    778778
     
    919919        RegisterSet clobbers;
    920920        clobbers.set(pinnedRegs->baseMemoryPointer);
    921         clobbers.set(pinnedRegs->sizeRegister);
     921        clobbers.set(pinnedRegs->boundsCheckingSizeRegister);
    922922        if (!isARM64())
    923923            clobbers.set(RegisterSet::macroScratchRegisters());
     
    934934            AllowMacroScratchRegisterUsage allowScratch(jit);
    935935            GPRReg baseMemory = pinnedRegs->baseMemoryPointer;
    936             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;
    937 
    938             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister);
     936            GPRReg scratchOrBoundsCheckingSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->boundsCheckingSizeRegister;
     937
     938            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs->boundsCheckingSizeRegister);
    939939            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory);
    940940
    941             jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);
     941            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->boundsCheckingSizeRegister, scratchOrBoundsCheckingSize);
    942942        });
    943943
     
    11691169    auto temp2 = g64();
    11701170
    1171     RELEASE_ASSERT(Arg::isValidAddrForm(Instance::offsetOfCachedMemorySize(), B3::Width64));
    1172     append(Move, Arg::addr(instanceValue(), Instance::offsetOfCachedMemorySize()), temp1);
     1171    RELEASE_ASSERT(Arg::isValidAddrForm(Instance::offsetOfMemory(), B3::Width64));
     1172    RELEASE_ASSERT(Arg::isValidAddrForm(Memory::offsetOfHandle(), B3::Width64));
     1173    RELEASE_ASSERT(Arg::isValidAddrForm(MemoryHandle::offsetOfSize(), B3::Width64));
     1174    append(Move, Arg::addr(instanceValue(), Instance::offsetOfMemory()), temp1);
     1175    append(Move, Arg::addr(temp1, Memory::offsetOfHandle()), temp1);
     1176    append(Move, Arg::addr(temp1, MemoryHandle::offsetOfSize()), temp1);
    11731177    constexpr uint32_t shiftValue = 16;
    11741178    static_assert(PageCount::pageSize == 1ull << shiftValue, "This must hold for the code below to be correct.");
     
    13641368    switch (m_mode) {
    13651369    case MemoryMode::BoundsChecking: {
    1366         // We're not using signal handling at all, we must therefore check that no memory access exceeds the current memory size.
    1367         ASSERT(m_memorySizeGPR);
     1370        // In bound checking mode, while shared wasm memory partially relies on signal handler too, we need to perform bound checking
     1371        // to ensure that no memory access exceeds the current memory size.
     1372        ASSERT(m_boundsCheckingSizeGPR);
    13681373        ASSERT(sizeOfOperation + offset > offset);
    13691374        auto temp = g64();
     
    13721377
    13731378        emitCheck([&] {
    1374             return Inst(Branch64, nullptr, Arg::relCond(MacroAssembler::AboveOrEqual), temp, Tmp(m_memorySizeGPR));
     1379            return Inst(Branch64, nullptr, Arg::relCond(MacroAssembler::AboveOrEqual), temp, Tmp(m_boundsCheckingSizeGPR));
    13751380        }, [=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
    13761381            this->emitThrowException(jit, ExceptionType::OutOfBoundsMemoryAccess);
     
    21552160        // We need to clobber the size register since the LLInt always bounds checks
    21562161        if (m_mode == MemoryMode::Signaling)
    2157             patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().sizeRegister });
     2162            patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().boundsCheckingSizeRegister });
    21582163        patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
    21592164            AllowMacroScratchRegisterUsage allowScratch(jit);
     
    22792284            // FIXME: We should support more than one memory size register
    22802285            //   see: https://bugs.webkit.org/show_bug.cgi?id=162952
    2281             ASSERT(pinnedRegs.sizeRegister != newContextInstance);
    2282             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;
    2283 
    2284             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
     2286            ASSERT(pinnedRegs.boundsCheckingSizeRegister != newContextInstance);
     2287            GPRReg scratchOrBoundsCheckingSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.boundsCheckingSizeRegister;
     2288
     2289            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Bound checking size.
    22852290            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
    22862291
    2287             jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
     2292            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratchOrBoundsCheckingSize);
    22882293        });
    22892294
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r269694 r269940  
    326326    Value* m_framePointer { nullptr };
    327327    GPRReg m_memoryBaseGPR { InvalidGPRReg };
    328     GPRReg m_memorySizeGPR { InvalidGPRReg };
     328    GPRReg m_boundsCheckingSizeGPR { InvalidGPRReg };
    329329    GPRReg m_wasmContextInstanceGPR { InvalidGPRReg };
    330330    bool m_makesCalls { false };
     
    409409
    410410    if (mode != MemoryMode::Signaling) {
    411         m_memorySizeGPR = pinnedRegs.sizeRegister;
    412         m_proc.pinRegister(m_memorySizeGPR);
     411        m_boundsCheckingSizeGPR = pinnedRegs.boundsCheckingSizeRegister;
     412        m_proc.pinRegister(m_boundsCheckingSizeGPR);
    413413    }
    414414
     
    418418            switch (m_mode) {
    419419            case MemoryMode::BoundsChecking:
    420                 ASSERT_UNUSED(pinnedGPR, m_memorySizeGPR == pinnedGPR);
     420                ASSERT_UNUSED(pinnedGPR, m_boundsCheckingSizeGPR == pinnedGPR);
    421421                break;
    422422            case MemoryMode::Signaling:
     
    546546        RegisterSet clobbers;
    547547        clobbers.set(pinnedRegs->baseMemoryPointer);
    548         clobbers.set(pinnedRegs->sizeRegister);
     548        clobbers.set(pinnedRegs->boundsCheckingSizeRegister);
    549549        if (!isARM64())
    550550            clobbers.set(RegisterSet::macroScratchRegisters());
     
    562562            AllowMacroScratchRegisterUsage allowScratch(jit);
    563563            GPRReg baseMemory = pinnedRegs->baseMemoryPointer;
    564             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;
    565 
    566             jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemorySize()), pinnedRegs->sizeRegister);
     564            GPRReg scratchOrBoundsCheckingSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->boundsCheckingSizeRegister;
     565
     566            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs->boundsCheckingSizeRegister);
    567567            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory);
    568568
    569             jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->sizeRegister, scratchOrSize);
     569            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->boundsCheckingSizeRegister, scratchOrBoundsCheckingSize);
    570570        });
    571571    }
     
    794794{
    795795    static_assert(sizeof(decltype(static_cast<Memory*>(nullptr)->size())) == sizeof(uint64_t), "codegen relies on this size");
    796     Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfCachedMemorySize()));
     796    Value* memory = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfMemory()));
     797    Value* handle = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), memory, safeCast<int32_t>(Memory::offsetOfHandle()));
     798    Value* size = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), handle, safeCast<int32_t>(MemoryHandle::offsetOfSize()));
    797799
    798800    constexpr uint32_t shiftValue = 16;
     
    955957    case MemoryMode::BoundsChecking: {
    956958        // We're not using signal handling at all, we must therefore check that no memory access exceeds the current memory size.
    957         ASSERT(m_memorySizeGPR);
     959        ASSERT(m_boundsCheckingSizeGPR);
    958960        ASSERT(sizeOfOperation + offset > offset);
    959         m_currentBlock->appendNew<WasmBoundsCheckValue>(m_proc, origin(), m_memorySizeGPR, pointer, sizeOfOperation + offset - 1);
     961        m_currentBlock->appendNew<WasmBoundsCheckValue>(m_proc, origin(), m_boundsCheckingSizeGPR, pointer, sizeOfOperation + offset - 1);
    960962        break;
    961963    }
     
    17111713                // We need to clobber the size register since the LLInt always bounds checks
    17121714                if (m_mode == MemoryMode::Signaling)
    1713                     patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().sizeRegister });
     1715                    patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().boundsCheckingSizeRegister });
    17141716                patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
    17151717                    AllowMacroScratchRegisterUsage allowScratch(jit);
     
    18321834            jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit()));
    18331835            jit.storeWasmContextInstance(newContextInstance);
    1834             ASSERT(pinnedRegs.sizeRegister != baseMemory);
     1836            ASSERT(pinnedRegs.boundsCheckingSizeRegister != baseMemory);
    18351837            // FIXME: We should support more than one memory size register
    18361838            //   see: https://bugs.webkit.org/show_bug.cgi?id=162952
    1837             ASSERT(pinnedRegs.sizeRegister != newContextInstance);
    1838             GPRReg scratchOrSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;
    1839 
    1840             jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
     1839            ASSERT(pinnedRegs.boundsCheckingSizeRegister != newContextInstance);
     1840            GPRReg scratchOrBoundsCheckingSize = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.boundsCheckingSizeRegister;
     1841
     1842            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Memory size.
    18411843            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
    18421844
    1843             jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
     1845            jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratchOrBoundsCheckingSize);
    18441846        });
    18451847        doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation);
  • trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp

    r265186 r269940  
    5050    ASSERT(baseMemory != GPRReg::InvalidGPRReg);
    5151    ASSERT(baseMemory != scratch);
    52     ASSERT(pinnedRegs.sizeRegister != baseMemory);
    53     ASSERT(pinnedRegs.sizeRegister != scratch);
    54     GPRReg sizeRegAsScratch = pinnedRegs.sizeRegister;
     52    ASSERT(pinnedRegs.boundsCheckingSizeRegister != baseMemory);
     53    ASSERT(pinnedRegs.boundsCheckingSizeRegister != scratch);
     54    GPRReg sizeRegAsScratch = pinnedRegs.boundsCheckingSizeRegister;
    5555    ASSERT(sizeRegAsScratch != GPRReg::InvalidGPRReg);
    5656
     
    6969    // Set up the callee's baseMemory register as well as the memory size registers.
    7070    {
    71         GPRReg scratchOrSize = !Gigacage::isEnabled(Gigacage::Primitive) ? pinnedRegs.sizeRegister : wasmCallingConvention().prologueScratchGPRs[1];
     71        GPRReg scratchOrBoundsCheckingSize = !Gigacage::isEnabled(Gigacage::Primitive) ? pinnedRegs.boundsCheckingSizeRegister : wasmCallingConvention().prologueScratchGPRs[1];
    7272
    73         jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister); // Memory size.
     73        jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Bound checking size.
    7474        jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedMemory()), baseMemory); // Wasm::Memory::TaggedArrayStoragePtr<void> (void*).
    75         jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.sizeRegister, scratchOrSize);
     75        jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratchOrBoundsCheckingSize);
    7676    }
    7777
  • trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp

    r269694 r269940  
    5353static bool fastHandlerInstalled { false };
    5454
    55 #if ENABLE(WEBASSEMBLY_FAST_MEMORY)
     55#if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    5656
    5757static SignalAction trapHandler(Signal, SigInfo& sigInfo, PlatformRegisters& context)
     
    6464
    6565    dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "JIT memory start: ", RawPointer(startOfFixedExecutableMemoryPool()), " end: ", RawPointer(endOfFixedExecutableMemoryPool()));
    66     // First we need to make sure we are in JIT code before we can aquire any locks. Otherwise,
     66    dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "WasmLLInt memory start: ", RawPointer(untagCodePtr<void*, CFunctionPtrTag>(LLInt::wasmLLIntPCRangeStart)), " end: ", RawPointer(untagCodePtr<void*, CFunctionPtrTag>(LLInt::wasmLLIntPCRangeEnd)));
     67    // First we need to make sure we are in JIT code or Wasm LLInt code before we can aquire any locks. Otherwise,
    6768    // we might have crashed in code that is already holding one of the locks we want to aquire.
    6869    assertIsNotTagged(faultingInstruction);
    69     if (isJITPC(faultingInstruction)) {
    70         bool faultedInActiveFastMemory = false;
     70    if (isJITPC(faultingInstruction) || LLInt::isWasmLLIntPC(faultingInstruction)) {
     71        bool faultedInActiveGrowableMemory = false;
    7172        {
    7273            void* faultingAddress = sigInfo.faultingAddress;
    7374            dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "checking faulting address: ", RawPointer(faultingAddress), " is in an active fast memory");
    74             faultedInActiveFastMemory = Wasm::Memory::addressIsInActiveFastMemory(faultingAddress);
     75            faultedInActiveGrowableMemory = Wasm::Memory::addressIsInGrowableOrFastMemory(faultingAddress);
    7576        }
    76         if (faultedInActiveFastMemory) {
     77        if (faultedInActiveGrowableMemory) {
    7778            dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found active fast memory for faulting address");
    78             auto& calleeRegistry = CalleeRegistry::singleton();
    79             auto locker = holdLock(calleeRegistry.getLock());
    80             for (auto* callee : calleeRegistry.allCallees(locker)) {
    81                 auto [start, end] = callee->range();
    82                 dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end));
    83                 if (start <= faultingInstruction && faultingInstruction < end) {
    84                     dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found match");
    85                     MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(static_cast<uintptr_t>(Wasm::Context::useFastTLS()));
    86                     MachineContext::setInstructionPointer(context, LLInt::getCodePtr<CFunctionPtrTag>(wasm_throw_from_fault_handler_trampoline));
    87                     return SignalAction::Handled;
     79
     80            auto didFaultInWasm = [](void* faultingInstruction) {
     81                if (LLInt::isWasmLLIntPC(faultingInstruction))
     82                    return true;
     83                auto& calleeRegistry = CalleeRegistry::singleton();
     84                auto locker = holdLock(calleeRegistry.getLock());
     85                for (auto* callee : calleeRegistry.allCallees(locker)) {
     86                    auto [start, end] = callee->range();
     87                    dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end));
     88                    if (start <= faultingInstruction && faultingInstruction < end) {
     89                        dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found match");
     90                        return true;
     91                    }
    8892                }
     93                return false;
     94            };
     95
     96            if (didFaultInWasm(faultingInstruction)) {
     97                MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(static_cast<uintptr_t>(Wasm::Context::useFastTLS()));
     98                MachineContext::setInstructionPointer(context, LLInt::getCodePtr<CFunctionPtrTag>(wasm_throw_from_fault_handler_trampoline));
     99                return SignalAction::Handled;
    89100            }
    90101        }
     
    93104}
    94105
    95 #endif // ENABLE(WEBASSEMBLY_FAST_MEMORY)
     106#endif // ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    96107
    97108bool fastMemoryEnabled()
     
    102113void enableFastMemory()
    103114{
    104 #if ENABLE(WEBASSEMBLY_FAST_MEMORY)
     115#if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    105116    static std::once_flag once;
    106117    std::call_once(once, [] {
     
    108119            return;
    109120
    110         if (!Options::useWebAssemblyFastMemory())
     121        if (!Options::useWebAssemblyFastMemory() && !Options::useSharedArrayBuffer())
    111122            return;
    112123
     
    120131void prepareFastMemory()
    121132{
    122 #if ENABLE(WEBASSEMBLY_FAST_MEMORY)
     133#if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    123134    static std::once_flag once;
    124135    std::call_once(once, [] {
     
    126137            return;
    127138
    128         if (!Options::useWebAssemblyFastMemory())
     139        if (!Options::useWebAssemblyFastMemory() && !Options::useSharedArrayBuffer())
    129140            return;
    130141
     
    133144        });
    134145    });
    135 #endif // ENABLE(WEBASSEMBLY_FAST_MEMORY)
     146#endif // ENABLE(WEBASSEMBLY_SIGNALING_MEMORY)
    136147}
    137148   
  • trunk/Source/JavaScriptCore/wasm/WasmInstance.h

    r253987 r269940  
    7878    void setTable(unsigned, Ref<Table>&&);
    7979
    80     void* cachedMemory() const { return m_cachedMemory.getMayBeNull(cachedMemorySize()); }
    81     size_t cachedMemorySize() const { return m_cachedMemorySize; }
     80    void* cachedMemory() const { return m_cachedMemory.getMayBeNull(cachedBoundsCheckingSize()); }
     81    size_t cachedBoundsCheckingSize() const { return m_cachedBoundsCheckingSize; }
    8282
    8383    void setMemory(Ref<Memory>&& memory)
     
    9090    {
    9191        if (m_memory != nullptr) {
    92             m_cachedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>(memory()->memory(), memory()->size());
    93             m_cachedMemorySize = memory()->size();
     92            m_cachedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>(memory()->memory(), memory()->boundsCheckingSize());
     93            m_cachedBoundsCheckingSize = memory()->boundsCheckingSize();
    9494        }
    9595    }
     
    147147    static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(Instance, m_globals); }
    148148    static ptrdiff_t offsetOfCachedMemory() { return OBJECT_OFFSETOF(Instance, m_cachedMemory); }
    149     static ptrdiff_t offsetOfCachedMemorySize() { return OBJECT_OFFSETOF(Instance, m_cachedMemorySize); }
     149    static ptrdiff_t offsetOfCachedBoundsCheckingSize() { return OBJECT_OFFSETOF(Instance, m_cachedBoundsCheckingSize); }
    150150    static ptrdiff_t offsetOfPointerToTopEntryFrame() { return OBJECT_OFFSETOF(Instance, m_pointerToTopEntryFrame); }
    151151
     
    202202    Context* m_context { nullptr };
    203203    CagedPtr<Gigacage::Primitive, void, tagCagedPtr> m_cachedMemory;
    204     size_t m_cachedMemorySize { 0 };
     204    size_t m_cachedBoundsCheckingSize { 0 };
    205205    Ref<Module> m_module;
    206206    RefPtr<CodeBlock> m_codeBlock;
  • trunk/Source/JavaScriptCore/wasm/WasmMemory.cpp

    r261755 r269940  
    3737#include <wtf/PrintStream.h>
    3838#include <wtf/RAMSize.h>
     39#include <wtf/StdSet.h>
    3940#include <wtf/Vector.h>
    4041
     
    134135        dataLogLnIf(Options::logWebAssemblyMemory(), "Freed virtual; state: ", *this);
    135136    }
    136    
    137     bool isAddressInFastMemory(void* address)
    138     {
    139         // NOTE: This can be called from a signal handler, but only after we proved that we're in JIT code.
     137
     138    MemoryResult tryAllocateGrowableBoundsCheckingMemory(size_t mappedCapacity)
     139    {
     140        MemoryResult result = [&] {
     141            auto holder = holdLock(m_lock);
     142            void* result = Gigacage::tryAllocateZeroedVirtualPages(Gigacage::Primitive, mappedCapacity);
     143            if (!result)
     144                return MemoryResult(nullptr, MemoryResult::SyncTryToReclaimMemory);
     145
     146            m_growableBoundsCheckingMemories.insert(std::make_pair(bitwise_cast<uintptr_t>(result), mappedCapacity));
     147
     148            return MemoryResult(result, MemoryResult::Success);
     149        }();
     150
     151        dataLogLnIf(Options::logWebAssemblyMemory(), "Allocated virtual: ", result, "; state: ", *this);
     152
     153        return result;
     154    }
     155
     156    void freeGrowableBoundsCheckingMemory(void* basePtr, size_t mappedCapacity)
     157    {
     158        {
     159            auto holder = holdLock(m_lock);
     160            Gigacage::freeVirtualPages(Gigacage::Primitive, basePtr, mappedCapacity);
     161            m_growableBoundsCheckingMemories.erase(std::make_pair(bitwise_cast<uintptr_t>(basePtr), mappedCapacity));
     162        }
     163
     164        dataLogLnIf(Options::logWebAssemblyMemory(), "Freed virtual; state: ", *this);
     165    }
     166
     167    bool isInGrowableOrFastMemory(void* address)
     168    {
     169        // NOTE: This can be called from a signal handler, but only after we proved that we're in JIT code or WasmLLInt code.
    140170        auto holder = holdLock(m_lock);
    141171        for (void* memory : m_fastMemories) {
    142172            char* start = static_cast<char*>(memory);
    143173            if (start <= address && address <= start + Memory::fastMappedBytes())
     174                return true;
     175        }
     176        uintptr_t addressValue = bitwise_cast<uintptr_t>(address);
     177        auto iterator = std::upper_bound(m_growableBoundsCheckingMemories.begin(), m_growableBoundsCheckingMemories.end(), std::make_pair(addressValue, 0),
     178            [](std::pair<uintptr_t, size_t> a, std::pair<uintptr_t, size_t> b) {
     179                return (a.first + a.second) < (b.first + b.second);
     180            });
     181        if (iterator != m_growableBoundsCheckingMemories.end()) {
     182            // Since we never have overlapped range in m_growableBoundsCheckingMemories, just checking one lower-bound range is enough.
     183            if (iterator->first <= addressValue && addressValue < (iterator->first + iterator->second))
    144184                return true;
    145185        }
     
    193233    unsigned m_maxFastMemoryCount { 0 };
    194234    Vector<void*> m_fastMemories;
     235    StdSet<std::pair<uintptr_t, size_t>> m_growableBoundsCheckingMemories;
    195236    size_t m_physicalBytes { 0 };
    196237};
     
    236277} // anonymous namespace
    237278
    238 Memory::Memory()
    239 {
    240 }
    241 
    242 Memory::Memory(PageCount initial, PageCount maximum, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
    243     : m_initial(initial)
    244     , m_maximum(maximum)
    245     , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
    246     , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
    247     , m_growSuccessCallback(WTFMove(growSuccessCallback))
    248 {
    249     ASSERT(!initial.bytes());
    250     ASSERT(m_mode == MemoryMode::BoundsChecking);
    251     dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
    252     ASSERT(!memory());
    253 }
    254 
    255 Memory::Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode mode, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
    256     : m_memory(memory, initial.bytes())
    257     , m_size(initial.bytes())
     279
     280MemoryHandle::MemoryHandle(void* memory, size_t size, size_t mappedCapacity, PageCount initial, PageCount maximum, MemorySharingMode sharingMode, MemoryMode mode)
     281    : m_memory(memory, mappedCapacity)
     282    , m_size(size)
     283    , m_mappedCapacity(mappedCapacity)
    258284    , m_initial(initial)
    259285    , m_maximum(maximum)
    260     , m_mappedCapacity(mappedCapacity)
     286    , m_sharingMode(sharingMode)
    261287    , m_mode(mode)
    262     , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
    263     , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
    264     , m_growSuccessCallback(WTFMove(growSuccessCallback))
    265 {
    266     dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
    267 }
    268 
    269 Ref<Memory> Memory::create()
    270 {
    271     return adoptRef(*new Memory());
    272 }
    273 
    274 RefPtr<Memory> Memory::tryCreate(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
    275 {
    276     ASSERT(initial);
    277     RELEASE_ASSERT(!maximum || maximum >= initial); // This should be guaranteed by our caller.
    278 
    279     const size_t initialBytes = initial.bytes();
    280     const size_t maximumBytes = maximum ? maximum.bytes() : 0;
    281 
    282     if (initialBytes > MAX_ARRAY_BUFFER_SIZE)
    283         return nullptr; // Client will throw OOMError.
    284 
    285     if (maximum && !maximumBytes) {
    286         // User specified a zero maximum, initial size must also be zero.
    287         RELEASE_ASSERT(!initialBytes);
    288         return adoptRef(new Memory(initial, maximum, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
    289     }
    290    
    291     bool done = tryAllocate(
    292         [&] () -> MemoryResult::Kind {
    293             return memoryManager().tryAllocatePhysicalBytes(initialBytes);
    294         }, notifyMemoryPressure, syncTryToReclaimMemory);
    295     if (!done)
    296         return nullptr;
    297        
    298     char* fastMemory = nullptr;
    299     if (Options::useWebAssemblyFastMemory()) {
    300         tryAllocate(
    301             [&] () -> MemoryResult::Kind {
    302                 auto result = memoryManager().tryAllocateFastMemory();
    303                 fastMemory = bitwise_cast<char*>(result.basePtr);
    304                 return result.kind;
    305             }, notifyMemoryPressure, syncTryToReclaimMemory);
    306     }
    307    
    308     if (fastMemory) {
    309        
    310         if (mprotect(fastMemory + initialBytes, Memory::fastMappedBytes() - initialBytes, PROT_NONE)) {
    311             dataLog("mprotect failed: ", strerror(errno), "\n");
    312             RELEASE_ASSERT_NOT_REACHED();
    313         }
    314 
    315         return adoptRef(new Memory(fastMemory, initial, maximum, Memory::fastMappedBytes(), MemoryMode::Signaling, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
    316     }
    317    
    318     if (UNLIKELY(Options::crashIfWebAssemblyCantFastMemory()))
    319         webAssemblyCouldntGetFastMemory();
    320 
    321     if (!initialBytes)
    322         return adoptRef(new Memory(initial, maximum, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
    323    
    324     void* slowMemory = Gigacage::tryAllocateZeroedVirtualPages(Gigacage::Primitive, initialBytes);
    325     if (!slowMemory) {
    326         memoryManager().freePhysicalBytes(initialBytes);
    327         return nullptr;
    328     }
    329     return adoptRef(new Memory(slowMemory, initial, maximum, initialBytes, MemoryMode::BoundsChecking, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
    330 }
    331 
    332 Memory::~Memory()
     288{
     289#if ASSERT_ENABLED
     290    if (sharingMode == MemorySharingMode::Default && mode == MemoryMode::BoundsChecking)
     291        ASSERT(mappedCapacity == size);
     292#endif
     293}
     294
     295MemoryHandle::~MemoryHandle()
    333296{
    334297    if (m_memory) {
     
    342305            memoryManager().freeFastMemory(memory());
    343306            break;
    344         case MemoryMode::BoundsChecking:
    345             Gigacage::freeVirtualPages(Gigacage::Primitive, memory(), m_size);
     307        case MemoryMode::BoundsChecking: {
     308            switch (m_sharingMode) {
     309            case MemorySharingMode::Default:
     310                Gigacage::freeVirtualPages(Gigacage::Primitive, memory(), m_size);
     311                break;
     312            case MemorySharingMode::Shared: {
     313                if (mprotect(memory(), m_mappedCapacity, PROT_READ | PROT_WRITE)) {
     314                    dataLog("mprotect failed: ", strerror(errno), "\n");
     315                    RELEASE_ASSERT_NOT_REACHED();
     316                }
     317                memoryManager().freeGrowableBoundsCheckingMemory(memory(), m_mappedCapacity);
     318                break;
     319            }
     320            }
    346321            break;
    347322        }
    348     }
    349 }
     323        }
     324    }
     325}
     326
     327Memory::Memory()
     328    : m_handle(adoptRef(*new MemoryHandle(nullptr, 0, 0, PageCount(0), PageCount(0), MemorySharingMode::Default, MemoryMode::BoundsChecking)))
     329{
     330}
     331
     332Memory::Memory(PageCount initial, PageCount maximum, MemorySharingMode sharingMode, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     333    : m_handle(adoptRef(*new MemoryHandle(nullptr, 0, 0, initial, maximum, sharingMode, MemoryMode::BoundsChecking)))
     334    , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
     335    , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
     336    , m_growSuccessCallback(WTFMove(growSuccessCallback))
     337{
     338    ASSERT(!initial.bytes());
     339    ASSERT(mode() == MemoryMode::BoundsChecking);
     340    dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
     341    ASSERT(!memory());
     342}
     343
     344Memory::Memory(Ref<MemoryHandle>&& handle, Function<void(NotifyPressure)>&& notifyMemoryPressure, Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     345    : m_handle(WTFMove(handle))
     346    , m_notifyMemoryPressure(WTFMove(notifyMemoryPressure))
     347    , m_syncTryToReclaimMemory(WTFMove(syncTryToReclaimMemory))
     348    , m_growSuccessCallback(WTFMove(growSuccessCallback))
     349{
     350    dataLogLnIf(verbose, "Memory::Memory allocating ", *this);
     351}
     352
     353Ref<Memory> Memory::create()
     354{
     355    return adoptRef(*new Memory());
     356}
     357
     358Ref<Memory> Memory::create(Ref<MemoryHandle>&& handle, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     359{
     360    return adoptRef(*new Memory(WTFMove(handle), WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     361}
     362
     363RefPtr<Memory> Memory::tryCreate(PageCount initial, PageCount maximum, MemorySharingMode sharingMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback)
     364{
     365    ASSERT(initial);
     366    RELEASE_ASSERT(!maximum || maximum >= initial); // This should be guaranteed by our caller.
     367
     368    const size_t initialBytes = initial.bytes();
     369    const size_t maximumBytes = maximum ? maximum.bytes() : 0;
     370
     371    if (initialBytes > MAX_ARRAY_BUFFER_SIZE)
     372        return nullptr; // Client will throw OOMError.
     373
     374    if (maximum && !maximumBytes) {
     375        // User specified a zero maximum, initial size must also be zero.
     376        RELEASE_ASSERT(!initialBytes);
     377        return adoptRef(new Memory(initial, maximum, sharingMode, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     378    }
     379   
     380    bool done = tryAllocate(
     381        [&] () -> MemoryResult::Kind {
     382            return memoryManager().tryAllocatePhysicalBytes(initialBytes);
     383        }, notifyMemoryPressure, syncTryToReclaimMemory);
     384    if (!done)
     385        return nullptr;
     386       
     387    char* fastMemory = nullptr;
     388    if (Options::useWebAssemblyFastMemory()) {
     389        tryAllocate(
     390            [&] () -> MemoryResult::Kind {
     391                auto result = memoryManager().tryAllocateFastMemory();
     392                fastMemory = bitwise_cast<char*>(result.basePtr);
     393                return result.kind;
     394            }, notifyMemoryPressure, syncTryToReclaimMemory);
     395    }
     396   
     397    if (fastMemory) {
     398        if (mprotect(fastMemory + initialBytes, Memory::fastMappedBytes() - initialBytes, PROT_NONE)) {
     399            dataLog("mprotect failed: ", strerror(errno), "\n");
     400            RELEASE_ASSERT_NOT_REACHED();
     401        }
     402
     403        return Memory::create(adoptRef(*new MemoryHandle(fastMemory, initialBytes, Memory::fastMappedBytes(), initial, maximum, sharingMode, MemoryMode::Signaling)), WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback));
     404    }
     405   
     406    if (UNLIKELY(Options::crashIfWebAssemblyCantFastMemory()))
     407        webAssemblyCouldntGetFastMemory();
     408
     409    if (!initialBytes)
     410        return adoptRef(new Memory(initial, maximum, sharingMode, WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback)));
     411
     412    switch (sharingMode) {
     413    case MemorySharingMode::Default: {
     414        void* slowMemory = Gigacage::tryAllocateZeroedVirtualPages(Gigacage::Primitive, initialBytes);
     415        if (!slowMemory) {
     416            memoryManager().freePhysicalBytes(initialBytes);
     417            return nullptr;
     418        }
     419        return Memory::create(adoptRef(*new MemoryHandle(slowMemory, initialBytes, initialBytes, initial, maximum, sharingMode, MemoryMode::BoundsChecking)), WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback));
     420    }
     421    case MemorySharingMode::Shared: {
     422        char* slowMemory = nullptr;
     423        tryAllocate(
     424            [&] () -> MemoryResult::Kind {
     425                auto result = memoryManager().tryAllocateGrowableBoundsCheckingMemory(maximumBytes);
     426                slowMemory = bitwise_cast<char*>(result.basePtr);
     427                return result.kind;
     428            }, notifyMemoryPressure, syncTryToReclaimMemory);
     429        if (!slowMemory) {
     430            memoryManager().freePhysicalBytes(initialBytes);
     431            return nullptr;
     432        }
     433
     434        if (mprotect(slowMemory + initialBytes, maximumBytes - initialBytes, PROT_NONE)) {
     435            dataLog("mprotect failed: ", strerror(errno), "\n");
     436            RELEASE_ASSERT_NOT_REACHED();
     437        }
     438
     439        return Memory::create(adoptRef(*new MemoryHandle(slowMemory, initialBytes, maximumBytes, initial, maximum, sharingMode, MemoryMode::BoundsChecking)), WTFMove(notifyMemoryPressure), WTFMove(syncTryToReclaimMemory), WTFMove(growSuccessCallback));
     440    }
     441    }
     442    RELEASE_ASSERT_NOT_REACHED();
     443    return nullptr;
     444}
     445
     446Memory::~Memory() = default;
    350447
    351448size_t Memory::fastMappedRedzoneBytes()
     
    360457}
    361458
    362 bool Memory::addressIsInActiveFastMemory(void* address)
    363 {
    364     return memoryManager().isAddressInFastMemory(address);
     459bool Memory::addressIsInGrowableOrFastMemory(void* address)
     460{
     461    return memoryManager().isInGrowableOrFastMemory(address);
     462}
     463
     464Expected<PageCount, Memory::GrowFailReason> Memory::growShared(PageCount delta)
     465{
     466    Wasm::PageCount oldPageCount;
     467    Wasm::PageCount newPageCount;
     468    auto result = ([&]() -> Expected<PageCount, Memory::GrowFailReason> {
     469        auto locker = holdLock(m_handle->lock());
     470
     471        oldPageCount = sizeInPages();
     472        newPageCount = oldPageCount + delta;
     473        if (!newPageCount || !newPageCount.isValid())
     474            return makeUnexpected(GrowFailReason::InvalidGrowSize);
     475        if (newPageCount.bytes() > MAX_ARRAY_BUFFER_SIZE)
     476            return makeUnexpected(GrowFailReason::OutOfMemory);
     477
     478        if (!delta.pageCount())
     479            return oldPageCount;
     480
     481        dataLogLnIf(verbose, "Memory::grow(", delta, ") to ", newPageCount, " from ", *this);
     482        RELEASE_ASSERT(newPageCount > PageCount::fromBytes(size()));
     483
     484        if (maximum() && newPageCount > maximum())
     485            return makeUnexpected(GrowFailReason::WouldExceedMaximum);
     486
     487        size_t desiredSize = newPageCount.bytes();
     488        RELEASE_ASSERT(desiredSize <= MAX_ARRAY_BUFFER_SIZE);
     489        RELEASE_ASSERT(desiredSize > size());
     490
     491        // If the memory is MemorySharingMode::Shared, we already allocated enough virtual address space even if the memory is bound-checking mode. We perform mprotect to extend.
     492        size_t extraBytes = desiredSize - size();
     493        RELEASE_ASSERT(extraBytes);
     494        bool allocationSuccess = tryAllocate(
     495            [&] () -> MemoryResult::Kind {
     496                return memoryManager().tryAllocatePhysicalBytes(extraBytes);
     497            }, [](Wasm::Memory::NotifyPressure) { }, [](Memory::SyncTryToReclaim) { });
     498        if (!allocationSuccess)
     499            return makeUnexpected(GrowFailReason::OutOfMemory);
     500
     501        RELEASE_ASSERT(memory());
     502
     503        // Signaling memory must have been pre-allocated virtually.
     504        uint8_t* startAddress = static_cast<uint8_t*>(memory()) + size();
     505
     506        dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(memory()), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")");
     507        if (mprotect(startAddress, extraBytes, PROT_READ | PROT_WRITE)) {
     508            dataLog("mprotect failed: ", strerror(errno), "\n");
     509            RELEASE_ASSERT_NOT_REACHED();
     510        }
     511
     512        m_handle->growToSize(desiredSize);
     513        return oldPageCount;
     514    }());
     515    if (result)
     516        m_growSuccessCallback(GrowSuccessTag, oldPageCount, newPageCount);
     517    return result;
    365518}
    366519
    367520Expected<PageCount, Memory::GrowFailReason> Memory::grow(PageCount delta)
    368521{
    369     const Wasm::PageCount oldPageCount = sizeInPages();
    370 
    371522    if (!delta.isValid())
    372523        return makeUnexpected(GrowFailReason::InvalidDelta);
    373    
     524
     525    if (sharingMode() == MemorySharingMode::Shared)
     526        return growShared(delta);
     527
     528    const Wasm::PageCount oldPageCount = sizeInPages();
    374529    const Wasm::PageCount newPageCount = oldPageCount + delta;
    375530    if (!newPageCount || !newPageCount.isValid())
     
    392547
    393548    dataLogLnIf(verbose, "Memory::grow(", delta, ") to ", newPageCount, " from ", *this);
    394     RELEASE_ASSERT(newPageCount > PageCount::fromBytes(m_size));
     549    RELEASE_ASSERT(newPageCount > PageCount::fromBytes(size()));
    395550
    396551    if (maximum() && newPageCount > maximum())
     
    399554    size_t desiredSize = newPageCount.bytes();
    400555    RELEASE_ASSERT(desiredSize <= MAX_ARRAY_BUFFER_SIZE);
    401     RELEASE_ASSERT(desiredSize > m_size);
    402     size_t extraBytes = desiredSize - m_size;
    403     RELEASE_ASSERT(extraBytes);
    404     bool allocationSuccess = tryAllocate(
    405         [&] () -> MemoryResult::Kind {
    406             return memoryManager().tryAllocatePhysicalBytes(extraBytes);
    407         }, m_notifyMemoryPressure, m_syncTryToReclaimMemory);
    408     if (!allocationSuccess)
    409         return makeUnexpected(GrowFailReason::OutOfMemory);
    410 
     556    RELEASE_ASSERT(desiredSize > size());
    411557    switch (mode()) {
    412558    case MemoryMode::BoundsChecking: {
     559        bool allocationSuccess = tryAllocate(
     560            [&] () -> MemoryResult::Kind {
     561                return memoryManager().tryAllocatePhysicalBytes(desiredSize);
     562            }, m_notifyMemoryPressure, m_syncTryToReclaimMemory);
     563        if (!allocationSuccess)
     564            return makeUnexpected(GrowFailReason::OutOfMemory);
     565
    413566        RELEASE_ASSERT(maximum().bytes() != 0);
    414567
     
    417570            return makeUnexpected(GrowFailReason::OutOfMemory);
    418571
    419         memcpy(newMemory, memory(), m_size);
    420         if (m_memory)
    421             Gigacage::freeVirtualPages(Gigacage::Primitive, memory(), m_size);
    422         m_memory = CagedMemory(newMemory, desiredSize);
    423         m_mappedCapacity = desiredSize;
    424         m_size = desiredSize;
     572        memcpy(newMemory, memory(), size());
     573        auto newHandle = adoptRef(*new MemoryHandle(newMemory, desiredSize, desiredSize, initial(), maximum(), sharingMode(), MemoryMode::BoundsChecking));
     574        m_handle = WTFMove(newHandle);
     575
    425576        ASSERT(memory() == newMemory);
    426577        return success();
    427578    }
    428579    case MemoryMode::Signaling: {
     580        size_t extraBytes = desiredSize - size();
     581        RELEASE_ASSERT(extraBytes);
     582        bool allocationSuccess = tryAllocate(
     583            [&] () -> MemoryResult::Kind {
     584                return memoryManager().tryAllocatePhysicalBytes(extraBytes);
     585            }, m_notifyMemoryPressure, m_syncTryToReclaimMemory);
     586        if (!allocationSuccess)
     587            return makeUnexpected(GrowFailReason::OutOfMemory);
     588
    429589        RELEASE_ASSERT(memory());
     590
    430591        // Signaling memory must have been pre-allocated virtually.
    431         uint8_t* startAddress = static_cast<uint8_t*>(memory()) + m_size;
     592        uint8_t* startAddress = static_cast<uint8_t*>(memory()) + size();
    432593       
    433594        dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(memory()), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")");
     
    436597            RELEASE_ASSERT_NOT_REACHED();
    437598        }
    438         m_memory.recage(m_size, desiredSize);
    439         m_size = desiredSize;
     599
     600        m_handle->growToSize(desiredSize);
    440601        return success();
    441602    }
     
    460621void Memory::dump(PrintStream& out) const
    461622{
    462     out.print("Memory at ", RawPointer(memory()), ", size ", m_size, "B capacity ", m_mappedCapacity, "B, initial ", m_initial, " maximum ", m_maximum, " mode ", makeString(m_mode));
     623    auto handle = m_handle.copyRef();
     624    out.print("Memory at ", RawPointer(handle->memory()), ", size ", handle->size(), "B capacity ", handle->mappedCapacity(), "B, initial ", handle->initial(), " maximum ", handle->maximum(), " mode ", makeString(handle->mode()), " sharingMode ", makeString(handle->sharingMode()));
    463625}
    464626
  • trunk/Source/JavaScriptCore/wasm/WasmMemory.h

    r246368 r269940  
    4545namespace JSC {
    4646
     47class LLIntOffsetsExtractor;
     48
    4749namespace Wasm {
    4850
    4951class Instance;
    5052
    51 class Memory : public RefCounted<Memory> {
     53class MemoryHandle final : public ThreadSafeRefCounted<MemoryHandle> {
     54    WTF_MAKE_NONCOPYABLE(MemoryHandle);
     55    WTF_MAKE_FAST_ALLOCATED;
     56    friend LLIntOffsetsExtractor;
     57public:
     58    MemoryHandle(void*, size_t size, size_t mappedCapacity, PageCount initial, PageCount maximum, MemorySharingMode, MemoryMode);
     59    JS_EXPORT_PRIVATE ~MemoryHandle();
     60
     61    void* memory() const { ASSERT(m_memory.getMayBeNull(m_mappedCapacity) == m_memory.getUnsafe()); return m_memory.getMayBeNull(m_mappedCapacity); }
     62    size_t size() const { return m_size; }
     63    size_t mappedCapacity() const { return m_mappedCapacity; }
     64    PageCount initial() const { return m_initial; }
     65    PageCount maximum() const { return m_maximum; }
     66    MemorySharingMode sharingMode() const { return m_sharingMode; }
     67    MemoryMode mode() const { return m_mode; }
     68    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(MemoryHandle, m_size); }
     69    Lock& lock() { return m_lock; }
     70
     71    void growToSize(size_t size)
     72    {
     73        m_size = size;
     74    }
     75
     76private:
     77    using CagedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>;
     78    CagedMemory m_memory;
     79    size_t m_size { 0 };
     80    size_t m_mappedCapacity { 0 };
     81    PageCount m_initial;
     82    PageCount m_maximum;
     83    MemorySharingMode m_sharingMode { MemorySharingMode::Default };
     84    MemoryMode m_mode { MemoryMode::BoundsChecking };
     85    Lock m_lock;
     86};
     87
     88class Memory final : public RefCounted<Memory> {
    5289    WTF_MAKE_NONCOPYABLE(Memory);
    5390    WTF_MAKE_FAST_ALLOCATED;
     91    friend LLIntOffsetsExtractor;
    5492public:
    5593    void dump(WTF::PrintStream&) const;
    5694
    57     explicit operator bool() const { return !!m_memory; }
     95    explicit operator bool() const { return !!m_handle->memory(); }
    5896   
    5997    enum NotifyPressure { NotifyPressureTag };
     
    62100
    63101    static Ref<Memory> create();
    64     static RefPtr<Memory> tryCreate(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
     102    JS_EXPORT_PRIVATE static Ref<Memory> create(Ref<MemoryHandle>&&, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
     103    static RefPtr<Memory> tryCreate(PageCount initial, PageCount maximum, MemorySharingMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
    65104
    66     ~Memory();
     105    JS_EXPORT_PRIVATE ~Memory();
    67106
    68107    static size_t fastMappedRedzoneBytes();
    69108    static size_t fastMappedBytes(); // Includes redzone.
    70     static bool addressIsInActiveFastMemory(void*);
     109    static bool addressIsInGrowableOrFastMemory(void*);
    71110
    72     void* memory() const { ASSERT(m_memory.getMayBeNull(size()) == m_memory.getUnsafe()); return m_memory.getMayBeNull(size()); }
    73     size_t size() const { return m_size; }
    74     PageCount sizeInPages() const { return PageCount::fromBytes(m_size); }
     111    void* memory() const { return m_handle->memory(); }
     112    size_t size() const { return m_handle->size(); }
     113    PageCount sizeInPages() const { return PageCount::fromBytes(size()); }
     114    size_t boundsCheckingSize() const { return m_handle->mappedCapacity(); }
     115    PageCount initial() const { return m_handle->initial(); }
     116    PageCount maximum() const { return m_handle->maximum(); }
     117    MemoryHandle& handle() { return m_handle.get(); }
    75118
    76     PageCount initial() const { return m_initial; }
    77     PageCount maximum() const { return m_maximum; }
    78 
    79     MemoryMode mode() const { return m_mode; }
     119    MemorySharingMode sharingMode() const { return m_handle->sharingMode(); }
     120    MemoryMode mode() const { return m_handle->mode(); }
    80121
    81122    enum class GrowFailReason {
     
    90131    void check() {  ASSERT(!deletionHasBegun()); }
    91132
    92     static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Memory, m_memory); }
    93     static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Memory, m_size); }
     133    static ptrdiff_t offsetOfHandle() { return OBJECT_OFFSETOF(Memory, m_handle); }
    94134
    95135private:
    96136    Memory();
    97     Memory(void* memory, PageCount initial, PageCount maximum, size_t mappedCapacity, MemoryMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
    98     Memory(PageCount initial, PageCount maximum, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
     137    Memory(Ref<MemoryHandle>&&, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
     138    Memory(PageCount initial, PageCount maximum, MemorySharingMode, WTF::Function<void(NotifyPressure)>&& notifyMemoryPressure, WTF::Function<void(SyncTryToReclaim)>&& syncTryToReclaimMemory, WTF::Function<void(GrowSuccess, PageCount, PageCount)>&& growSuccessCallback);
    99139
    100     using CagedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>;
    101     CagedMemory m_memory;
    102     size_t m_size { 0 };
    103     PageCount m_initial;
    104     PageCount m_maximum;
    105     size_t m_mappedCapacity { 0 };
    106     MemoryMode m_mode { MemoryMode::BoundsChecking };
     140    Expected<PageCount, GrowFailReason> growShared(PageCount);
     141
     142    Ref<MemoryHandle> m_handle;
    107143    WTF::Function<void(NotifyPressure)> m_notifyMemoryPressure;
    108144    WTF::Function<void(SyncTryToReclaim)> m_syncTryToReclaimMemory;
     
    120156public:
    121157    static size_t maxFastMemoryCount() { return 0; }
    122     static bool addressIsInActiveFastMemory(void*) { return false; }
     158    static bool addressIsInGrowableOrFastMemory(void*) { return false; }
    123159};
    124160
  • trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp

    r261755 r269940  
    4343            ++numberOfPinnedRegisters;
    4444        GPRReg baseMemoryPointer = GPRInfo::regCS3;
    45         GPRReg sizeRegister = GPRInfo::regCS4;
     45        GPRReg boundsCheckingSizeRegister = GPRInfo::regCS4;
    4646        GPRReg wasmContextInstancePointer = InvalidGPRReg;
    4747        if (!Context::useFastTLS())
    4848            wasmContextInstancePointer = GPRInfo::regCS0;
    4949
    50         staticPinnedRegisterInfo.construct(sizeRegister, baseMemoryPointer, wasmContextInstancePointer);
     50        staticPinnedRegisterInfo.construct(boundsCheckingSizeRegister, baseMemoryPointer, wasmContextInstancePointer);
    5151    });
    5252
     
    5454}
    5555
    56 PinnedRegisterInfo::PinnedRegisterInfo(GPRReg sizeRegister, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer)
    57     : sizeRegister(sizeRegister)
     56PinnedRegisterInfo::PinnedRegisterInfo(GPRReg boundsCheckingSizeRegister, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer)
     57    : boundsCheckingSizeRegister(boundsCheckingSizeRegister)
    5858    , baseMemoryPointer(baseMemoryPointer)
    5959    , wasmContextInstancePointer(wasmContextInstancePointer)
  • trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.h

    r243886 r269940  
    4040
    4141struct PinnedSizeRegisterInfo {
    42     GPRReg sizeRegister;
     42    GPRReg boundsCheckingSizeRegister;
    4343    unsigned sizeOffset;
    4444};
     
    5757            result.set(wasmContextInstancePointer);
    5858        if (mode != MemoryMode::Signaling)
    59             result.set(sizeRegister);
     59            result.set(boundsCheckingSizeRegister);
    6060        return result;
    6161    }
    6262
    63     GPRReg sizeRegister;
     63    GPRReg boundsCheckingSizeRegister;
    6464    GPRReg baseMemoryPointer;
    6565    GPRReg wasmContextInstancePointer;
  • trunk/Source/JavaScriptCore/wasm/WasmMemoryMode.cpp

    r223738 r269940  
    4343}
    4444
     45const char* makeString(MemorySharingMode sharingMode)
     46{
     47    switch (sharingMode) {
     48    case MemorySharingMode::Default: return "Default";
     49    case MemorySharingMode::Shared: return "Shared";
     50    }
     51    RELEASE_ASSERT_NOT_REACHED();
     52    return "";
     53}
     54
    4555} } // namespace JSC::Wasm
    4656
  • trunk/Source/JavaScriptCore/wasm/WasmMemoryMode.h

    r225028 r269940  
    4141JS_EXPORT_PRIVATE const char* makeString(MemoryMode);
    4242
     43enum class MemorySharingMode : uint8_t {
     44    Default,
     45    Shared,
     46};
     47
     48JS_EXPORT_PRIVATE const char* makeString(MemorySharingMode);
     49
    4350} } // namespace JSC::Wasm
    4451
  • trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp

    r269552 r269940  
    222222    if (!!info.memory) {
    223223        GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
    224         GPRReg scratchOrSize = wasmCallingConvention().prologueScratchGPRs[0];
     224        GPRReg scratchOrBoundsCheckingSize = wasmCallingConvention().prologueScratchGPRs[0];
    225225
    226226        if (Context::useFastTLS())
     
    230230        if (isARM64E()) {
    231231            if (mode != Wasm::MemoryMode::Signaling)
    232                 scratchOrSize = pinnedRegs.sizeRegister;
    233             jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratchOrSize);
     232                scratchOrBoundsCheckingSize = pinnedRegs.boundsCheckingSizeRegister;
     233            jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), scratchOrBoundsCheckingSize);
    234234        } else {
    235235            if (mode != Wasm::MemoryMode::Signaling)
    236                 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister);
     236                jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister);
    237237        }
    238238
    239239        jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory);
    240         jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);
     240        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrBoundsCheckingSize, scratchOrBoundsCheckingSize);
    241241    }
    242242
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

    r261755 r269940  
    292292            RETURN_IF_EXCEPTION(throwScope, nullptr);
    293293
    294             RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(moduleInformation.memory.initial(), moduleInformation.memory.maximum(),
     294            RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(moduleInformation.memory.initial(), moduleInformation.memory.maximum(), Wasm::MemorySharingMode::Default,
    295295                [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); },
    296296                [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); },
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp

    r269343 r269940  
    3333#include "ArrayBuffer.h"
    3434#include "JSArrayBuffer.h"
     35#include "ObjectConstructor.h"
    3536
    3637namespace JSC {
     
    7374}
    7475
    75 JSArrayBuffer* JSWebAssemblyMemory::buffer(VM& vm, JSGlobalObject* globalObject)
     76JSArrayBuffer* JSWebAssemblyMemory::buffer(JSGlobalObject* globalObject)
    7677{
    77     if (m_bufferWrapper)
    78         return m_bufferWrapper.get();
     78    VM& vm = globalObject->vm();
     79    auto throwScope = DECLARE_THROW_SCOPE(vm);
    7980
    80     // We can't use a ref here since it doesn't have a copy constructor...
    81     Ref<Wasm::Memory> protectedMemory = m_memory.get();
    82     auto destructor = createSharedTask<void(void*)>([protectedMemory = WTFMove(protectedMemory)] (void*) { });
     81    auto* wrapper = m_bufferWrapper.get();
     82    if (wrapper) {
     83        if (m_memory->sharingMode() == Wasm::MemorySharingMode::Default)
     84            return wrapper;
     85
     86        ASSERT(m_memory->sharingMode() == Wasm::MemorySharingMode::Shared);
     87        // If SharedArrayBuffer's underlying memory is not grown, we continue using cached wrapper.
     88        if (wrapper->impl()->byteLength() == memory().size())
     89            return wrapper;
     90    }
     91
     92    Ref<Wasm::MemoryHandle> protectedHandle = m_memory->handle();
     93    auto destructor = createSharedTask<void(void*)>([protectedHandle = WTFMove(protectedHandle)] (void*) { });
    8394    m_buffer = ArrayBuffer::createFromBytes(memory().memory(), memory().size(), WTFMove(destructor));
    8495    m_buffer->makeWasmMemory();
    85     m_bufferWrapper.set(vm, this, JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), m_buffer.get()));
     96    if (m_memory->sharingMode() == Wasm::MemorySharingMode::Shared)
     97        m_buffer->makeShared();
     98    auto* arrayBuffer = JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(m_buffer->sharingMode()), m_buffer.get());
     99    if (m_memory->sharingMode() == Wasm::MemorySharingMode::Shared) {
     100        objectConstructorFreeze(globalObject, arrayBuffer);
     101        RETURN_IF_EXCEPTION(throwScope, { });
     102    }
     103    m_bufferWrapper.set(vm, this, arrayBuffer);
    86104    RELEASE_ASSERT(m_bufferWrapper);
    87105    return m_bufferWrapper.get();
     
    118136    // We need to clear out the old array buffer because it might now be pointing to stale memory.
    119137    if (m_buffer) {
    120         m_buffer->detach(vm);
     138        if (m_memory->sharingMode() == Wasm::MemorySharingMode::Default)
     139            m_buffer->detach(vm);
    121140        m_buffer = nullptr;
    122141        m_bufferWrapper.clear();
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h

    r253121 r269940  
    2828#if ENABLE(WEBASSEMBLY)
    2929
    30 #include "JSDestructibleObject.h"
     30#include "JSObject.h"
    3131#include "WasmMemory.h"
    3232#include <wtf/Ref.h>
     
    5050    }
    5151
    52     static JSWebAssemblyMemory* tryCreate(JSGlobalObject*, VM&, Structure*);
     52    JS_EXPORT_PRIVATE static JSWebAssemblyMemory* tryCreate(JSGlobalObject*, VM&, Structure*);
    5353    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    5454
    5555    DECLARE_EXPORT_INFO;
    5656
    57     void adopt(Ref<Wasm::Memory>&&);
     57    JS_EXPORT_PRIVATE void adopt(Ref<Wasm::Memory>&&);
    5858    Wasm::Memory& memory() { return m_memory.get(); }
    59     JSArrayBuffer* buffer(VM& vm, JSGlobalObject*);
     59    JSArrayBuffer* buffer(JSGlobalObject*);
    6060    Wasm::PageCount grow(VM&, JSGlobalObject*, uint32_t delta);
    61     void growSuccessCallback(VM&, Wasm::PageCount oldPageCount, Wasm::PageCount newPageCount);
     61    JS_EXPORT_PRIVATE void growSuccessCallback(VM&, Wasm::PageCount oldPageCount, Wasm::PageCount newPageCount);
    6262
    6363private:
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r269552 r269940  
    358358    if (!!moduleInformation.memory) {
    359359        GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
    360         GPRReg scratchOrSize = stackLimitGPR;
     360        GPRReg scratchOrBoundsCheckingSize = stackLimitGPR;
    361361        auto mode = instance()->memoryMode();
    362362
    363363        if (isARM64E()) {
    364364            if (mode != Wasm::MemoryMode::Signaling)
    365                 scratchOrSize = pinnedRegs.sizeRegister;
    366             jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), scratchOrSize);
     365                scratchOrBoundsCheckingSize = pinnedRegs.boundsCheckingSizeRegister;
     366            jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), scratchOrBoundsCheckingSize);
    367367        } else {
    368368            if (mode != Wasm::MemoryMode::Signaling)
    369                 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemorySize()), pinnedRegs.sizeRegister);
     369                jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister);
    370370        }
    371371
    372372        jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory);
    373         jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrSize, scratchOrSize);
     373        jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrBoundsCheckingSize, scratchOrBoundsCheckingSize);
    374374    }
    375375
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp

    r267594 r269940  
    5757    VM& vm = globalObject->vm();
    5858    auto throwScope = DECLARE_THROW_SCOPE(vm);
    59     if (callFrame->argumentCount() != 1)
    60         return JSValue::encode(throwException(globalObject, throwScope, createTypeError(globalObject, "WebAssembly.Memory expects exactly one argument"_s)));
    6159
    6260    JSObject* memoryDescriptor;
     
    103101    }
    104102
     103    Wasm::MemorySharingMode sharingMode = Wasm::MemorySharingMode::Default;
     104    JSValue sharedValue = memoryDescriptor->get(globalObject, Identifier::fromString(vm, "shared"));
     105    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     106    bool shared = sharedValue.toBoolean(globalObject);
     107    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     108    if (shared) {
     109        if (!maximumPageCount)
     110            return throwVMTypeError(globalObject, throwScope, "'maximum' page count must be defined if 'shared' is true"_s);
     111        if (!Options::useSharedArrayBuffer())
     112            return throwVMTypeError(globalObject, throwScope, "Shared WebAssembly.Memory and SharedArrayBuffer are not enabled"_s);
     113        sharingMode = Wasm::MemorySharingMode::Shared;
     114    }
     115
    105116    auto* jsMemory = JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure());
    106117    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    107118
    108     RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(initialPageCount, maximumPageCount,
     119    RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(initialPageCount, maximumPageCount, sharingMode,
    109120        [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); },
    110121        [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); },
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp

    r267594 r269940  
    9494    JSWebAssemblyMemory* memory = getMemory(globalObject, vm, callFrame->thisValue());
    9595    RETURN_IF_EXCEPTION(throwScope, { });
    96     return JSValue::encode(memory->buffer(globalObject->vm(), globalObject));
     96    RELEASE_AND_RETURN(throwScope, JSValue::encode(memory->buffer(globalObject)));
    9797}
    9898
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

    r269552 r269940  
    567567
    568568    auto forEachSegment = [&] (auto fn) {
    569         uint8_t* memory = reinterpret_cast<uint8_t*>(m_instance->instance().cachedMemory());
    570         uint64_t sizeInBytes = m_instance->instance().cachedMemorySize();
     569        auto wasmMemory = m_instance->instance().memory();
     570        uint8_t* memory = reinterpret_cast<uint8_t*>(wasmMemory->memory());
     571        uint64_t sizeInBytes = wasmMemory->size();
    571572
    572573        for (const Wasm::Segment::Ptr& segment : data) {
  • trunk/Source/WTF/wtf/PlatformEnable.h

    r269775 r269940  
    691691
    692692#if ENABLE(WEBASSEMBLY) && HAVE(MACHINE_CONTEXT)
    693 #define ENABLE_WEBASSEMBLY_FAST_MEMORY 1
     693#define ENABLE_WEBASSEMBLY_SIGNALING_MEMORY 1
    694694#endif
    695695
  • trunk/Source/WebCore/ChangeLog

    r269938 r269940  
     12020-11-16  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement WebAssembly.Memory with shared
     4        https://bugs.webkit.org/show_bug.cgi?id=218693
     5
     6        Reviewed by Saam Barati.
     7
     8        In WebCore, we need three things.
     9
     10        1. Shared WebAssembly.Memory serialization/deserialization
     11
     12            This patch adds structure-cloning for WebAssembly.Memory to pass it to the other workers. Cloning is available
     13            only when the WebAssembly.Memory is shared mode. And it is only available when we are using it in postMessage.
     14            So we cannot store WebAssembly.Memory in IndexedDB.
     15
     16        2. WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread
     17
     18            Atomics.wait is usable only in Workers, and *not* usable in Service Workers. When creating VM, we pass WorkerThreadType
     19            and make WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread return appropriate value.
     20
     21        3. [AllowShared] support for WPT
     22
     23            WPT tests for this are broken, and tests are saying "PASS" while the feature is not implemented at all.
     24            Now, the feature is actually implemented, and WPT tests start showing that [AllowShared] annotation in IDL
     25            is not implemented. [AllowShared] is that, usually, DOM does not accept TypedArray originated from SharedArrayBuffer.
     26            e.g. encodeInto(..., Uint8Array) DOM IDL throws an error if Uint8Array is backed by SharedArrayBuffer.
     27            But in the limited places, we are explicitly allowing this. This is [AllowShared] annotation.
     28            This patch implements that so that we keep passing TextEncoder / TextDecoder tests.
     29
     30        * Headers.cmake:
     31        * Modules/indexeddb/server/IDBSerializationContext.cpp:
     32        (WebCore::IDBServer::IDBSerializationContext::initializeVM):
     33        * WebCore.xcodeproj/project.pbxproj:
     34        * bindings/IDLTypes.h:
     35        * bindings/js/CommonVM.cpp:
     36        (WebCore::commonVMSlow):
     37        * bindings/js/JSDOMConvertBufferSource.h:
     38        (WebCore::Detail::BufferSourceConverter::convert):
     39        (WebCore::Converter<IDLArrayBuffer>::convert):
     40        (WebCore::Converter<IDLDataView>::convert):
     41        (WebCore::Converter<IDLInt8Array>::convert):
     42        (WebCore::Converter<IDLInt16Array>::convert):
     43        (WebCore::Converter<IDLInt32Array>::convert):
     44        (WebCore::Converter<IDLUint8Array>::convert):
     45        (WebCore::Converter<IDLUint16Array>::convert):
     46        (WebCore::Converter<IDLUint32Array>::convert):
     47        (WebCore::Converter<IDLUint8ClampedArray>::convert):
     48        (WebCore::Converter<IDLFloat32Array>::convert):
     49        (WebCore::Converter<IDLFloat64Array>::convert):
     50        (WebCore::Converter<IDLArrayBufferView>::convert):
     51        (WebCore::Converter<IDLAllowSharedAdaptor<T>>::convert):
     52        * bindings/js/JSDOMConvertUnion.h:
     53        * bindings/js/SerializedScriptValue.cpp:
     54        (WebCore::CloneSerializer::serialize):
     55        (WebCore::CloneSerializer::CloneSerializer):
     56        (WebCore::CloneSerializer::dumpIfTerminal):
     57        (WebCore::CloneDeserializer::deserialize):
     58        (WebCore::CloneDeserializer::CloneDeserializer):
     59        (WebCore::CloneDeserializer::readTerminal):
     60        (WebCore::SerializedScriptValue::SerializedScriptValue):
     61        (WebCore::SerializedScriptValue::computeMemoryCost const):
     62        (WebCore::SerializedScriptValue::create):
     63        (WebCore::SerializedScriptValue::deserialize):
     64        * bindings/js/SerializedScriptValue.h:
     65        * bindings/js/WebCoreJSClientData.cpp:
     66        (WebCore::JSVMClientData::initNormalWorld):
     67        * bindings/js/WebCoreJSClientData.h:
     68        * bindings/js/WebCoreTypedArrayController.cpp:
     69        (WebCore::WebCoreTypedArrayController::WebCoreTypedArrayController):
     70        (WebCore::WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread):
     71        * bindings/js/WebCoreTypedArrayController.h:
     72        * bindings/scripts/CodeGeneratorJS.pm:
     73        (IsAnnotatedType):
     74        (GetAnnotatedIDLType):
     75        * bindings/scripts/IDLAttributes.json:
     76        * bindings/scripts/test/JS/JSTestObj.cpp:
     77        (WebCore::JSTestObjDOMConstructor::construct):
     78        (WebCore::jsTestObjPrototypeFunction_encodeIntoBody):
     79        (WebCore::JSC_DEFINE_HOST_FUNCTION):
     80        * bindings/scripts/test/TestObj.idl:
     81        * dom/TextDecoder.idl:
     82        * dom/TextDecoderStreamDecoder.idl:
     83        * dom/TextEncoder.idl:
     84        * workers/DedicatedWorkerGlobalScope.cpp:
     85        (WebCore::DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope):
     86        * workers/WorkerGlobalScope.cpp:
     87        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
     88        * workers/WorkerGlobalScope.h:
     89        * workers/WorkerOrWorkletGlobalScope.cpp:
     90        (WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
     91        * workers/WorkerOrWorkletGlobalScope.h:
     92        * workers/WorkerOrWorkletScriptController.cpp:
     93        (WebCore::WorkerOrWorkletScriptController::WorkerOrWorkletScriptController):
     94        * workers/WorkerOrWorkletScriptController.h:
     95        * workers/WorkerThreadType.h: Added.
     96        * workers/service/ServiceWorkerGlobalScope.cpp:
     97        (WebCore::ServiceWorkerGlobalScope::ServiceWorkerGlobalScope):
     98        * worklets/WorkletGlobalScope.cpp:
     99        (WebCore::WorkletGlobalScope::WorkletGlobalScope):
     100
    11012020-11-17  Zalan Bujtas  <zalan@apple.com>
    2102
  • trunk/Source/WebCore/Headers.cmake

    r269907 r269940  
    15771577    workers/WorkerScriptLoaderClient.h
    15781578    workers/WorkerThread.h
     1579    workers/WorkerThreadType.h
    15791580    workers/WorkerType.h
    15801581
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp

    r268700 r269940  
    8080    m_vm = JSC::VM::create();
    8181    m_vm->heap.acquireAccess();
    82     JSVMClientData::initNormalWorld(m_vm.get());
     82    JSVMClientData::initNormalWorld(m_vm.get(), WorkerThreadType::Worklet);
    8383
    8484    JSC::JSLockHolder locker(m_vm.get());
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r269937 r269940  
    50275027                E3A776671DC85D2800B690D8 /* DOMJITIDLConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A776651DC85D2200B690D8 /* DOMJITIDLConvert.h */; settings = {ATTRIBUTES = (Private, ); }; };
    50285028                E3A776681DC85D2800B690D8 /* DOMJITIDLType.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A776661DC85D2200B690D8 /* DOMJITIDLType.h */; settings = {ATTRIBUTES = (Private, ); }; };
     5029                E3AFD7AD255F50EB00E5E30E /* WorkerThreadType.h in Headers */ = {isa = PBXBuildFile; fileRef = E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */; settings = {ATTRIBUTES = (Private, ); }; };
    50295030                E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
    50305031                E3B2F0EE1D7F4CA900B0C9D1 /* LoadableScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1607216073                E3AE6CD12252F27000C70B50 /* AllDescendantsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllDescendantsCollection.cpp; sourceTree = "<group>"; };
    1607316074                E3AFA9641DA6E908002861BD /* JSNodeDOMJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNodeDOMJIT.cpp; sourceTree = "<group>"; };
     16075                E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WorkerThreadType.h; sourceTree = "<group>"; };
    1607416076                E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableClassicScript.cpp; sourceTree = "<group>"; };
    1607516077                E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableClassicScript.h; sourceTree = "<group>"; };
     
    1904819050                                2E4346420F546A8200B0F1BA /* WorkerThread.cpp */,
    1904919051                                2E4346430F546A8200B0F1BA /* WorkerThread.h */,
     19052                                E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */,
    1905019053                                51F174FC1F35898800C74950 /* WorkerType.h */,
    1905119054                                51F174FA1F3588D700C74950 /* WorkerType.idl */,
     
    3519635199                                0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */,
    3519735200                                97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */,
     35201                                E3AFD7AD255F50EB00E5E30E /* WorkerThreadType.h in Headers */,
    3519835202                                A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */,
    3519935203                                51F174FE1F35899200C74950 /* WorkerType.h in Headers */,
  • trunk/Source/WebCore/bindings/IDLTypes.h

    r266662 r269940  
    152152};
    153153
     154template<typename T> struct IDLAllowSharedAdaptor : T {
     155    using InnerType = T;
     156};
     157
    154158struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> {
    155159    using NullableType = JSC::Strong<JSC::JSObject>;
     
    324328struct IsIDLTypedArray : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLTypedArray, T>::value> { };
    325329
     330template<typename T>
     331struct IsIDLArrayBuffer : public std::integral_constant<bool, std::is_base_of<IDLArrayBuffer, T>::value> { };
     332
     333template<typename T>
     334struct IsIDLArrayBufferView : public std::integral_constant<bool, std::is_base_of<IDLArrayBufferView, T>::value> { };
     335
     336template<typename T>
     337struct IsIDLArrayBufferAllowShared : public std::integral_constant<bool, std::is_base_of<IDLAllowSharedAdaptor<IDLArrayBuffer>, T>::value> { };
     338
     339template<typename T>
     340struct IsIDLArrayBufferViewAllowShared : public std::integral_constant<bool, std::is_base_of<IDLAllowSharedAdaptor<IDLArrayBufferView>, T>::value> { };
     341
     342
    326343} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/CommonVM.cpp

    r266355 r269940  
    8989    vm.setGlobalConstRedeclarationShouldThrow(globalConstRedeclarationShouldThrow());
    9090
    91     JSVMClientData::initNormalWorld(&vm);
     91    JSVMClientData::initNormalWorld(&vm, WorkerThreadType::Main);
    9292
    9393    return vm;
  • trunk/Source/WebCore/bindings/js/JSDOMConvertBufferSource.h

    r266533 r269940  
    110110namespace Detail {
    111111
    112 template<typename BufferSourceType>
     112enum class BufferSourceConverterAllowSharedMode { Allow, Disallow };
     113template<typename BufferSourceType, BufferSourceConverterAllowSharedMode mode>
    113114struct BufferSourceConverter {
    114115    using WrapperType = typename Converter<BufferSourceType>::WrapperType;
     
    120121        auto& vm = JSC::getVM(&lexicalGlobalObject);
    121122        auto scope = DECLARE_THROW_SCOPE(vm);
    122         ReturnType object = WrapperType::toWrapped(vm, value);
     123        ReturnType object { };
     124        if constexpr (mode == BufferSourceConverterAllowSharedMode::Allow)
     125            object = WrapperType::toWrappedAllowShared(vm, value);
     126        else
     127            object = WrapperType::toWrapped(vm, value);
    123128        if (UNLIKELY(!object))
    124129            exceptionThrower(lexicalGlobalObject, scope);
     
    136141    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    137142    {
    138         return Detail::BufferSourceConverter<IDLArrayBuffer>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     143        return Detail::BufferSourceConverter<IDLArrayBuffer, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    139144    }
    140145};
     
    158163    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    159164    {
    160         return Detail::BufferSourceConverter<IDLDataView>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     165        return Detail::BufferSourceConverter<IDLDataView, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    161166    }
    162167};
     
    180185    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    181186    {
    182         return Detail::BufferSourceConverter<IDLInt8Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     187        return Detail::BufferSourceConverter<IDLInt8Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    183188    }
    184189};
     
    202207    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    203208    {
    204         return Detail::BufferSourceConverter<IDLInt16Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     209        return Detail::BufferSourceConverter<IDLInt16Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    205210    }
    206211};
     
    224229    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    225230    {
    226         return Detail::BufferSourceConverter<IDLInt32Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     231        return Detail::BufferSourceConverter<IDLInt32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    227232    }
    228233};
     
    246251    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    247252    {
    248         return Detail::BufferSourceConverter<IDLUint8Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     253        return Detail::BufferSourceConverter<IDLUint8Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    249254    }
    250255};
     
    274279    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    275280    {
    276         return Detail::BufferSourceConverter<IDLUint16Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     281        return Detail::BufferSourceConverter<IDLUint16Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    277282    }
    278283};
     
    296301    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    297302    {
    298         return Detail::BufferSourceConverter<IDLUint32Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     303        return Detail::BufferSourceConverter<IDLUint32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    299304    }
    300305};
     
    318323    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    319324    {
    320         return Detail::BufferSourceConverter<IDLUint8ClampedArray>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     325        return Detail::BufferSourceConverter<IDLUint8ClampedArray, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    321326    }
    322327};
     
    340345    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    341346    {
    342         return Detail::BufferSourceConverter<IDLFloat32Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     347        return Detail::BufferSourceConverter<IDLFloat32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    343348    }
    344349};
     
    362367    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    363368    {
    364         return Detail::BufferSourceConverter<IDLFloat64Array>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     369        return Detail::BufferSourceConverter<IDLFloat64Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    365370    }
    366371};
     
    384389    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
    385390    {
    386         return Detail::BufferSourceConverter<IDLArrayBufferView>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     391        return Detail::BufferSourceConverter<IDLArrayBufferView, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
    387392    }
    388393};
     
    399404};
    400405
     406template<typename T>
     407struct Converter<IDLAllowSharedAdaptor<T>> : DefaultConverter<T> {
     408    using ConverterType = Converter<T>;
     409    using WrapperType = typename ConverterType::WrapperType;
     410    using ReturnType = typename ConverterType::ReturnType;
     411
     412    template<typename ExceptionThrower = DefaultExceptionThrower>
     413    static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
     414    {
     415        return Detail::BufferSourceConverter<T, Detail::BufferSourceConverterAllowSharedMode::Allow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower));
     416    }
     417};
     418
    401419} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/JSDOMConvertUnion.h

    r264751 r269940  
    226226        //     1. If types includes ArrayBuffer, then return the result of converting V to ArrayBuffer.
    227227        //     2. If types includes object, then return the IDL value that is a reference to the object V.
    228         constexpr bool hasArrayBufferType = brigand::any<TypeList, std::is_same<IDLArrayBuffer, brigand::_1>>::value;
     228        constexpr bool hasArrayBufferType = brigand::any<TypeList, IsIDLArrayBuffer<brigand::_1>>::value;
    229229        if (hasArrayBufferType || hasObjectType) {
    230             auto arrayBuffer = JSC::JSArrayBuffer::toWrapped(vm, value);
     230            auto arrayBuffer = (brigand::any<TypeList, IsIDLArrayBufferAllowShared<brigand::_1>>::value) ? JSC::JSArrayBuffer::toWrappedAllowShared(vm, value) : JSC::JSArrayBuffer::toWrapped(vm, value);
    231231            if (arrayBuffer) {
    232232                if (hasArrayBufferType)
     
    236236        }
    237237
    238         constexpr bool hasArrayBufferViewType = brigand::any<TypeList, std::is_same<IDLArrayBufferView, brigand::_1>>::value;
     238        constexpr bool hasArrayBufferViewType = brigand::any<TypeList, IsIDLArrayBufferView<brigand::_1>>::value;
    239239        if (hasArrayBufferViewType || hasObjectType) {
    240             auto arrayBufferView = JSC::JSArrayBufferView::toWrapped(vm, value);
     240            auto arrayBufferView = (brigand::any<TypeList, IsIDLArrayBufferViewAllowShared<brigand::_1>>::value) ? JSC::JSArrayBufferView::toWrappedAllowShared(vm, value) : JSC::JSArrayBufferView::toWrapped(vm, value);
    241241            if (arrayBufferView) {
    242242                if (hasArrayBufferViewType)
     
    406406};
    407407
     408// BufferSource specialization. In WebKit, BufferSource is defined as IDLUnion<IDLArrayBufferView, IDLArrayBuffer> as a hack, and it is not compatible to
     409// annotation described in WebIDL.
     410template<> struct Converter<IDLAllowSharedAdaptor<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>> : DefaultConverter<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>> {
     411    static auto convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) -> decltype(auto)
     412    {
     413        return Converter<IDLUnion<IDLAllowSharedAdaptor<IDLArrayBufferView>, IDLAllowSharedAdaptor<IDLArrayBuffer>>>::convert(lexicalGlobalObject, value);
     414    }
     415};
     416
    408417} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r269381 r269940  
    7676#include <JavaScriptCore/JSSetIterator.h>
    7777#include <JavaScriptCore/JSTypedArrays.h>
     78#include <JavaScriptCore/JSWebAssemblyMemory.h>
    7879#include <JavaScriptCore/JSWebAssemblyModule.h>
    7980#include <JavaScriptCore/ObjectConstructor.h>
     
    183184    BigIntTag = 47,
    184185    BigIntObjectTag = 48,
     186#if ENABLE(WEBASSEMBLY)
     187    WasmMemoryTag = 49,
     188#endif
    185189    ErrorTag = 255
    186190};
     
    358362 *    | ArrayBuffer
    359363 *    | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLength:uint32_t> (ArrayBuffer | ObjectReference)
    360  *    | ArrayBufferTransferTag <value:uint32_t>
    361364 *    | CryptoKeyTag <wrappedKeyLength:uint32_t> <factor:byte{wrappedKeyLength}>
    362365 *    | DOMPoint
     
    368371 *    | ImageBitmapTag <originClean:uint8_t> <logicalWidth:int32_t> <logicalHeight:int32_t> <resolutionScale:double> <byteLength:uint32_t>(<imageByteData:uint8_t>)
    369372 *    | OffscreenCanvasTransferTag <value:uint32_t>
     373 *    | WasmMemoryTag <value:uint32_t>
    370374 *
    371375 * Inside certificate, data is serialized in this format as per spec:
     
    420424 * ArrayBuffer :-
    421425 *    ArrayBufferTag <length:uint32_t> <contents:byte{length}>
     426 *    ArrayBufferTransferTag <value:uint32_t>
     427 *    SharedArrayBufferTag <value:uint32_t>
    422428 *
    423429 * CryptoKeyHMAC :-
     
    577583#if ENABLE(WEBASSEMBLY)
    578584            WasmModuleArray& wasmModules,
     585            WasmMemoryHandleArray& wasmMemoryHandles,
    579586#endif
    580587        Vector<String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
     
    586593#if ENABLE(WEBASSEMBLY)
    587594            wasmModules,
     595            wasmMemoryHandles,
    588596#endif
    589597            blobURLs, out, context, sharedBuffers);
     
    616624#if ENABLE(WEBASSEMBLY)
    617625            WasmModuleArray& wasmModules,
     626            WasmMemoryHandleArray& wasmMemoryHandles,
    618627#endif
    619628        Vector<String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
     
    626635#if ENABLE(WEBASSEMBLY)
    627636        , m_wasmModules(wasmModules)
     637        , m_wasmMemoryHandles(wasmMemoryHandles)
    628638#endif
    629639    {
     
    12311241#if ENABLE(WEBASSEMBLY)
    12321242                WasmModuleArray dummyModules;
     1243                WasmMemoryHandleArray dummyMemoryHandles;
    12331244#endif
    12341245                ArrayBufferContentsArray dummySharedBuffers;
     
    12391250#if ENABLE(WEBASSEMBLY)
    12401251                    dummyModules,
     1252                    dummyMemoryHandles,
    12411253#endif
    12421254                    dummyBlobURLs, serializedKey, SerializationContext::Default, dummySharedBuffers);
     
    12721284                m_wasmModules.append(makeRef(module->module()));
    12731285                write(WasmModuleTag);
     1286                write(index);
     1287                return true;
     1288            }
     1289            if (JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, obj)) {
     1290                if (memory->memory().sharingMode() != JSC::Wasm::MemorySharingMode::Shared) {
     1291                    code = SerializationReturnCode::DataCloneError;
     1292                    return true;
     1293                }
     1294                if (m_context != SerializationContext::WorkerPostMessage) {
     1295                    code = SerializationReturnCode::DataCloneError;
     1296                    return true;
     1297                }
     1298                uint32_t index = m_wasmMemoryHandles.size();
     1299                m_wasmMemoryHandles.append(makeRef(memory->memory().handle()));
     1300                write(WasmMemoryTag);
    12741301                write(index);
    12751302                return true;
     
    16591686#if ENABLE(WEBASSEMBLY)
    16601687    WasmModuleArray& m_wasmModules;
     1688    WasmMemoryHandleArray& m_wasmMemoryHandles;
    16611689#endif
    16621690};
     
    19381966#if ENABLE(WEBASSEMBLY)
    19391967        , WasmModuleArray* wasmModules
     1968        , WasmMemoryHandleArray* wasmMemoryHandles
    19401969#endif
    19411970        )
     
    19491978#if ENABLE(WEBASSEMBLY)
    19501979            , wasmModules
     1980            , wasmMemoryHandles
    19511981#endif
    19521982            );
     
    20022032#if ENABLE(WEBASSEMBLY)
    20032033        , WasmModuleArray* wasmModules = nullptr
     2034        , WasmMemoryHandleArray* wasmMemoryHandles = nullptr
    20042035#endif
    20052036        )
     
    20222053#if ENABLE(WEBASSEMBLY)
    20232054        , m_wasmModules(wasmModules)
     2055        , m_wasmMemoryHandles(wasmMemoryHandles)
    20242056#endif
    20252057    {
     
    20342066#if ENABLE(WEBASSEMBLY)
    20352067        , WasmModuleArray* wasmModules
     2068        , WasmMemoryHandleArray* wasmMemoryHandles
    20362069#endif
    20372070        )
     
    20572090#if ENABLE(WEBASSEMBLY)
    20582091        , m_wasmModules(wasmModules)
     2092        , m_wasmMemoryHandles(wasmMemoryHandles)
    20592093#endif
    20602094    {
     
    33003334            return result;
    33013335        }
     3336        case WasmMemoryTag: {
     3337            uint32_t index;
     3338            bool indexSuccessfullyRead = read(index);
     3339            if (!indexSuccessfullyRead || !m_wasmMemoryHandles || index >= m_wasmMemoryHandles->size()) {
     3340                fail();
     3341                return JSValue();
     3342            }
     3343            RefPtr<Wasm::MemoryHandle> handle = m_wasmMemoryHandles->at(index);
     3344            if (!handle) {
     3345                fail();
     3346                return JSValue();
     3347            }
     3348            auto& vm = m_lexicalGlobalObject->vm();
     3349            auto scope = DECLARE_THROW_SCOPE(vm);
     3350            JSWebAssemblyMemory* result = JSC::JSWebAssemblyMemory::tryCreate(m_lexicalGlobalObject, vm, m_globalObject->webAssemblyMemoryStructure());
     3351            // Since we are cloning a JSWebAssemblyMemory, it's impossible for that
     3352            // module to not have been a valid module. Therefore, createStub should
     3353            // not trow.
     3354            scope.releaseAssertNoException();
     3355            Ref<Wasm::Memory> memory = Wasm::Memory::create(handle.releaseNonNull(),
     3356                [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); },
     3357                [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); },
     3358                [&vm, result] (Wasm::Memory::GrowSuccess, Wasm::PageCount oldPageCount, Wasm::PageCount newPageCount) { result->growSuccessCallback(vm, oldPageCount, newPageCount); });
     3359            result->adopt(WTFMove(memory));
     3360            m_gcBuffer.appendWithCrashOnOverflow(result);
     3361            return result;
     3362        }
    33023363#endif
    33033364        case ArrayBufferTag: {
     
    34403501#if ENABLE(WEBASSEMBLY)
    34413502    WasmModuleArray* m_wasmModules;
     3503    WasmMemoryHandleArray* m_wasmMemoryHandles;
    34423504#endif
    34433505
     
    36623724#if ENABLE(WEBASSEMBLY)
    36633725        , std::unique_ptr<WasmModuleArray> wasmModulesArray
     3726        , std::unique_ptr<WasmMemoryHandleArray> wasmMemoryHandlesArray
    36643727#endif
    36653728        )
     
    36733736#if ENABLE(WEBASSEMBLY)
    36743737    , m_wasmModulesArray(WTFMove(wasmModulesArray))
     3738    , m_wasmMemoryHandlesArray(WTFMove(wasmMemoryHandlesArray))
    36753739#endif
    36763740{
     
    37113775#if ENABLE(WEBASSEMBLY)
    37123776    // We are not supporting WebAssembly Module memory estimation yet.
     3777    if (m_wasmMemoryHandlesArray) {
     3778        for (auto& content : *m_wasmMemoryHandlesArray)
     3779            cost += content->size();
     3780    }
    37133781#endif
    37143782
     
    38013869#if ENABLE(WEBASSEMBLY)
    38023870    WasmModuleArray dummyModules;
     3871    WasmMemoryHandleArray dummyMemoryHandles;
    38033872#endif
    38043873    ArrayBufferContentsArray dummySharedBuffers;
     
    38093878#if ENABLE(WEBASSEMBLY)
    38103879        dummyModules,
     3880        dummyMemoryHandles,
    38113881#endif
    38123882        blobURLs, buffer, SerializationContext::Default, dummySharedBuffers);
     
    38143884#if ENABLE(WEBASSEMBLY)
    38153885    ASSERT_WITH_MESSAGE(dummyModules.isEmpty(), "Wasm::Module serialization is only allowed in the postMessage context");
     3886    ASSERT_WITH_MESSAGE(dummyMemoryHandles.isEmpty(), "Wasm::Memory serialization is only allowed in the postMessage context");
    38163887#endif
    38173888
     
    38603931    for (auto& transferable : transferList) {
    38613932        if (auto arrayBuffer = toPossiblySharedArrayBuffer(vm, transferable.get())) {
    3862             if (arrayBuffer->isDetached())
     3933            if (arrayBuffer->isDetached() || arrayBuffer->isShared())
    38633934                return Exception { DataCloneError };
    38643935            if (arrayBuffer->isLocked()) {
     
    39053976#if ENABLE(WEBASSEMBLY)
    39063977    WasmModuleArray wasmModules;
     3978    WasmMemoryHandleArray wasmMemoryHandles;
    39073979#endif
    39083980    std::unique_ptr<ArrayBufferContentsArray> sharedBuffers = makeUnique<ArrayBufferContentsArray>();
     
    39123984#endif
    39133985#if ENABLE(WEBASSEMBLY)
    3914         wasmModules,
     3986        wasmModules,
     3987        wasmMemoryHandles,
    39153988#endif
    39163989        blobURLs, buffer, context, *sharedBuffers);
     
    39374010#if ENABLE(WEBASSEMBLY)
    39384011                , makeUnique<WasmModuleArray>(wasmModules)
     4012                , context == SerializationContext::WorkerPostMessage ? makeUnique<WasmMemoryHandleArray>(wasmMemoryHandles) : nullptr
    39394013#endif
    39404014                ));
     
    39944068#if ENABLE(WEBASSEMBLY)
    39954069        , m_wasmModulesArray.get()
     4070        , m_wasmMemoryHandlesArray.get()
    39964071#endif
    39974072        );
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.h

    r267615 r269940  
    4242namespace JSC { namespace Wasm {
    4343class Module;
     44class MemoryHandle;
    4445} }
    4546#endif
     
    6263#if ENABLE(WEBASSEMBLY)
    6364using WasmModuleArray = Vector<RefPtr<JSC::Wasm::Module>>;
     65using WasmMemoryHandleArray = Vector<RefPtr<JSC::Wasm::MemoryHandle>>;
    6466#endif
    6567
     
    123125#if ENABLE(WEBASSEMBLY)
    124126        , std::unique_ptr<WasmModuleArray> = nullptr
     127        , std::unique_ptr<WasmMemoryHandleArray> = nullptr
    125128#endif
    126129        );
     
    137140#if ENABLE(WEBASSEMBLY)
    138141    std::unique_ptr<WasmModuleArray> m_wasmModulesArray;
     142    std::unique_ptr<WasmMemoryHandleArray> m_wasmMemoryHandlesArray;
    139143#endif
    140144    Vector<String> m_blobURLs;
  • trunk/Source/WebCore/bindings/js/WebCoreJSClientData.cpp

    r267859 r269940  
    137137}
    138138
    139 void JSVMClientData::initNormalWorld(VM* vm)
     139void JSVMClientData::initNormalWorld(VM* vm, WorkerThreadType type)
    140140{
    141141    JSVMClientData* clientData = new JSVMClientData(*vm);
     
    145145
    146146    clientData->m_normalWorld = DOMWrapperWorld::create(*vm, DOMWrapperWorld::Type::Normal);
    147     vm->m_typedArrayController = adoptRef(new WebCoreTypedArrayController());
     147    vm->m_typedArrayController = adoptRef(new WebCoreTypedArrayController(type == WorkerThreadType::DedicatedWorker || type == WorkerThreadType::Worklet));
    148148}
    149149
  • trunk/Source/WebCore/bindings/js/WebCoreJSClientData.h

    r267859 r269940  
    2525#include "WebCoreBuiltinNames.h"
    2626#include "WebCoreJSBuiltins.h"
     27#include "WorkerThreadType.h"
    2728#include <wtf/HashSet.h>
    2829#include <wtf/RefPtr.h>
     
    4142    virtual ~JSVMClientData();
    4243   
    43     WEBCORE_EXPORT static void initNormalWorld(JSC::VM*);
     44    WEBCORE_EXPORT static void initNormalWorld(JSC::VM*, WorkerThreadType);
    4445
    4546    DOMWrapperWorld& normalWorld() { return *m_normalWorld; }
  • trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.cpp

    r251425 r269940  
    3535namespace WebCore {
    3636
    37 WebCoreTypedArrayController::WebCoreTypedArrayController() = default;
     37WebCoreTypedArrayController::WebCoreTypedArrayController(bool allowAtomicsWait)
     38    : m_allowAtomicsWait(allowAtomicsWait)
     39{
     40}
    3841
    3942WebCoreTypedArrayController::~WebCoreTypedArrayController() = default;
     
    5154bool WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread()
    5255{
    53     return !isMainThread();
     56    return m_allowAtomicsWait;
    5457}
    5558
  • trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.h

    r251425 r269940  
    3737class WebCoreTypedArrayController : public JSC::TypedArrayController {
    3838public:
    39     WebCoreTypedArrayController();
     39    WebCoreTypedArrayController(bool allowAtomicsWait);
    4040    virtual ~WebCoreTypedArrayController();
    4141   
     
    5454
    5555    JSArrayBufferOwner m_owner;
     56    bool m_allowAtomicsWait;
    5657};
    5758
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r269847 r269940  
    70007000    return 1 if $type->extendedAttributes->{AtomString};
    70017001    return 1 if $type->extendedAttributes->{RequiresExistingAtomString};
     7002    return 1 if $type->extendedAttributes->{AllowShared};
    70027003}
    70037004
     
    70117012    return "IDLAtomStringAdaptor" if $type->extendedAttributes->{AtomString};
    70127013    return "IDLRequiresExistingAtomStringAdaptor" if $type->extendedAttributes->{RequiresExistingAtomString};
     7014    return "IDLAllowSharedAdaptor" if $type->extendedAttributes->{AllowShared};
    70137015}
    70147016
  • trunk/Source/WebCore/bindings/scripts/IDLAttributes.json

    r269314 r269940  
    2525            "standard": {
    2626                "url": "https://heycam.github.io/webidl/#AllowShared"
    27             },
    28             "unsupported": true
     27            }
    2928        },
    3029        "AppleCopyright": {
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r268990 r269940  
    16031603static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_double_leading_underscore_function);
    16041604static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_trailing_underscore_function_);
     1605static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_encodeInto);
    16051606static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_toString);
    16061607
     
    23342335    { "_double_leading_underscore_function", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_double_leading_underscore_function), (intptr_t) (0) } },
    23352336    { "trailing_underscore_function_", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_trailing_underscore_function_), (intptr_t) (0) } },
     2337    { "encodeInto", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_encodeInto), (intptr_t) (1) } },
    23362338    { "toString", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_toString), (intptr_t) (0) } },
    23372339#if ENABLE(Condition1)
     
    94989500}
    94999501
     9502static inline JSC::EncodedJSValue jsTestObjPrototypeFunction_encodeIntoBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSTestObj>::ClassParameter castedThis)
     9503{
     9504    auto& vm = JSC::getVM(lexicalGlobalObject);
     9505    auto throwScope = DECLARE_THROW_SCOPE(vm);
     9506    UNUSED_PARAM(throwScope);
     9507    UNUSED_PARAM(callFrame);
     9508    auto& impl = castedThis->wrapped();
     9509    if (UNLIKELY(callFrame->argumentCount() < 1))
     9510        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
     9511    EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
     9512    auto destination = convert<IDLAllowSharedAdaptor<IDLUint8Array>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "destination", "TestObject", "encodeInto", "Uint8Array"); });
     9513    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     9514    RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(impl.encodeInto(destination.releaseNonNull()))));
     9515}
     9516
     9517JSC_DEFINE_HOST_FUNCTION(jsTestObjPrototypeFunction_encodeInto, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
     9518{
     9519    return IDLOperation<JSTestObj>::call<jsTestObjPrototypeFunction_encodeIntoBody>(*lexicalGlobalObject, *callFrame, "encodeInto");
     9520}
     9521
    95009522static inline JSC::EncodedJSValue jsTestObjPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSTestObj>::ClassParameter castedThis)
    95019523{
  • trunk/Source/WebCore/bindings/scripts/test/TestObj.idl

    r268435 r269940  
    468468    undefined __double_leading_underscore_function(); // NOTE: WebIDL removes the leading underscore so this is interpreted as "_double_leading_underscore_function"
    469469    undefined trailing_underscore_function_();
     470
     471    boolean encodeInto([AllowShared] Uint8Array destination);
    470472};
    471473
  • trunk/Source/WebCore/dom/TextDecoder.idl

    r267007 r269940  
    4242    readonly attribute boolean fatal;
    4343    readonly attribute boolean ignoreBOM;
    44     [MayThrowException] USVString decode(optional BufferSource? input, optional TextDecodeOptions options);
     44    [MayThrowException] USVString decode(optional [AllowShared] BufferSource? input, optional TextDecodeOptions options);
    4545};
  • trunk/Source/WebCore/dom/TextDecoderStreamDecoder.idl

    r267007 r269940  
    3333
    3434    [PrivateIdentifier] DOMString encoding();
    35     [PrivateIdentifier, MayThrowException] DOMString decode(BufferSource source);
     35    [PrivateIdentifier, MayThrowException] DOMString decode([AllowShared] BufferSource source);
    3636    [PrivateIdentifier, MayThrowException] DOMString flush();
    3737};
  • trunk/Source/WebCore/dom/TextEncoder.idl

    r266621 r269940  
    4040
    4141    [NewObject] Uint8Array encode(optional USVString input = "");
    42     TextEncoderEncodeIntoResult encodeInto(USVString source, Uint8Array destination);
     42    TextEncoderEncodeIntoResult encodeInto(USVString source, [AllowShared] Uint8Array destination);
    4343};
  • trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp

    r259298 r269940  
    5858
    5959DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, DedicatedWorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    60     : WorkerGlobalScope(params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider)
     60    : WorkerGlobalScope(WorkerThreadType::DedicatedWorker, params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider)
    6161    , m_name(params.name)
    6262{
  • trunk/Source/WebCore/workers/WorkerGlobalScope.cpp

    r268900 r269940  
    6060WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerGlobalScope);
    6161
    62 WorkerGlobalScope::WorkerGlobalScope(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, WorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    63     : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
     62WorkerGlobalScope::WorkerGlobalScope(WorkerThreadType type, const WorkerParameters& params, Ref<SecurityOrigin>&& origin, WorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
     63    : WorkerOrWorkletGlobalScope(type, JSC::VM::create(), &thread)
    6464    , m_url(params.scriptURL)
    6565    , m_identifier(params.identifier)
  • trunk/Source/WebCore/workers/WorkerGlobalScope.h

    r268900 r269940  
    127127
    128128protected:
    129     WorkerGlobalScope(const WorkerParameters&, Ref<SecurityOrigin>&&, WorkerThread&, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
     129    WorkerGlobalScope(WorkerThreadType, const WorkerParameters&, Ref<SecurityOrigin>&&, WorkerThread&, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
    130130
    131131    void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&);
  • trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp

    r269227 r269940  
    3838WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerOrWorkletGlobalScope);
    3939
    40 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread)
    41     : m_script(makeUnique<WorkerOrWorkletScriptController>(WTFMove(vm), this))
     40WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(WorkerThreadType type, Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread)
     41    : m_script(makeUnique<WorkerOrWorkletScriptController>(type, WTFMove(vm), this))
    4242    , m_thread(thread)
    4343    , m_inspectorController(makeUnique<WorkerInspectorController>(*this))
  • trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h

    r268900 r269940  
    2828#include "EventTarget.h"
    2929#include "ScriptExecutionContext.h"
     30#include "WorkerThreadType.h"
    3031
    3132namespace WebCore {
     
    6869
    6970protected:
    70     WorkerOrWorkletGlobalScope(Ref<JSC::VM>&&, WorkerOrWorkletThread*);
     71    WorkerOrWorkletGlobalScope(WorkerThreadType, Ref<JSC::VM>&&, WorkerOrWorkletThread*);
    7172
    7273    // ScriptExecutionContext.
  • trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp

    r268775 r269940  
    5151using namespace JSC;
    5252
    53 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(Ref<VM>&& vm, WorkerOrWorkletGlobalScope* globalScope)
     53WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(WorkerThreadType type, Ref<VM>&& vm, WorkerOrWorkletGlobalScope* globalScope)
    5454    : m_vm(WTFMove(vm))
    5555    , m_globalScope(globalScope)
     
    5757{
    5858    m_vm->heap.acquireAccess(); // It's not clear that we have good discipline for heap access, so turn it on permanently.
    59     JSVMClientData::initNormalWorld(m_vm.get());
    60 }
    61 
    62 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(WorkerOrWorkletGlobalScope* globalScope)
    63     : WorkerOrWorkletScriptController(JSC::VM::create(), globalScope)
     59    JSVMClientData::initNormalWorld(m_vm.get(), type);
     60}
     61
     62WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(WorkerThreadType type, WorkerOrWorkletGlobalScope* globalScope)
     63    : WorkerOrWorkletScriptController(type, JSC::VM::create(), globalScope)
    6464{
    6565}
  • trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h

    r268775 r269940  
    2727#pragma once
    2828
     29#include "WorkerThreadType.h"
    2930#include <JavaScriptCore/Debugger.h>
    3031#include <JavaScriptCore/JSRunLoopTimer.h>
     
    5253    WTF_MAKE_FAST_ALLOCATED;
    5354public:
    54     WorkerOrWorkletScriptController(Ref<JSC::VM>&&, WorkerOrWorkletGlobalScope*);
    55     explicit WorkerOrWorkletScriptController(WorkerOrWorkletGlobalScope*);
     55    WorkerOrWorkletScriptController(WorkerThreadType, Ref<JSC::VM>&&, WorkerOrWorkletGlobalScope*);
     56    explicit WorkerOrWorkletScriptController(WorkerThreadType, WorkerOrWorkletGlobalScope*);
    5657    ~WorkerOrWorkletScriptController();
    5758
  • trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp

    r260350 r269940  
    5353
    5454ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(const ServiceWorkerContextData& data, const WorkerParameters& params, Ref<SecurityOrigin>&& origin, ServiceWorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    55     : WorkerGlobalScope(params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider)
     55    : WorkerGlobalScope(WorkerThreadType::ServiceWorker, params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider)
    5656    , m_contextData(crossThreadCopy(data))
    5757    , m_registration(ServiceWorkerRegistration::getOrCreate(*this, navigator().serviceWorker(), WTFMove(m_contextData.registration)))
  • trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp

    r269221 r269940  
    5151
    5252WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, const WorkletParameters& parameters)
    53     : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
     53    : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, JSC::VM::create(), &thread)
    5454    , m_topOrigin(SecurityOrigin::createUnique())
    5555    , m_url(parameters.windowURL)
     
    6363
    6464WorkletGlobalScope::WorkletGlobalScope(Document& document, Ref<JSC::VM>&& vm, ScriptSourceCode&& code)
    65     : WorkerOrWorkletGlobalScope(WTFMove(vm), nullptr)
     65    : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, WTFMove(vm), nullptr)
    6666    , m_document(makeWeakPtr(document))
    6767    , m_topOrigin(SecurityOrigin::createUnique())
Note: See TracChangeset for help on using the changeset viewer.