Changeset 269940 in webkit
- Timestamp:
- Nov 17, 2020 7:46:39 PM (20 months ago)
- Location:
- trunk
- Files:
-
- 17 added
- 74 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/wasm/function-tests/trap-load-shared.js (added)
-
JSTests/wasm/function-tests/trap-store-shared.js (added)
-
JSTests/wasm/js-api/test_memory.js (modified) (1 diff)
-
JSTests/wasm/stress/shared-memory-errors.js (added)
-
JSTests/wasm/stress/shared-wasm-memory-buffer.js (added)
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/requires-success.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt (modified) (3 diffs)
-
LayoutTests/js/dom/resources (added)
-
LayoutTests/js/dom/resources/webassembly-memory-normal-fail-worker.js (added)
-
LayoutTests/js/dom/resources/webassembly-memory-shared-worker.js (added)
-
LayoutTests/js/dom/webassembly-memory-normal-fail-expected.txt (added)
-
LayoutTests/js/dom/webassembly-memory-normal-fail.html (added)
-
LayoutTests/js/dom/webassembly-memory-shared-basic-expected.txt (added)
-
LayoutTests/js/dom/webassembly-memory-shared-basic.html (added)
-
LayoutTests/js/dom/webassembly-memory-shared-fail-expected.txt (added)
-
LayoutTests/js/dom/webassembly-memory-shared-fail.html (added)
-
LayoutTests/platform/win/TestExpectations (modified) (1 diff)
-
LayoutTests/storage/indexeddb/resources/shared-memory-structured-clone.js (added)
-
LayoutTests/storage/indexeddb/shared-memory-structured-clone-expected.txt (added)
-
LayoutTests/storage/indexeddb/shared-memory-structured-clone.html (added)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntPCRanges.h (modified) (2 diffs)
-
Source/JavaScriptCore/llint/LowLevelInterpreter.asm (modified) (1 diff)
-
Source/JavaScriptCore/llint/WebAssembly.asm (modified) (6 diffs)
-
Source/JavaScriptCore/runtime/JSArrayBuffer.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSArrayBufferView.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/Options.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmBinding.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/wasm/WasmInstance.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmMemory.cpp (modified) (11 diffs)
-
Source/JavaScriptCore/wasm/WasmMemory.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmMemoryInformation.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmMemoryMode.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmMemoryMode.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSToWasm.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (modified) (1 diff)
-
Source/WTF/wtf/PlatformEnable.h (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Headers.cmake (modified) (1 diff)
-
Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/WebCore/bindings/IDLTypes.h (modified) (2 diffs)
-
Source/WebCore/bindings/js/CommonVM.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSDOMConvertBufferSource.h (modified) (15 diffs)
-
Source/WebCore/bindings/js/JSDOMConvertUnion.h (modified) (3 diffs)
-
Source/WebCore/bindings/js/SerializedScriptValue.cpp (modified) (32 diffs)
-
Source/WebCore/bindings/js/SerializedScriptValue.h (modified) (4 diffs)
-
Source/WebCore/bindings/js/WebCoreJSClientData.cpp (modified) (2 diffs)
-
Source/WebCore/bindings/js/WebCoreJSClientData.h (modified) (2 diffs)
-
Source/WebCore/bindings/js/WebCoreTypedArrayController.cpp (modified) (2 diffs)
-
Source/WebCore/bindings/js/WebCoreTypedArrayController.h (modified) (2 diffs)
-
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (modified) (2 diffs)
-
Source/WebCore/bindings/scripts/IDLAttributes.json (modified) (1 diff)
-
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (modified) (3 diffs)
-
Source/WebCore/bindings/scripts/test/TestObj.idl (modified) (1 diff)
-
Source/WebCore/dom/TextDecoder.idl (modified) (1 diff)
-
Source/WebCore/dom/TextDecoderStreamDecoder.idl (modified) (1 diff)
-
Source/WebCore/dom/TextEncoder.idl (modified) (1 diff)
-
Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp (modified) (1 diff)
-
Source/WebCore/workers/WorkerGlobalScope.cpp (modified) (1 diff)
-
Source/WebCore/workers/WorkerGlobalScope.h (modified) (1 diff)
-
Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp (modified) (1 diff)
-
Source/WebCore/workers/WorkerOrWorkletGlobalScope.h (modified) (2 diffs)
-
Source/WebCore/workers/WorkerOrWorkletScriptController.cpp (modified) (2 diffs)
-
Source/WebCore/workers/WorkerOrWorkletScriptController.h (modified) (2 diffs)
-
Source/WebCore/workers/WorkerThreadType.h (added)
-
Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp (modified) (1 diff)
-
Source/WebCore/worklets/WorkletGlobalScope.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r269939 r269940 1 2020-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 1 17 2020-11-17 Yusuke Suzuki <ysuzuki@apple.com> 2 18 -
trunk/JSTests/wasm/js-api/test_memory.js
r217921 r269940 125 125 { 126 126 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}, {}); 128 128 } 129 129 -
trunk/LayoutTests/ChangeLog
r269929 r269940 1 2020-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 1 25 2020-11-17 Sergey Rubanov <chi187@gmail.com> 2 26 -
trunk/LayoutTests/imported/w3c/ChangeLog
r269875 r269940 1 2020-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 1 17 2020-11-16 Alex Christensen <achristensen@webkit.org> 2 18 -
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 1 1 2 FAIL [[CanBlock]] in a DedicatedWorkerGlobalScope Typed array for wait/notify must wrap a SharedArrayBuffer. 2 PASS [[CanBlock]] in a DedicatedWorkerGlobalScope 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any-expected.txt
r269866 r269940 1 1 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 2 PASS Shared memory without maximum 3 PASS Order of evaluation for descriptor (with shared) 4 PASS Shared memory 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor-shared.tentative.any.worker-expected.txt
r269866 r269940 1 1 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 2 PASS Shared memory without maximum 3 PASS Order of evaluation for descriptor (with shared) 4 PASS Shared memory 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any-expected.txt
r269866 r269940 23 23 PASS Zero initial 24 24 PASS Non-zero initial 25 FAIL Stray argument WebAssembly.Memory expects exactly oneargument25 PASS Stray argument 26 26 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/constructor.any.worker-expected.txt
r269866 r269940 23 23 PASS Zero initial 24 24 PASS Non-zero initial 25 FAIL Stray argument WebAssembly.Memory expects exactly oneargument25 PASS Stray argument 26 26 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any-expected.txt
r267649 r269940 18 18 PASS Out-of-range argument: object "[object Object]" 19 19 PASS Stray argument 20 FAIL Growing shared memory does not detach old buffer assert_equals: Buffer before growing: constructor expected true but got false 20 PASS Growing shared memory does not detach old buffer 21 21 -
trunk/LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/memory/grow.any.worker-expected.txt
r267649 r269940 18 18 PASS Out-of-range argument: object "[object Object]" 19 19 PASS Stray argument 20 FAIL Growing shared memory does not detach old buffer assert_equals: Buffer before growing: constructor expected true but got false 20 PASS Growing shared memory does not detach old buffer 21 21 -
trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffer-interface/audiobuffer-copy-channel-expected.txt
r267649 r269940 20 20 PASS 6: buffer.copyFromChannel(x, 0, 16) did not throw an exception. 21 21 PASS 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 22 PASS 8: buffer.copyFromChannel(SharedArrayBuffer view, 0) threw TypeError: "Argument 1 ('destination') to AudioBuffer.copyFromChannel must be an instance of Float32Array". 23 PASS 9: buffer.copyFromChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Argument 1 ('destination') to AudioBuffer.copyFromChannel must be an instance of Float32Array". 24 PASS < [copyFrom-exceptions] All assertions passed. (total 11 assertions) 25 25 PASS > [copyTo-exceptions] 26 26 PASS AudioBuffer.prototype.copyToChannel does exist. … … 32 32 PASS 5: buffer.copyToChannel(x, 0, 16) did not throw an exception. 33 33 PASS 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 34 PASS 7: buffer.copyToChannel(SharedArrayBuffer view, 0) threw TypeError: "Argument 1 ('source') to AudioBuffer.copyToChannel must be an instance of Float32Array". 35 PASS 8: buffer.copyToChannel(SharedArrayBuffer view, 0, 0) threw TypeError: "Argument 1 ('source') to AudioBuffer.copyToChannel must be an instance of Float32Array". 36 PASS < [copyTo-exceptions] All assertions passed. (total 10 assertions) 37 37 PASS > [copyFrom-validate] 38 38 PASS buffer.copyFromChannel(dst8, 0) is identical to the array [1,2,3,4,5,6,7,8]. … … 61 61 PASS 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...]. 62 62 PASS < [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 63 PASS # AUDIT TASK RUNNER FINISHED: 5 tasks ran successfully. 64 64 -
trunk/LayoutTests/platform/win/TestExpectations
r269785 r269940 4601 4601 webkit.org/b/218346 fast/text/canvas-color-fonts [ Pass ImageOnlyFailure ] 4602 4602 webkit.org/b/218346 http/tests/canvas/color-fonts [ Pass ImageOnlyFailure ] 4603 4604 # WebAssembly is not enabled 4605 js/dom/webassembly-memory-shared-basic.html [ Skip ] 4606 js/dom/webassembly-memory-normal-fail.html [ Skip ] 4607 js/dom/webassembly-memory-shared-fail.html [ Skip ] 4608 storage/indexeddb/shared-memory-structured-clone.html [ Skip ] -
trunk/Source/JavaScriptCore/CMakeLists.txt
r269933 r269940 1090 1090 1091 1091 wasm/js/JSWebAssembly.h 1092 wasm/js/JSWebAssemblyMemory.h 1092 1093 wasm/js/JSWebAssemblyModule.h 1093 1094 -
trunk/Source/JavaScriptCore/ChangeLog
r269939 r269940 1 2020-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 1 124 2020-11-17 Yusuke Suzuki <ysuzuki@apple.com> 2 125 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r269706 r269940 1575 1575 AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */; }; 1576 1576 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, ); }; }; 1578 1578 AD2FCBE91DB58DAD00B3E736 /* JSWebAssemblyRuntimeError.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAD1DB58DA400B3E736 /* JSWebAssemblyRuntimeError.h */; }; 1579 1579 AD2FCBEB1DB58DAD00B3E736 /* JSWebAssemblyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBAF1DB58DA400B3E736 /* JSWebAssemblyTable.h */; }; -
trunk/Source/JavaScriptCore/llint/LLIntPCRanges.h
r268247 r269940 36 36 void llintPCRangeStart(); 37 37 void llintPCRangeEnd(); 38 #if ENABLE(WEBASSEMBLY) 39 void wasmLLIntPCRangeStart(); 40 void wasmLLIntPCRangeEnd(); 41 #endif 38 42 } 39 43 … … 47 51 } 48 52 53 #if ENABLE(WEBASSEMBLY) 54 ALWAYS_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 49 64 #if !ENABLE(C_LOOP) 50 65 static constexpr GPRReg LLIntPC = GPRInfo::regT4; -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r269929 r269940 2468 2468 include WebAssembly 2469 2469 end 2470 2471 global _wasmLLIntPCRangeStart 2472 _wasmLLIntPCRangeStart: 2470 2473 wasmScope() 2474 global _wasmLLIntPCRangeEnd 2475 _wasmLLIntPCRangeEnd: 2471 2476 2472 2477 else -
trunk/Source/JavaScriptCore/llint/WebAssembly.asm
r269929 r269940 46 46 const wasmInstance = csr0 47 47 const memoryBase = csr3 48 const memorySize = csr448 const boundsCheckingSize = csr4 49 49 50 50 # This must match the definition in LowLevelInterpreter.asm … … 188 188 189 189 macro preserveCalleeSavesUsedByWasm() 190 # NOTE: We intentionally don't save memoryBase and memorySize here. See the comment190 # NOTE: We intentionally don't save memoryBase and boundsCheckingSize here. See the comment 191 191 # in restoreCalleeSavesUsedByWasm() below for why. 192 192 subp CalleeSaveSpaceStackAligned, sp … … 202 202 203 203 macro restoreCalleeSavesUsedByWasm() 204 # NOTE: We intentionally don't restore memoryBase and memorySize here. These are saved204 # NOTE: We intentionally don't restore memoryBase and boundsCheckingSize here. These are saved 205 205 # and restored when entering Wasm by the JSToWasm wrapper and changes to them are meant 206 206 # to be observable within the same Wasm module. … … 241 241 macro reloadMemoryRegistersFromInstance(instance, scratch1, scratch2) 242 242 loadp Wasm::Instance::m_cachedMemory[instance], memoryBase 243 loadi Wasm::Instance::m_cached MemorySize[instance], memorySize244 cagedPrimitive(memoryBase, memorySize, scratch1, scratch2)243 loadi Wasm::Instance::m_cachedBoundsCheckingSize[instance], boundsCheckingSize 244 cagedPrimitive(memoryBase, boundsCheckingSize, scratch1, scratch2) 245 245 end 246 246 … … 857 857 858 858 wasmOp(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 860 862 urshiftq 16, t0 861 863 returnq(ctx, t0) … … 875 877 macro emitCheckAndPreparePointer(ctx, pointer, offset, size) 876 878 leap size - 1[pointer, offset], t5 877 bpb t5, memorySize, .continuation879 bpb t5, boundsCheckingSize, .continuation 878 880 throwException(OutOfBoundsMemoryAccess) 879 881 .continuation: -
trunk/Source/JavaScriptCore/runtime/JSArrayBuffer.h
r260415 r269940 56 56 // This is the default DOM unwrapping. It calls toUnsharedArrayBuffer(). 57 57 static ArrayBuffer* toWrapped(VM&, JSValue); 58 static ArrayBuffer* toWrappedAllowShared(VM&, JSValue); 58 59 59 60 private: … … 87 88 } 88 89 90 inline ArrayBuffer* JSArrayBuffer::toWrappedAllowShared(VM& vm, JSValue value) 91 { 92 return toPossiblySharedArrayBuffer(vm, value); 93 } 94 89 95 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.h
r269832 r269940 205 205 206 206 static RefPtr<ArrayBufferView> toWrapped(VM&, JSValue); 207 static RefPtr<ArrayBufferView> toWrappedAllowShared(VM&, JSValue); 207 208 208 209 private: -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h
r259069 r269940 130 130 } 131 131 132 inline 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 132 140 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h
r269343 r269940 288 288 // This is the default DOM unwrapping. It calls toUnsharedNativeTypedView(). 289 289 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); 290 292 291 293 private: … … 393 395 } 394 396 397 template<typename Adaptor> 398 RefPtr<typename Adaptor::ViewType> JSGenericTypedArrayView<Adaptor>::toWrappedAllowShared(VM& vm, JSValue value) 399 { 400 return JSC::toPossiblySharedNativeTypedView<Adaptor>(vm, value); 401 } 402 403 395 404 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r269349 r269940 366 366 #endif 367 367 368 #if !ENABLE(WEBASSEMBLY_ FAST_MEMORY)368 #if !ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 369 369 Options::useWebAssemblyFastMemory() = false; 370 Options::useSharedArrayBuffer() = false; 370 371 #endif 371 372 … … 659 660 #endif 660 661 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()) { 663 664 const char* asanOptions = getenv("ASAN_OPTIONS"); 664 665 bool okToUseWebAssemblyFastMemory = asanOptions 665 666 && (strstr(asanOptions, "allow_user_segv_handler=1") || strstr(asanOptions, "handle_segv=0")); 666 667 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."); 668 669 Options::useWebAssemblyFastMemory() = false; 670 Options::useSharedArrayBuffer() = false; 669 671 } 670 672 } -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r269929 r269940 681 681 Vector<UnlinkedWasmToWasmCall>& m_unlinkedWasmToWasmCalls; // List each call site and the function index whose address it should be patched with. 682 682 GPRReg m_memoryBaseGPR { InvalidGPRReg }; 683 GPRReg m_ memorySizeGPR { InvalidGPRReg };683 GPRReg m_boundsCheckingSizeGPR { InvalidGPRReg }; 684 684 GPRReg m_wasmContextInstanceGPR { InvalidGPRReg }; 685 685 bool m_makesCalls { false }; … … 773 773 774 774 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); 777 777 } 778 778 … … 919 919 RegisterSet clobbers; 920 920 clobbers.set(pinnedRegs->baseMemoryPointer); 921 clobbers.set(pinnedRegs-> sizeRegister);921 clobbers.set(pinnedRegs->boundsCheckingSizeRegister); 922 922 if (!isARM64()) 923 923 clobbers.set(RegisterSet::macroScratchRegisters()); … … 934 934 AllowMacroScratchRegisterUsage allowScratch(jit); 935 935 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 936 GPRReg scratchOr Size = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;937 938 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCached MemorySize()), 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); 939 939 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 940 940 941 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs-> sizeRegister, scratchOrSize);941 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->boundsCheckingSizeRegister, scratchOrBoundsCheckingSize); 942 942 }); 943 943 … … 1169 1169 auto temp2 = g64(); 1170 1170 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); 1173 1177 constexpr uint32_t shiftValue = 16; 1174 1178 static_assert(PageCount::pageSize == 1ull << shiftValue, "This must hold for the code below to be correct."); … … 1364 1368 switch (m_mode) { 1365 1369 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); 1368 1373 ASSERT(sizeOfOperation + offset > offset); 1369 1374 auto temp = g64(); … … 1372 1377 1373 1378 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)); 1375 1380 }, [=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { 1376 1381 this->emitThrowException(jit, ExceptionType::OutOfBoundsMemoryAccess); … … 2155 2160 // We need to clobber the size register since the LLInt always bounds checks 2156 2161 if (m_mode == MemoryMode::Signaling) 2157 patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get(). sizeRegister });2162 patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().boundsCheckingSizeRegister }); 2158 2163 patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { 2159 2164 AllowMacroScratchRegisterUsage allowScratch(jit); … … 2279 2284 // FIXME: We should support more than one memory size register 2280 2285 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 2281 ASSERT(pinnedRegs. sizeRegister != newContextInstance);2282 GPRReg scratchOr Size = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;2283 2284 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCached MemorySize()), pinnedRegs.sizeRegister); // Memorysize.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. 2285 2290 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 2286 2291 2287 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs. sizeRegister, scratchOrSize);2292 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratchOrBoundsCheckingSize); 2288 2293 }); 2289 2294 -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r269694 r269940 326 326 Value* m_framePointer { nullptr }; 327 327 GPRReg m_memoryBaseGPR { InvalidGPRReg }; 328 GPRReg m_ memorySizeGPR { InvalidGPRReg };328 GPRReg m_boundsCheckingSizeGPR { InvalidGPRReg }; 329 329 GPRReg m_wasmContextInstanceGPR { InvalidGPRReg }; 330 330 bool m_makesCalls { false }; … … 409 409 410 410 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); 413 413 } 414 414 … … 418 418 switch (m_mode) { 419 419 case MemoryMode::BoundsChecking: 420 ASSERT_UNUSED(pinnedGPR, m_ memorySizeGPR == pinnedGPR);420 ASSERT_UNUSED(pinnedGPR, m_boundsCheckingSizeGPR == pinnedGPR); 421 421 break; 422 422 case MemoryMode::Signaling: … … 546 546 RegisterSet clobbers; 547 547 clobbers.set(pinnedRegs->baseMemoryPointer); 548 clobbers.set(pinnedRegs-> sizeRegister);548 clobbers.set(pinnedRegs->boundsCheckingSizeRegister); 549 549 if (!isARM64()) 550 550 clobbers.set(RegisterSet::macroScratchRegisters()); … … 562 562 AllowMacroScratchRegisterUsage allowScratch(jit); 563 563 GPRReg baseMemory = pinnedRegs->baseMemoryPointer; 564 GPRReg scratchOr Size = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs->sizeRegister;565 566 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCached MemorySize()), 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); 567 567 jit.loadPtr(CCallHelpers::Address(params[0].gpr(), Instance::offsetOfCachedMemory()), baseMemory); 568 568 569 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs-> sizeRegister, scratchOrSize);569 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs->boundsCheckingSizeRegister, scratchOrBoundsCheckingSize); 570 570 }); 571 571 } … … 794 794 { 795 795 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())); 797 799 798 800 constexpr uint32_t shiftValue = 16; … … 955 957 case MemoryMode::BoundsChecking: { 956 958 // 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); 958 960 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); 960 962 break; 961 963 } … … 1711 1713 // We need to clobber the size register since the LLInt always bounds checks 1712 1714 if (m_mode == MemoryMode::Signaling) 1713 patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get(). sizeRegister });1715 patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().boundsCheckingSizeRegister }); 1714 1716 patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { 1715 1717 AllowMacroScratchRegisterUsage allowScratch(jit); … … 1832 1834 jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit())); 1833 1835 jit.storeWasmContextInstance(newContextInstance); 1834 ASSERT(pinnedRegs. sizeRegister != baseMemory);1836 ASSERT(pinnedRegs.boundsCheckingSizeRegister != baseMemory); 1835 1837 // FIXME: We should support more than one memory size register 1836 1838 // see: https://bugs.webkit.org/show_bug.cgi?id=162952 1837 ASSERT(pinnedRegs. sizeRegister != newContextInstance);1838 GPRReg scratchOr Size = Gigacage::isEnabled(Gigacage::Primitive) ? params.gpScratch(0) : pinnedRegs.sizeRegister;1839 1840 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCached MemorySize()), 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. 1841 1843 jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*. 1842 1844 1843 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs. sizeRegister, scratchOrSize);1845 jit.cageConditionally(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratchOrBoundsCheckingSize); 1844 1846 }); 1845 1847 doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation); -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r265186 r269940 50 50 ASSERT(baseMemory != GPRReg::InvalidGPRReg); 51 51 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; 55 55 ASSERT(sizeRegAsScratch != GPRReg::InvalidGPRReg); 56 56 … … 69 69 // Set up the callee's baseMemory register as well as the memory size registers. 70 70 { 71 GPRReg scratchOr Size = !Gigacage::isEnabled(Gigacage::Primitive) ? pinnedRegs.sizeRegister : wasmCallingConvention().prologueScratchGPRs[1];71 GPRReg scratchOrBoundsCheckingSize = !Gigacage::isEnabled(Gigacage::Primitive) ? pinnedRegs.boundsCheckingSizeRegister : wasmCallingConvention().prologueScratchGPRs[1]; 72 72 73 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCached MemorySize()), pinnedRegs.sizeRegister); // Memorysize.73 jit.loadPtr(JIT::Address(baseMemory, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Bound checking size. 74 74 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); 76 76 } 77 77 -
trunk/Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp
r269694 r269940 53 53 static bool fastHandlerInstalled { false }; 54 54 55 #if ENABLE(WEBASSEMBLY_ FAST_MEMORY)55 #if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 56 56 57 57 static SignalAction trapHandler(Signal, SigInfo& sigInfo, PlatformRegisters& context) … … 64 64 65 65 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, 67 68 // we might have crashed in code that is already holding one of the locks we want to aquire. 68 69 assertIsNotTagged(faultingInstruction); 69 if (isJITPC(faultingInstruction) ) {70 bool faultedInActive FastMemory = false;70 if (isJITPC(faultingInstruction) || LLInt::isWasmLLIntPC(faultingInstruction)) { 71 bool faultedInActiveGrowableMemory = false; 71 72 { 72 73 void* faultingAddress = sigInfo.faultingAddress; 73 74 dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "checking faulting address: ", RawPointer(faultingAddress), " is in an active fast memory"); 74 faultedInActive FastMemory = Wasm::Memory::addressIsInActiveFastMemory(faultingAddress);75 faultedInActiveGrowableMemory = Wasm::Memory::addressIsInGrowableOrFastMemory(faultingAddress); 75 76 } 76 if (faultedInActive FastMemory) {77 if (faultedInActiveGrowableMemory) { 77 78 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 } 88 92 } 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; 89 100 } 90 101 } … … 93 104 } 94 105 95 #endif // ENABLE(WEBASSEMBLY_ FAST_MEMORY)106 #endif // ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 96 107 97 108 bool fastMemoryEnabled() … … 102 113 void enableFastMemory() 103 114 { 104 #if ENABLE(WEBASSEMBLY_ FAST_MEMORY)115 #if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 105 116 static std::once_flag once; 106 117 std::call_once(once, [] { … … 108 119 return; 109 120 110 if (!Options::useWebAssemblyFastMemory() )121 if (!Options::useWebAssemblyFastMemory() && !Options::useSharedArrayBuffer()) 111 122 return; 112 123 … … 120 131 void prepareFastMemory() 121 132 { 122 #if ENABLE(WEBASSEMBLY_ FAST_MEMORY)133 #if ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 123 134 static std::once_flag once; 124 135 std::call_once(once, [] { … … 126 137 return; 127 138 128 if (!Options::useWebAssemblyFastMemory() )139 if (!Options::useWebAssemblyFastMemory() && !Options::useSharedArrayBuffer()) 129 140 return; 130 141 … … 133 144 }); 134 145 }); 135 #endif // ENABLE(WEBASSEMBLY_ FAST_MEMORY)146 #endif // ENABLE(WEBASSEMBLY_SIGNALING_MEMORY) 136 147 } 137 148 -
trunk/Source/JavaScriptCore/wasm/WasmInstance.h
r253987 r269940 78 78 void setTable(unsigned, Ref<Table>&&); 79 79 80 void* cachedMemory() const { return m_cachedMemory.getMayBeNull(cached MemorySize()); }81 size_t cached MemorySize() const { return m_cachedMemorySize; }80 void* cachedMemory() const { return m_cachedMemory.getMayBeNull(cachedBoundsCheckingSize()); } 81 size_t cachedBoundsCheckingSize() const { return m_cachedBoundsCheckingSize; } 82 82 83 83 void setMemory(Ref<Memory>&& memory) … … 90 90 { 91 91 if (m_memory != nullptr) { 92 m_cachedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>(memory()->memory(), memory()-> size());93 m_cached MemorySize = memory()->size();92 m_cachedMemory = CagedPtr<Gigacage::Primitive, void, tagCagedPtr>(memory()->memory(), memory()->boundsCheckingSize()); 93 m_cachedBoundsCheckingSize = memory()->boundsCheckingSize(); 94 94 } 95 95 } … … 147 147 static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(Instance, m_globals); } 148 148 static ptrdiff_t offsetOfCachedMemory() { return OBJECT_OFFSETOF(Instance, m_cachedMemory); } 149 static ptrdiff_t offsetOfCached MemorySize() { return OBJECT_OFFSETOF(Instance, m_cachedMemorySize); }149 static ptrdiff_t offsetOfCachedBoundsCheckingSize() { return OBJECT_OFFSETOF(Instance, m_cachedBoundsCheckingSize); } 150 150 static ptrdiff_t offsetOfPointerToTopEntryFrame() { return OBJECT_OFFSETOF(Instance, m_pointerToTopEntryFrame); } 151 151 … … 202 202 Context* m_context { nullptr }; 203 203 CagedPtr<Gigacage::Primitive, void, tagCagedPtr> m_cachedMemory; 204 size_t m_cached MemorySize { 0 };204 size_t m_cachedBoundsCheckingSize { 0 }; 205 205 Ref<Module> m_module; 206 206 RefPtr<CodeBlock> m_codeBlock; -
trunk/Source/JavaScriptCore/wasm/WasmMemory.cpp
r261755 r269940 37 37 #include <wtf/PrintStream.h> 38 38 #include <wtf/RAMSize.h> 39 #include <wtf/StdSet.h> 39 40 #include <wtf/Vector.h> 40 41 … … 134 135 dataLogLnIf(Options::logWebAssemblyMemory(), "Freed virtual; state: ", *this); 135 136 } 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. 140 170 auto holder = holdLock(m_lock); 141 171 for (void* memory : m_fastMemories) { 142 172 char* start = static_cast<char*>(memory); 143 173 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)) 144 184 return true; 145 185 } … … 193 233 unsigned m_maxFastMemoryCount { 0 }; 194 234 Vector<void*> m_fastMemories; 235 StdSet<std::pair<uintptr_t, size_t>> m_growableBoundsCheckingMemories; 195 236 size_t m_physicalBytes { 0 }; 196 237 }; … … 236 277 } // anonymous namespace 237 278 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 280 MemoryHandle::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) 258 284 , m_initial(initial) 259 285 , m_maximum(maximum) 260 , m_ mappedCapacity(mappedCapacity)286 , m_sharingMode(sharingMode) 261 287 , 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 295 MemoryHandle::~MemoryHandle() 333 296 { 334 297 if (m_memory) { … … 342 305 memoryManager().freeFastMemory(memory()); 343 306 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 } 346 321 break; 347 322 } 348 } 349 } 323 } 324 } 325 } 326 327 Memory::Memory() 328 : m_handle(adoptRef(*new MemoryHandle(nullptr, 0, 0, PageCount(0), PageCount(0), MemorySharingMode::Default, MemoryMode::BoundsChecking))) 329 { 330 } 331 332 Memory::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 344 Memory::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 353 Ref<Memory> Memory::create() 354 { 355 return adoptRef(*new Memory()); 356 } 357 358 Ref<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 363 RefPtr<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 446 Memory::~Memory() = default; 350 447 351 448 size_t Memory::fastMappedRedzoneBytes() … … 360 457 } 361 458 362 bool Memory::addressIsInActiveFastMemory(void* address) 363 { 364 return memoryManager().isAddressInFastMemory(address); 459 bool Memory::addressIsInGrowableOrFastMemory(void* address) 460 { 461 return memoryManager().isInGrowableOrFastMemory(address); 462 } 463 464 Expected<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; 365 518 } 366 519 367 520 Expected<PageCount, Memory::GrowFailReason> Memory::grow(PageCount delta) 368 521 { 369 const Wasm::PageCount oldPageCount = sizeInPages();370 371 522 if (!delta.isValid()) 372 523 return makeUnexpected(GrowFailReason::InvalidDelta); 373 524 525 if (sharingMode() == MemorySharingMode::Shared) 526 return growShared(delta); 527 528 const Wasm::PageCount oldPageCount = sizeInPages(); 374 529 const Wasm::PageCount newPageCount = oldPageCount + delta; 375 530 if (!newPageCount || !newPageCount.isValid()) … … 392 547 393 548 dataLogLnIf(verbose, "Memory::grow(", delta, ") to ", newPageCount, " from ", *this); 394 RELEASE_ASSERT(newPageCount > PageCount::fromBytes( m_size));549 RELEASE_ASSERT(newPageCount > PageCount::fromBytes(size())); 395 550 396 551 if (maximum() && newPageCount > maximum()) … … 399 554 size_t desiredSize = newPageCount.bytes(); 400 555 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()); 411 557 switch (mode()) { 412 558 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 413 566 RELEASE_ASSERT(maximum().bytes() != 0); 414 567 … … 417 570 return makeUnexpected(GrowFailReason::OutOfMemory); 418 571 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 425 576 ASSERT(memory() == newMemory); 426 577 return success(); 427 578 } 428 579 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 429 589 RELEASE_ASSERT(memory()); 590 430 591 // 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(); 432 593 433 594 dataLogLnIf(verbose, "Marking WebAssembly memory's ", RawPointer(memory()), " as read+write in range [", RawPointer(startAddress), ", ", RawPointer(startAddress + extraBytes), ")"); … … 436 597 RELEASE_ASSERT_NOT_REACHED(); 437 598 } 438 m_memory.recage(m_size, desiredSize); 439 m_ size = desiredSize;599 600 m_handle->growToSize(desiredSize); 440 601 return success(); 441 602 } … … 460 621 void Memory::dump(PrintStream& out) const 461 622 { 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())); 463 625 } 464 626 -
trunk/Source/JavaScriptCore/wasm/WasmMemory.h
r246368 r269940 45 45 namespace JSC { 46 46 47 class LLIntOffsetsExtractor; 48 47 49 namespace Wasm { 48 50 49 51 class Instance; 50 52 51 class Memory : public RefCounted<Memory> { 53 class MemoryHandle final : public ThreadSafeRefCounted<MemoryHandle> { 54 WTF_MAKE_NONCOPYABLE(MemoryHandle); 55 WTF_MAKE_FAST_ALLOCATED; 56 friend LLIntOffsetsExtractor; 57 public: 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 76 private: 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 88 class Memory final : public RefCounted<Memory> { 52 89 WTF_MAKE_NONCOPYABLE(Memory); 53 90 WTF_MAKE_FAST_ALLOCATED; 91 friend LLIntOffsetsExtractor; 54 92 public: 55 93 void dump(WTF::PrintStream&) const; 56 94 57 explicit operator bool() const { return !!m_ memory; }95 explicit operator bool() const { return !!m_handle->memory(); } 58 96 59 97 enum NotifyPressure { NotifyPressureTag }; … … 62 100 63 101 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); 65 104 66 ~Memory();105 JS_EXPORT_PRIVATE ~Memory(); 67 106 68 107 static size_t fastMappedRedzoneBytes(); 69 108 static size_t fastMappedBytes(); // Includes redzone. 70 static bool addressIsIn ActiveFastMemory(void*);109 static bool addressIsInGrowableOrFastMemory(void*); 71 110 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(); } 75 118 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(); } 80 121 81 122 enum class GrowFailReason { … … 90 131 void check() { ASSERT(!deletionHasBegun()); } 91 132 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); } 94 134 95 135 private: 96 136 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); 99 139 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; 107 143 WTF::Function<void(NotifyPressure)> m_notifyMemoryPressure; 108 144 WTF::Function<void(SyncTryToReclaim)> m_syncTryToReclaimMemory; … … 120 156 public: 121 157 static size_t maxFastMemoryCount() { return 0; } 122 static bool addressIsIn ActiveFastMemory(void*) { return false; }158 static bool addressIsInGrowableOrFastMemory(void*) { return false; } 123 159 }; 124 160 -
trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp
r261755 r269940 43 43 ++numberOfPinnedRegisters; 44 44 GPRReg baseMemoryPointer = GPRInfo::regCS3; 45 GPRReg sizeRegister = GPRInfo::regCS4;45 GPRReg boundsCheckingSizeRegister = GPRInfo::regCS4; 46 46 GPRReg wasmContextInstancePointer = InvalidGPRReg; 47 47 if (!Context::useFastTLS()) 48 48 wasmContextInstancePointer = GPRInfo::regCS0; 49 49 50 staticPinnedRegisterInfo.construct( sizeRegister, baseMemoryPointer, wasmContextInstancePointer);50 staticPinnedRegisterInfo.construct(boundsCheckingSizeRegister, baseMemoryPointer, wasmContextInstancePointer); 51 51 }); 52 52 … … 54 54 } 55 55 56 PinnedRegisterInfo::PinnedRegisterInfo(GPRReg sizeRegister, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer)57 : sizeRegister(sizeRegister)56 PinnedRegisterInfo::PinnedRegisterInfo(GPRReg boundsCheckingSizeRegister, GPRReg baseMemoryPointer, GPRReg wasmContextInstancePointer) 57 : boundsCheckingSizeRegister(boundsCheckingSizeRegister) 58 58 , baseMemoryPointer(baseMemoryPointer) 59 59 , wasmContextInstancePointer(wasmContextInstancePointer) -
trunk/Source/JavaScriptCore/wasm/WasmMemoryInformation.h
r243886 r269940 40 40 41 41 struct PinnedSizeRegisterInfo { 42 GPRReg sizeRegister;42 GPRReg boundsCheckingSizeRegister; 43 43 unsigned sizeOffset; 44 44 }; … … 57 57 result.set(wasmContextInstancePointer); 58 58 if (mode != MemoryMode::Signaling) 59 result.set( sizeRegister);59 result.set(boundsCheckingSizeRegister); 60 60 return result; 61 61 } 62 62 63 GPRReg sizeRegister;63 GPRReg boundsCheckingSizeRegister; 64 64 GPRReg baseMemoryPointer; 65 65 GPRReg wasmContextInstancePointer; -
trunk/Source/JavaScriptCore/wasm/WasmMemoryMode.cpp
r223738 r269940 43 43 } 44 44 45 const 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 45 55 } } // namespace JSC::Wasm 46 56 -
trunk/Source/JavaScriptCore/wasm/WasmMemoryMode.h
r225028 r269940 41 41 JS_EXPORT_PRIVATE const char* makeString(MemoryMode); 42 42 43 enum class MemorySharingMode : uint8_t { 44 Default, 45 Shared, 46 }; 47 48 JS_EXPORT_PRIVATE const char* makeString(MemorySharingMode); 49 43 50 } } // namespace JSC::Wasm 44 51 -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r269552 r269940 222 222 if (!!info.memory) { 223 223 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 224 GPRReg scratchOr Size = wasmCallingConvention().prologueScratchGPRs[0];224 GPRReg scratchOrBoundsCheckingSize = wasmCallingConvention().prologueScratchGPRs[0]; 225 225 226 226 if (Context::useFastTLS()) … … 230 230 if (isARM64E()) { 231 231 if (mode != Wasm::MemoryMode::Signaling) 232 scratchOr Size = pinnedRegs.sizeRegister;233 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCached MemorySize()), scratchOrSize);232 scratchOrBoundsCheckingSize = pinnedRegs.boundsCheckingSizeRegister; 233 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), scratchOrBoundsCheckingSize); 234 234 } else { 235 235 if (mode != Wasm::MemoryMode::Signaling) 236 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCached MemorySize()), pinnedRegs.sizeRegister);236 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); 237 237 } 238 238 239 239 jit.loadPtr(CCallHelpers::Address(currentInstanceGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 240 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOr Size, scratchOrSize);240 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrBoundsCheckingSize, scratchOrBoundsCheckingSize); 241 241 } 242 242 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r261755 r269940 292 292 RETURN_IF_EXCEPTION(throwScope, nullptr); 293 293 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, 295 295 [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); }, 296 296 [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); }, -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp
r269343 r269940 33 33 #include "ArrayBuffer.h" 34 34 #include "JSArrayBuffer.h" 35 #include "ObjectConstructor.h" 35 36 36 37 namespace JSC { … … 73 74 } 74 75 75 JSArrayBuffer* JSWebAssemblyMemory::buffer( VM& vm,JSGlobalObject* globalObject)76 JSArrayBuffer* JSWebAssemblyMemory::buffer(JSGlobalObject* globalObject) 76 77 { 77 if (m_bufferWrapper)78 return m_bufferWrapper.get();78 VM& vm = globalObject->vm(); 79 auto throwScope = DECLARE_THROW_SCOPE(vm); 79 80 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*) { }); 83 94 m_buffer = ArrayBuffer::createFromBytes(memory().memory(), memory().size(), WTFMove(destructor)); 84 95 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); 86 104 RELEASE_ASSERT(m_bufferWrapper); 87 105 return m_bufferWrapper.get(); … … 118 136 // We need to clear out the old array buffer because it might now be pointing to stale memory. 119 137 if (m_buffer) { 120 m_buffer->detach(vm); 138 if (m_memory->sharingMode() == Wasm::MemorySharingMode::Default) 139 m_buffer->detach(vm); 121 140 m_buffer = nullptr; 122 141 m_bufferWrapper.clear(); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h
r253121 r269940 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include "JS DestructibleObject.h"30 #include "JSObject.h" 31 31 #include "WasmMemory.h" 32 32 #include <wtf/Ref.h> … … 50 50 } 51 51 52 static JSWebAssemblyMemory* tryCreate(JSGlobalObject*, VM&, Structure*);52 JS_EXPORT_PRIVATE static JSWebAssemblyMemory* tryCreate(JSGlobalObject*, VM&, Structure*); 53 53 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 54 54 55 55 DECLARE_EXPORT_INFO; 56 56 57 void adopt(Ref<Wasm::Memory>&&);57 JS_EXPORT_PRIVATE void adopt(Ref<Wasm::Memory>&&); 58 58 Wasm::Memory& memory() { return m_memory.get(); } 59 JSArrayBuffer* buffer( VM& vm,JSGlobalObject*);59 JSArrayBuffer* buffer(JSGlobalObject*); 60 60 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); 62 62 63 63 private: -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r269552 r269940 358 358 if (!!moduleInformation.memory) { 359 359 GPRReg baseMemory = pinnedRegs.baseMemoryPointer; 360 GPRReg scratchOr Size = stackLimitGPR;360 GPRReg scratchOrBoundsCheckingSize = stackLimitGPR; 361 361 auto mode = instance()->memoryMode(); 362 362 363 363 if (isARM64E()) { 364 364 if (mode != Wasm::MemoryMode::Signaling) 365 scratchOr Size = pinnedRegs.sizeRegister;366 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCached MemorySize()), scratchOrSize);365 scratchOrBoundsCheckingSize = pinnedRegs.boundsCheckingSizeRegister; 366 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), scratchOrBoundsCheckingSize); 367 367 } else { 368 368 if (mode != Wasm::MemoryMode::Signaling) 369 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCached MemorySize()), pinnedRegs.sizeRegister);369 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); 370 370 } 371 371 372 372 jit.loadPtr(CCallHelpers::Address(scratchGPR, Wasm::Instance::offsetOfCachedMemory()), baseMemory); 373 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOr Size, scratchOrSize);373 jit.cageConditionally(Gigacage::Primitive, baseMemory, scratchOrBoundsCheckingSize, scratchOrBoundsCheckingSize); 374 374 } 375 375 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp
r267594 r269940 57 57 VM& vm = globalObject->vm(); 58 58 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)));61 59 62 60 JSObject* memoryDescriptor; … … 103 101 } 104 102 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 105 116 auto* jsMemory = JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure()); 106 117 RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); 107 118 108 RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(initialPageCount, maximumPageCount, 119 RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(initialPageCount, maximumPageCount, sharingMode, 109 120 [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); }, 110 121 [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); }, -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp
r267594 r269940 94 94 JSWebAssemblyMemory* memory = getMemory(globalObject, vm, callFrame->thisValue()); 95 95 RETURN_IF_EXCEPTION(throwScope, { }); 96 return JSValue::encode(memory->buffer(globalObject->vm(), globalObject));96 RELEASE_AND_RETURN(throwScope, JSValue::encode(memory->buffer(globalObject))); 97 97 } 98 98 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r269552 r269940 567 567 568 568 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(); 571 572 572 573 for (const Wasm::Segment::Ptr& segment : data) { -
trunk/Source/WTF/wtf/PlatformEnable.h
r269775 r269940 691 691 692 692 #if ENABLE(WEBASSEMBLY) && HAVE(MACHINE_CONTEXT) 693 #define ENABLE_WEBASSEMBLY_ FAST_MEMORY 1693 #define ENABLE_WEBASSEMBLY_SIGNALING_MEMORY 1 694 694 #endif 695 695 -
trunk/Source/WebCore/ChangeLog
r269938 r269940 1 2020-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 1 101 2020-11-17 Zalan Bujtas <zalan@apple.com> 2 102 -
trunk/Source/WebCore/Headers.cmake
r269907 r269940 1577 1577 workers/WorkerScriptLoaderClient.h 1578 1578 workers/WorkerThread.h 1579 workers/WorkerThreadType.h 1579 1580 workers/WorkerType.h 1580 1581 -
trunk/Source/WebCore/Modules/indexeddb/server/IDBSerializationContext.cpp
r268700 r269940 80 80 m_vm = JSC::VM::create(); 81 81 m_vm->heap.acquireAccess(); 82 JSVMClientData::initNormalWorld(m_vm.get() );82 JSVMClientData::initNormalWorld(m_vm.get(), WorkerThreadType::Worklet); 83 83 84 84 JSC::JSLockHolder locker(m_vm.get()); -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r269937 r269940 5027 5027 E3A776671DC85D2800B690D8 /* DOMJITIDLConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A776651DC85D2200B690D8 /* DOMJITIDLConvert.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5028 5028 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, ); }; }; 5029 5030 E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5030 5031 E3B2F0EE1D7F4CA900B0C9D1 /* LoadableScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 16072 16073 E3AE6CD12252F27000C70B50 /* AllDescendantsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllDescendantsCollection.cpp; sourceTree = "<group>"; }; 16073 16074 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>"; }; 16074 16076 E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableClassicScript.cpp; sourceTree = "<group>"; }; 16075 16077 E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableClassicScript.h; sourceTree = "<group>"; }; … … 19048 19050 2E4346420F546A8200B0F1BA /* WorkerThread.cpp */, 19049 19051 2E4346430F546A8200B0F1BA /* WorkerThread.h */, 19052 E3AFD7AB255F50DC00E5E30E /* WorkerThreadType.h */, 19050 19053 51F174FC1F35898800C74950 /* WorkerType.h */, 19051 19054 51F174FA1F3588D700C74950 /* WorkerType.idl */, … … 35196 35199 0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */, 35197 35200 97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */, 35201 E3AFD7AD255F50EB00E5E30E /* WorkerThreadType.h in Headers */, 35198 35202 A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */, 35199 35203 51F174FE1F35899200C74950 /* WorkerType.h in Headers */, -
trunk/Source/WebCore/bindings/IDLTypes.h
r266662 r269940 152 152 }; 153 153 154 template<typename T> struct IDLAllowSharedAdaptor : T { 155 using InnerType = T; 156 }; 157 154 158 struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> { 155 159 using NullableType = JSC::Strong<JSC::JSObject>; … … 324 328 struct IsIDLTypedArray : public std::integral_constant<bool, WTF::IsBaseOfTemplate<IDLTypedArray, T>::value> { }; 325 329 330 template<typename T> 331 struct IsIDLArrayBuffer : public std::integral_constant<bool, std::is_base_of<IDLArrayBuffer, T>::value> { }; 332 333 template<typename T> 334 struct IsIDLArrayBufferView : public std::integral_constant<bool, std::is_base_of<IDLArrayBufferView, T>::value> { }; 335 336 template<typename T> 337 struct IsIDLArrayBufferAllowShared : public std::integral_constant<bool, std::is_base_of<IDLAllowSharedAdaptor<IDLArrayBuffer>, T>::value> { }; 338 339 template<typename T> 340 struct IsIDLArrayBufferViewAllowShared : public std::integral_constant<bool, std::is_base_of<IDLAllowSharedAdaptor<IDLArrayBufferView>, T>::value> { }; 341 342 326 343 } // namespace WebCore -
trunk/Source/WebCore/bindings/js/CommonVM.cpp
r266355 r269940 89 89 vm.setGlobalConstRedeclarationShouldThrow(globalConstRedeclarationShouldThrow()); 90 90 91 JSVMClientData::initNormalWorld(&vm );91 JSVMClientData::initNormalWorld(&vm, WorkerThreadType::Main); 92 92 93 93 return vm; -
trunk/Source/WebCore/bindings/js/JSDOMConvertBufferSource.h
r266533 r269940 110 110 namespace Detail { 111 111 112 template<typename BufferSourceType> 112 enum class BufferSourceConverterAllowSharedMode { Allow, Disallow }; 113 template<typename BufferSourceType, BufferSourceConverterAllowSharedMode mode> 113 114 struct BufferSourceConverter { 114 115 using WrapperType = typename Converter<BufferSourceType>::WrapperType; … … 120 121 auto& vm = JSC::getVM(&lexicalGlobalObject); 121 122 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); 123 128 if (UNLIKELY(!object)) 124 129 exceptionThrower(lexicalGlobalObject, scope); … … 136 141 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 137 142 { 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)); 139 144 } 140 145 }; … … 158 163 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 159 164 { 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)); 161 166 } 162 167 }; … … 180 185 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 181 186 { 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)); 183 188 } 184 189 }; … … 202 207 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 203 208 { 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)); 205 210 } 206 211 }; … … 224 229 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 225 230 { 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)); 227 232 } 228 233 }; … … 246 251 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 247 252 { 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)); 249 254 } 250 255 }; … … 274 279 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 275 280 { 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)); 277 282 } 278 283 }; … … 296 301 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 297 302 { 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)); 299 304 } 300 305 }; … … 318 323 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 319 324 { 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)); 321 326 } 322 327 }; … … 340 345 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 341 346 { 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)); 343 348 } 344 349 }; … … 362 367 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 363 368 { 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)); 365 370 } 366 371 }; … … 384 389 static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) 385 390 { 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)); 387 392 } 388 393 }; … … 399 404 }; 400 405 406 template<typename T> 407 struct 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 401 419 } // namespace WebCore -
trunk/Source/WebCore/bindings/js/JSDOMConvertUnion.h
r264751 r269940 226 226 // 1. If types includes ArrayBuffer, then return the result of converting V to ArrayBuffer. 227 227 // 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; 229 229 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); 231 231 if (arrayBuffer) { 232 232 if (hasArrayBufferType) … … 236 236 } 237 237 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; 239 239 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); 241 241 if (arrayBufferView) { 242 242 if (hasArrayBufferViewType) … … 406 406 }; 407 407 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. 410 template<> 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 408 417 } // namespace WebCore -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp
r269381 r269940 76 76 #include <JavaScriptCore/JSSetIterator.h> 77 77 #include <JavaScriptCore/JSTypedArrays.h> 78 #include <JavaScriptCore/JSWebAssemblyMemory.h> 78 79 #include <JavaScriptCore/JSWebAssemblyModule.h> 79 80 #include <JavaScriptCore/ObjectConstructor.h> … … 183 184 BigIntTag = 47, 184 185 BigIntObjectTag = 48, 186 #if ENABLE(WEBASSEMBLY) 187 WasmMemoryTag = 49, 188 #endif 185 189 ErrorTag = 255 186 190 }; … … 358 362 * | ArrayBuffer 359 363 * | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLength:uint32_t> (ArrayBuffer | ObjectReference) 360 * | ArrayBufferTransferTag <value:uint32_t>361 364 * | CryptoKeyTag <wrappedKeyLength:uint32_t> <factor:byte{wrappedKeyLength}> 362 365 * | DOMPoint … … 368 371 * | ImageBitmapTag <originClean:uint8_t> <logicalWidth:int32_t> <logicalHeight:int32_t> <resolutionScale:double> <byteLength:uint32_t>(<imageByteData:uint8_t>) 369 372 * | OffscreenCanvasTransferTag <value:uint32_t> 373 * | WasmMemoryTag <value:uint32_t> 370 374 * 371 375 * Inside certificate, data is serialized in this format as per spec: … … 420 424 * ArrayBuffer :- 421 425 * ArrayBufferTag <length:uint32_t> <contents:byte{length}> 426 * ArrayBufferTransferTag <value:uint32_t> 427 * SharedArrayBufferTag <value:uint32_t> 422 428 * 423 429 * CryptoKeyHMAC :- … … 577 583 #if ENABLE(WEBASSEMBLY) 578 584 WasmModuleArray& wasmModules, 585 WasmMemoryHandleArray& wasmMemoryHandles, 579 586 #endif 580 587 Vector<String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers) … … 586 593 #if ENABLE(WEBASSEMBLY) 587 594 wasmModules, 595 wasmMemoryHandles, 588 596 #endif 589 597 blobURLs, out, context, sharedBuffers); … … 616 624 #if ENABLE(WEBASSEMBLY) 617 625 WasmModuleArray& wasmModules, 626 WasmMemoryHandleArray& wasmMemoryHandles, 618 627 #endif 619 628 Vector<String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers) … … 626 635 #if ENABLE(WEBASSEMBLY) 627 636 , m_wasmModules(wasmModules) 637 , m_wasmMemoryHandles(wasmMemoryHandles) 628 638 #endif 629 639 { … … 1231 1241 #if ENABLE(WEBASSEMBLY) 1232 1242 WasmModuleArray dummyModules; 1243 WasmMemoryHandleArray dummyMemoryHandles; 1233 1244 #endif 1234 1245 ArrayBufferContentsArray dummySharedBuffers; … … 1239 1250 #if ENABLE(WEBASSEMBLY) 1240 1251 dummyModules, 1252 dummyMemoryHandles, 1241 1253 #endif 1242 1254 dummyBlobURLs, serializedKey, SerializationContext::Default, dummySharedBuffers); … … 1272 1284 m_wasmModules.append(makeRef(module->module())); 1273 1285 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); 1274 1301 write(index); 1275 1302 return true; … … 1659 1686 #if ENABLE(WEBASSEMBLY) 1660 1687 WasmModuleArray& m_wasmModules; 1688 WasmMemoryHandleArray& m_wasmMemoryHandles; 1661 1689 #endif 1662 1690 }; … … 1938 1966 #if ENABLE(WEBASSEMBLY) 1939 1967 , WasmModuleArray* wasmModules 1968 , WasmMemoryHandleArray* wasmMemoryHandles 1940 1969 #endif 1941 1970 ) … … 1949 1978 #if ENABLE(WEBASSEMBLY) 1950 1979 , wasmModules 1980 , wasmMemoryHandles 1951 1981 #endif 1952 1982 ); … … 2002 2032 #if ENABLE(WEBASSEMBLY) 2003 2033 , WasmModuleArray* wasmModules = nullptr 2034 , WasmMemoryHandleArray* wasmMemoryHandles = nullptr 2004 2035 #endif 2005 2036 ) … … 2022 2053 #if ENABLE(WEBASSEMBLY) 2023 2054 , m_wasmModules(wasmModules) 2055 , m_wasmMemoryHandles(wasmMemoryHandles) 2024 2056 #endif 2025 2057 { … … 2034 2066 #if ENABLE(WEBASSEMBLY) 2035 2067 , WasmModuleArray* wasmModules 2068 , WasmMemoryHandleArray* wasmMemoryHandles 2036 2069 #endif 2037 2070 ) … … 2057 2090 #if ENABLE(WEBASSEMBLY) 2058 2091 , m_wasmModules(wasmModules) 2092 , m_wasmMemoryHandles(wasmMemoryHandles) 2059 2093 #endif 2060 2094 { … … 3300 3334 return result; 3301 3335 } 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 } 3302 3363 #endif 3303 3364 case ArrayBufferTag: { … … 3440 3501 #if ENABLE(WEBASSEMBLY) 3441 3502 WasmModuleArray* m_wasmModules; 3503 WasmMemoryHandleArray* m_wasmMemoryHandles; 3442 3504 #endif 3443 3505 … … 3662 3724 #if ENABLE(WEBASSEMBLY) 3663 3725 , std::unique_ptr<WasmModuleArray> wasmModulesArray 3726 , std::unique_ptr<WasmMemoryHandleArray> wasmMemoryHandlesArray 3664 3727 #endif 3665 3728 ) … … 3673 3736 #if ENABLE(WEBASSEMBLY) 3674 3737 , m_wasmModulesArray(WTFMove(wasmModulesArray)) 3738 , m_wasmMemoryHandlesArray(WTFMove(wasmMemoryHandlesArray)) 3675 3739 #endif 3676 3740 { … … 3711 3775 #if ENABLE(WEBASSEMBLY) 3712 3776 // We are not supporting WebAssembly Module memory estimation yet. 3777 if (m_wasmMemoryHandlesArray) { 3778 for (auto& content : *m_wasmMemoryHandlesArray) 3779 cost += content->size(); 3780 } 3713 3781 #endif 3714 3782 … … 3801 3869 #if ENABLE(WEBASSEMBLY) 3802 3870 WasmModuleArray dummyModules; 3871 WasmMemoryHandleArray dummyMemoryHandles; 3803 3872 #endif 3804 3873 ArrayBufferContentsArray dummySharedBuffers; … … 3809 3878 #if ENABLE(WEBASSEMBLY) 3810 3879 dummyModules, 3880 dummyMemoryHandles, 3811 3881 #endif 3812 3882 blobURLs, buffer, SerializationContext::Default, dummySharedBuffers); … … 3814 3884 #if ENABLE(WEBASSEMBLY) 3815 3885 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"); 3816 3887 #endif 3817 3888 … … 3860 3931 for (auto& transferable : transferList) { 3861 3932 if (auto arrayBuffer = toPossiblySharedArrayBuffer(vm, transferable.get())) { 3862 if (arrayBuffer->isDetached() )3933 if (arrayBuffer->isDetached() || arrayBuffer->isShared()) 3863 3934 return Exception { DataCloneError }; 3864 3935 if (arrayBuffer->isLocked()) { … … 3905 3976 #if ENABLE(WEBASSEMBLY) 3906 3977 WasmModuleArray wasmModules; 3978 WasmMemoryHandleArray wasmMemoryHandles; 3907 3979 #endif 3908 3980 std::unique_ptr<ArrayBufferContentsArray> sharedBuffers = makeUnique<ArrayBufferContentsArray>(); … … 3912 3984 #endif 3913 3985 #if ENABLE(WEBASSEMBLY) 3914 wasmModules, 3986 wasmModules, 3987 wasmMemoryHandles, 3915 3988 #endif 3916 3989 blobURLs, buffer, context, *sharedBuffers); … … 3937 4010 #if ENABLE(WEBASSEMBLY) 3938 4011 , makeUnique<WasmModuleArray>(wasmModules) 4012 , context == SerializationContext::WorkerPostMessage ? makeUnique<WasmMemoryHandleArray>(wasmMemoryHandles) : nullptr 3939 4013 #endif 3940 4014 )); … … 3994 4068 #if ENABLE(WEBASSEMBLY) 3995 4069 , m_wasmModulesArray.get() 4070 , m_wasmMemoryHandlesArray.get() 3996 4071 #endif 3997 4072 ); -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.h
r267615 r269940 42 42 namespace JSC { namespace Wasm { 43 43 class Module; 44 class MemoryHandle; 44 45 } } 45 46 #endif … … 62 63 #if ENABLE(WEBASSEMBLY) 63 64 using WasmModuleArray = Vector<RefPtr<JSC::Wasm::Module>>; 65 using WasmMemoryHandleArray = Vector<RefPtr<JSC::Wasm::MemoryHandle>>; 64 66 #endif 65 67 … … 123 125 #if ENABLE(WEBASSEMBLY) 124 126 , std::unique_ptr<WasmModuleArray> = nullptr 127 , std::unique_ptr<WasmMemoryHandleArray> = nullptr 125 128 #endif 126 129 ); … … 137 140 #if ENABLE(WEBASSEMBLY) 138 141 std::unique_ptr<WasmModuleArray> m_wasmModulesArray; 142 std::unique_ptr<WasmMemoryHandleArray> m_wasmMemoryHandlesArray; 139 143 #endif 140 144 Vector<String> m_blobURLs; -
trunk/Source/WebCore/bindings/js/WebCoreJSClientData.cpp
r267859 r269940 137 137 } 138 138 139 void JSVMClientData::initNormalWorld(VM* vm )139 void JSVMClientData::initNormalWorld(VM* vm, WorkerThreadType type) 140 140 { 141 141 JSVMClientData* clientData = new JSVMClientData(*vm); … … 145 145 146 146 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)); 148 148 } 149 149 -
trunk/Source/WebCore/bindings/js/WebCoreJSClientData.h
r267859 r269940 25 25 #include "WebCoreBuiltinNames.h" 26 26 #include "WebCoreJSBuiltins.h" 27 #include "WorkerThreadType.h" 27 28 #include <wtf/HashSet.h> 28 29 #include <wtf/RefPtr.h> … … 41 42 virtual ~JSVMClientData(); 42 43 43 WEBCORE_EXPORT static void initNormalWorld(JSC::VM* );44 WEBCORE_EXPORT static void initNormalWorld(JSC::VM*, WorkerThreadType); 44 45 45 46 DOMWrapperWorld& normalWorld() { return *m_normalWorld; } -
trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.cpp
r251425 r269940 35 35 namespace WebCore { 36 36 37 WebCoreTypedArrayController::WebCoreTypedArrayController() = default; 37 WebCoreTypedArrayController::WebCoreTypedArrayController(bool allowAtomicsWait) 38 : m_allowAtomicsWait(allowAtomicsWait) 39 { 40 } 38 41 39 42 WebCoreTypedArrayController::~WebCoreTypedArrayController() = default; … … 51 54 bool WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread() 52 55 { 53 return !isMainThread();56 return m_allowAtomicsWait; 54 57 } 55 58 -
trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.h
r251425 r269940 37 37 class WebCoreTypedArrayController : public JSC::TypedArrayController { 38 38 public: 39 WebCoreTypedArrayController( );39 WebCoreTypedArrayController(bool allowAtomicsWait); 40 40 virtual ~WebCoreTypedArrayController(); 41 41 … … 54 54 55 55 JSArrayBufferOwner m_owner; 56 bool m_allowAtomicsWait; 56 57 }; 57 58 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r269847 r269940 7000 7000 return 1 if $type->extendedAttributes->{AtomString}; 7001 7001 return 1 if $type->extendedAttributes->{RequiresExistingAtomString}; 7002 return 1 if $type->extendedAttributes->{AllowShared}; 7002 7003 } 7003 7004 … … 7011 7012 return "IDLAtomStringAdaptor" if $type->extendedAttributes->{AtomString}; 7012 7013 return "IDLRequiresExistingAtomStringAdaptor" if $type->extendedAttributes->{RequiresExistingAtomString}; 7014 return "IDLAllowSharedAdaptor" if $type->extendedAttributes->{AllowShared}; 7013 7015 } 7014 7016 -
trunk/Source/WebCore/bindings/scripts/IDLAttributes.json
r269314 r269940 25 25 "standard": { 26 26 "url": "https://heycam.github.io/webidl/#AllowShared" 27 }, 28 "unsupported": true 27 } 29 28 }, 30 29 "AppleCopyright": { -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
r268990 r269940 1603 1603 static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_double_leading_underscore_function); 1604 1604 static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_trailing_underscore_function_); 1605 static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_encodeInto); 1605 1606 static JSC_DECLARE_HOST_FUNCTION(jsTestObjPrototypeFunction_toString); 1606 1607 … … 2334 2335 { "_double_leading_underscore_function", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_double_leading_underscore_function), (intptr_t) (0) } }, 2335 2336 { "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) } }, 2336 2338 { "toString", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsTestObjPrototypeFunction_toString), (intptr_t) (0) } }, 2337 2339 #if ENABLE(Condition1) … … 9498 9500 } 9499 9501 9502 static 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 9517 JSC_DEFINE_HOST_FUNCTION(jsTestObjPrototypeFunction_encodeInto, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)) 9518 { 9519 return IDLOperation<JSTestObj>::call<jsTestObjPrototypeFunction_encodeIntoBody>(*lexicalGlobalObject, *callFrame, "encodeInto"); 9520 } 9521 9500 9522 static inline JSC::EncodedJSValue jsTestObjPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSTestObj>::ClassParameter castedThis) 9501 9523 { -
trunk/Source/WebCore/bindings/scripts/test/TestObj.idl
r268435 r269940 468 468 undefined __double_leading_underscore_function(); // NOTE: WebIDL removes the leading underscore so this is interpreted as "_double_leading_underscore_function" 469 469 undefined trailing_underscore_function_(); 470 471 boolean encodeInto([AllowShared] Uint8Array destination); 470 472 }; 471 473 -
trunk/Source/WebCore/dom/TextDecoder.idl
r267007 r269940 42 42 readonly attribute boolean fatal; 43 43 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); 45 45 }; -
trunk/Source/WebCore/dom/TextDecoderStreamDecoder.idl
r267007 r269940 33 33 34 34 [PrivateIdentifier] DOMString encoding(); 35 [PrivateIdentifier, MayThrowException] DOMString decode( BufferSource source);35 [PrivateIdentifier, MayThrowException] DOMString decode([AllowShared] BufferSource source); 36 36 [PrivateIdentifier, MayThrowException] DOMString flush(); 37 37 }; -
trunk/Source/WebCore/dom/TextEncoder.idl
r266621 r269940 40 40 41 41 [NewObject] Uint8Array encode(optional USVString input = ""); 42 TextEncoderEncodeIntoResult encodeInto(USVString source, Uint8Array destination);42 TextEncoderEncodeIntoResult encodeInto(USVString source, [AllowShared] Uint8Array destination); 43 43 }; -
trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp
r259298 r269940 58 58 59 59 DedicatedWorkerGlobalScope::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) 61 61 , m_name(params.name) 62 62 { -
trunk/Source/WebCore/workers/WorkerGlobalScope.cpp
r268900 r269940 60 60 WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerGlobalScope); 61 61 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)62 WorkerGlobalScope::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) 64 64 , m_url(params.scriptURL) 65 65 , m_identifier(params.identifier) -
trunk/Source/WebCore/workers/WorkerGlobalScope.h
r268900 r269940 127 127 128 128 protected: 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*); 130 130 131 131 void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&); -
trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp
r269227 r269940 38 38 WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerOrWorkletGlobalScope); 39 39 40 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope( Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread)41 : m_script(makeUnique<WorkerOrWorkletScriptController>( WTFMove(vm), this))40 WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(WorkerThreadType type, Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread) 41 : m_script(makeUnique<WorkerOrWorkletScriptController>(type, WTFMove(vm), this)) 42 42 , m_thread(thread) 43 43 , m_inspectorController(makeUnique<WorkerInspectorController>(*this)) -
trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h
r268900 r269940 28 28 #include "EventTarget.h" 29 29 #include "ScriptExecutionContext.h" 30 #include "WorkerThreadType.h" 30 31 31 32 namespace WebCore { … … 68 69 69 70 protected: 70 WorkerOrWorkletGlobalScope( Ref<JSC::VM>&&, WorkerOrWorkletThread*);71 WorkerOrWorkletGlobalScope(WorkerThreadType, Ref<JSC::VM>&&, WorkerOrWorkletThread*); 71 72 72 73 // ScriptExecutionContext. -
trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp
r268775 r269940 51 51 using namespace JSC; 52 52 53 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController( Ref<VM>&& vm, WorkerOrWorkletGlobalScope* globalScope)53 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(WorkerThreadType type, Ref<VM>&& vm, WorkerOrWorkletGlobalScope* globalScope) 54 54 : m_vm(WTFMove(vm)) 55 55 , m_globalScope(globalScope) … … 57 57 { 58 58 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(Worker OrWorkletGlobalScope* globalScope)63 : WorkerOrWorkletScriptController( JSC::VM::create(), globalScope)59 JSVMClientData::initNormalWorld(m_vm.get(), type); 60 } 61 62 WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(WorkerThreadType type, WorkerOrWorkletGlobalScope* globalScope) 63 : WorkerOrWorkletScriptController(type, JSC::VM::create(), globalScope) 64 64 { 65 65 } -
trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h
r268775 r269940 27 27 #pragma once 28 28 29 #include "WorkerThreadType.h" 29 30 #include <JavaScriptCore/Debugger.h> 30 31 #include <JavaScriptCore/JSRunLoopTimer.h> … … 52 53 WTF_MAKE_FAST_ALLOCATED; 53 54 public: 54 WorkerOrWorkletScriptController( Ref<JSC::VM>&&, WorkerOrWorkletGlobalScope*);55 explicit WorkerOrWorkletScriptController(Worker OrWorkletGlobalScope*);55 WorkerOrWorkletScriptController(WorkerThreadType, Ref<JSC::VM>&&, WorkerOrWorkletGlobalScope*); 56 explicit WorkerOrWorkletScriptController(WorkerThreadType, WorkerOrWorkletGlobalScope*); 56 57 ~WorkerOrWorkletScriptController(); 57 58 -
trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp
r260350 r269940 53 53 54 54 ServiceWorkerGlobalScope::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) 56 56 , m_contextData(crossThreadCopy(data)) 57 57 , m_registration(ServiceWorkerRegistration::getOrCreate(*this, navigator().serviceWorker(), WTFMove(m_contextData.registration))) -
trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp
r269221 r269940 51 51 52 52 WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, const WorkletParameters& parameters) 53 : WorkerOrWorkletGlobalScope( JSC::VM::create(), &thread)53 : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, JSC::VM::create(), &thread) 54 54 , m_topOrigin(SecurityOrigin::createUnique()) 55 55 , m_url(parameters.windowURL) … … 63 63 64 64 WorkletGlobalScope::WorkletGlobalScope(Document& document, Ref<JSC::VM>&& vm, ScriptSourceCode&& code) 65 : WorkerOrWorkletGlobalScope(W TFMove(vm), nullptr)65 : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, WTFMove(vm), nullptr) 66 66 , m_document(makeWeakPtr(document)) 67 67 , m_topOrigin(SecurityOrigin::createUnique())
Note: See TracChangeset
for help on using the changeset viewer.