Changeset 215103 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Apr 7, 2017, 11:25:14 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 added
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r215073 r215103 939 939 wasm/WasmCallee.cpp 940 940 wasm/WasmCallingConvention.cpp 941 wasm/WasmCodeBlock.cpp 941 942 wasm/WasmContext.cpp 942 943 wasm/WasmFaultSignalHandler.cpp … … 944 945 wasm/WasmMemory.cpp 945 946 wasm/WasmMemoryInformation.cpp 947 wasm/WasmModule.cpp 946 948 wasm/WasmModuleInformation.cpp 947 949 wasm/WasmModuleParser.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r215088 r215103 1 2017-04-07 Saam Barati <[email protected]> 2 3 WebAssembly: Make to a compilation API that allows for multi-VM concurrent compilations of Wasm Modules 4 https://bugs.webkit.org/show_bug.cgi?id=170488 5 6 Reviewed by JF Bastien. 7 8 This patch adds a class called Wasm::Module. It contains the bits from 9 JSWebAssemblyModule that were not VM specific. JSWebAssemblyModule 10 now has a Ref<Wasm::Module>. Similarly, there is now a Wasm::CodeBlock, 11 which owns the non-VM-specific bits that JSWebAssemblyCodeBlock used 12 to own. 13 14 This patch also simplifies how we verify and compile code. Wasm::Module 15 now has an API for both sync/async validation and compilation. This 16 API abstracts away how Wasm::Plan works. 17 18 This is hopefully the last patch needed before we can implement 19 window.postMessage for a JSWebAssemblyModule. I think all that's 20 needed now to implement postMessage is simply creating a new 21 JSWebAssemblyModule with the underlying Wasm::Module. 22 23 This patch is neutral on WasmBench. 24 25 Finally, this patch changes the promise deferred timer to 26 allow for new tasks to be added while we're executing 27 a task. Before, we'd deadlock if this happened. 28 29 * CMakeLists.txt: 30 * JavaScriptCore.xcodeproj/project.pbxproj: 31 * jsc.cpp: 32 (functionTestWasmModuleFunctions): 33 * runtime/PromiseDeferredTimer.cpp: 34 (JSC::PromiseDeferredTimer::doWork): 35 (JSC::PromiseDeferredTimer::scheduleWorkSoon): 36 * runtime/PromiseDeferredTimer.h: 37 * wasm/WasmB3IRGenerator.cpp: 38 * wasm/WasmBinding.cpp: 39 (JSC::Wasm::wasmToJs): 40 (JSC::Wasm::wasmToWasm): 41 (JSC::Wasm::exitStubGenerator): Deleted. 42 * wasm/WasmBinding.h: 43 * wasm/WasmCodeBlock.cpp: Added. 44 (JSC::Wasm::CodeBlock::CodeBlock): 45 (JSC::Wasm::CodeBlock::waitUntilFinished): 46 (JSC::Wasm::CodeBlock::compileAsync): 47 (JSC::Wasm::CodeBlock::isSafeToRun): 48 * wasm/WasmCodeBlock.h: Added. 49 (JSC::Wasm::CodeBlock::create): 50 (JSC::Wasm::CodeBlock::compilationFinished): 51 (JSC::Wasm::CodeBlock::runnable): 52 (JSC::Wasm::CodeBlock::errorMessage): 53 (JSC::Wasm::CodeBlock::functionImportCount): 54 (JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace): 55 (JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace): 56 * wasm/WasmModule.cpp: Added. 57 (JSC::Wasm::Module::Module): 58 (JSC::Wasm::makeValidationResult): 59 (JSC::Wasm::Module::validateSyncImpl): 60 (JSC::Wasm::Module::getOrCreateCodeBlock): 61 (JSC::Wasm::Module::compileSync): 62 (JSC::Wasm::Module::makeValidationCallback): 63 (JSC::Wasm::Module::compileAsync): 64 * wasm/WasmModule.h: Added. 65 (JSC::Wasm::Module::create): 66 (JSC::Wasm::Module::validateSync): 67 (JSC::Wasm::Module::validateAsync): 68 (JSC::Wasm::Module::signatureIndexFromFunctionIndexSpace): 69 (JSC::Wasm::Module::moduleInformation): 70 (JSC::Wasm::Module::nonNullCodeBlock): 71 * wasm/WasmPlan.cpp: 72 (JSC::Wasm::Plan::Plan): 73 (JSC::Wasm::Plan::addCompletionTask): 74 (JSC::Wasm::Plan::prepare): 75 (JSC::Wasm::Plan::compileFunctions): 76 (JSC::Wasm::Plan::complete): 77 (JSC::Wasm::Plan::tryRemoveVMAndCancelIfLast): 78 (JSC::Wasm::Plan::cancel): Deleted. 79 * wasm/WasmPlan.h: 80 (JSC::Wasm::Plan::dontFinalize): 81 (JSC::Wasm::Plan::takeWasmToWasmExitStubs): 82 (JSC::Wasm::Plan::mode): 83 (JSC::Wasm::Plan::takeWasmExitStubs): Deleted. 84 (JSC::Wasm::Plan::vm): Deleted. 85 * wasm/WasmWorklist.cpp: 86 (JSC::Wasm::Worklist::stopAllPlansForVM): 87 * wasm/js/JSWebAssemblyCodeBlock.cpp: 88 (JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock): 89 (JSC::JSWebAssemblyCodeBlock::isSafeToRun): 90 (JSC::JSWebAssemblyCodeBlock::initialize): Deleted. 91 * wasm/js/JSWebAssemblyCodeBlock.h: 92 (JSC::JSWebAssemblyCodeBlock::create): 93 (JSC::JSWebAssemblyCodeBlock::functionImportCount): 94 (JSC::JSWebAssemblyCodeBlock::jsEntrypointCalleeFromFunctionIndexSpace): 95 (JSC::JSWebAssemblyCodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace): 96 (JSC::JSWebAssemblyCodeBlock::wasmToJsCallStubForImport): 97 (JSC::JSWebAssemblyCodeBlock::mode): Deleted. 98 (JSC::JSWebAssemblyCodeBlock::initialized): Deleted. 99 (JSC::JSWebAssemblyCodeBlock::plan): Deleted. 100 (JSC::JSWebAssemblyCodeBlock::runnable): Deleted. 101 (JSC::JSWebAssemblyCodeBlock::errorMessage): Deleted. 102 (JSC::JSWebAssemblyCodeBlock::setJSEntrypointCallee): Deleted. 103 (JSC::JSWebAssemblyCodeBlock::setWasmEntrypointCallee): Deleted. 104 * wasm/js/JSWebAssemblyInstance.cpp: 105 (JSC::JSWebAssemblyInstance::finalizeCreation): 106 (JSC::JSWebAssemblyInstance::addUnitializedCodeBlock): Deleted. 107 * wasm/js/JSWebAssemblyInstance.h: 108 (JSC::JSWebAssemblyInstance::initialized): Deleted. 109 * wasm/js/JSWebAssemblyModule.cpp: 110 (JSC::JSWebAssemblyModule::createStub): 111 (JSC::JSWebAssemblyModule::JSWebAssemblyModule): 112 (JSC::JSWebAssemblyModule::finishCreation): 113 * wasm/js/JSWebAssemblyModule.h: 114 (JSC::JSWebAssemblyModule::moduleInformation): 115 (JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace): 116 (JSC::JSWebAssemblyModule::module): 117 * wasm/js/WebAssemblyFunction.cpp: 118 (JSC::WebAssemblyFunction::create): 119 * wasm/js/WebAssemblyInstanceConstructor.cpp: 120 (JSC::constructJSWebAssemblyInstance): 121 * wasm/js/WebAssemblyModuleConstructor.cpp: 122 (JSC::WebAssemblyModuleConstructor::createModule): 123 * wasm/js/WebAssemblyPrototype.cpp: 124 (JSC::reject): 125 (JSC::webAssemblyCompileFunc): 126 (JSC::resolve): 127 (JSC::instantiate): 128 (JSC::compileAndInstantiate): 129 (JSC::webAssemblyValidateFunc): 130 1 131 2017-04-07 Carlos Garcia Campos <[email protected]> 2 132 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r215073 r215103 1322 1322 52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1323 1323 52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1324 526AC4B61E977C5D003500E1 /* WasmCodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 526AC4B41E977C5D003500E1 /* WasmCodeBlock.cpp */; }; 1325 526AC4B71E977C5D003500E1 /* WasmCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1324 1326 527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */; }; 1325 1327 52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1491 1493 72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */; }; 1492 1494 78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */; }; 1495 790081381E95A8EC0052D7CD /* WasmModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 790081361E95A8EC0052D7CD /* WasmModule.cpp */; }; 1496 790081391E95A8EC0052D7CD /* WasmModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 790081371E95A8EC0052D7CD /* WasmModule.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1493 1497 7905BB681D12050E0019FE57 /* InlineAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7905BB661D12050E0019FE57 /* InlineAccess.cpp */; }; 1494 1498 7905BB691D12050E0019FE57 /* InlineAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 7905BB671D12050E0019FE57 /* InlineAccess.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3832 3836 52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; }; 3833 3837 52678F901A04177C006A306D /* ControlFlowProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlFlowProfiler.h; sourceTree = "<group>"; }; 3838 526AC4B41E977C5D003500E1 /* WasmCodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCodeBlock.cpp; sourceTree = "<group>"; }; 3839 526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCodeBlock.h; sourceTree = "<group>"; }; 3834 3840 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; }; 3835 3841 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = "<group>"; }; … … 4044 4050 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterSetterFunction.h; sourceTree = "<group>"; }; 4045 4051 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleLoader.h; sourceTree = "<group>"; }; 4052 790081361E95A8EC0052D7CD /* WasmModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModule.cpp; sourceTree = "<group>"; }; 4053 790081371E95A8EC0052D7CD /* WasmModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmModule.h; sourceTree = "<group>"; }; 4046 4054 7905BB661D12050E0019FE57 /* InlineAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineAccess.cpp; sourceTree = "<group>"; }; 4047 4055 7905BB671D12050E0019FE57 /* InlineAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineAccess.h; sourceTree = "<group>"; }; … … 6322 6330 53FD04D11D7AB187003287D3 /* WasmCallingConvention.cpp */, 6323 6331 53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */, 6332 526AC4B41E977C5D003500E1 /* WasmCodeBlock.cpp */, 6333 526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */, 6324 6334 AD412B311E7B2E8A008AF157 /* WasmContext.cpp */, 6325 6335 AD412B321E7B2E8A008AF157 /* WasmContext.h */, … … 6328 6338 7BC547D21B69599B00959B58 /* WasmFormat.h */, 6329 6339 53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */, 6340 790081361E95A8EC0052D7CD /* WasmModule.cpp */, 6341 790081371E95A8EC0052D7CD /* WasmModule.h */, 6330 6342 535557151D9DFA32006D583B /* WasmMemory.cpp */, 6331 6343 535557131D9D9EA5006D583B /* WasmMemory.h */, … … 8775 8787 0F070A491D543A93006E7232 /* HeapCellInlines.h in Headers */, 8776 8788 0F32BD111BB34F190093A57F /* HeapHelperPool.h in Headers */, 8789 526AC4B71E977C5D003500E1 /* WasmCodeBlock.h in Headers */, 8777 8790 C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */, 8778 8791 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */, … … 8923 8936 BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */, 8924 8937 A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */, 8938 790081391E95A8EC0052D7CD /* WasmModule.h in Headers */, 8925 8939 A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */, 8926 8940 0FF4B4C71E8893C500DBBE86 /* AirCFG.h in Headers */, … … 10367 10381 0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */, 10368 10382 0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */, 10383 790081381E95A8EC0052D7CD /* WasmModule.cpp in Sources */, 10369 10384 0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */, 10370 10385 0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */, … … 10547 10562 140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */, 10548 10563 70B7919B1C024A46002481E2 /* JSGeneratorFunction.cpp in Sources */, 10564 526AC4B61E977C5D003500E1 /* WasmCodeBlock.cpp in Sources */, 10549 10565 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */, 10550 10566 147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */, -
trunk/Source/JavaScriptCore/jsc.cpp
r214936 r215103 3192 3192 CRASH(); 3193 3193 3194 Ref<Wasm::Plan> plan = adoptRef(*new Wasm::Plan(vm, static_cast<uint8_t*>(source->vector()), source->length(), Wasm::Plan::FullCompile, Wasm::Plan::dontFinalize ));3194 Ref<Wasm::Plan> plan = adoptRef(*new Wasm::Plan(vm, static_cast<uint8_t*>(source->vector()), source->length(), Wasm::Plan::FullCompile, Wasm::Plan::dontFinalize())); 3195 3195 Wasm::ensureWorklist().enqueue(plan.copyRef()); 3196 3196 Wasm::ensureWorklist().completePlanSynchronously(plan.get()); -
trunk/Source/JavaScriptCore/runtime/PromiseDeferredTimer.cpp
r214970 r215103 45 45 { 46 46 ASSERT(m_vm->currentThreadIsHoldingAPILock()); 47 LockHolder locker(m_taskLock);47 m_taskLock.lock(); 48 48 cancelTimer(); 49 if (!m_runTasks) 49 if (!m_runTasks) { 50 m_taskLock.unlock(); 50 51 return; 52 } 51 53 52 54 while (!m_tasks.isEmpty()) { … … 58 60 // We may have already canceled these promises. 59 61 if (m_pendingPromises.contains(ticket)) { 62 // Allow tasks we run now to schedule work. 63 m_currentlyRunningTask = true; 64 m_taskLock.unlock(); 65 60 66 task(); 61 67 m_vm->drainMicrotasks(); 68 69 m_taskLock.lock(); 70 m_currentlyRunningTask = false; 62 71 } 63 72 } 64 73 65 if (m_pendingPromises.isEmpty() && m_shouldStopRunLoopWhenAllPromisesFinish) 74 if (m_pendingPromises.isEmpty() && m_shouldStopRunLoopWhenAllPromisesFinish) { 66 75 #if USE(CF) 67 76 CFRunLoopStop(m_runLoop.get()); … … 69 78 RunLoop::current().stop(); 70 79 #endif 80 } 81 82 m_taskLock.unlock(); 71 83 } 72 84 … … 122 134 LockHolder locker(m_taskLock); 123 135 m_tasks.append(std::make_tuple(ticket, WTFMove(task))); 124 if (!isScheduled() )136 if (!isScheduled() && !m_currentlyRunningTask) 125 137 scheduleTimer(0); 126 138 } -
trunk/Source/JavaScriptCore/runtime/PromiseDeferredTimer.h
r214970 r215103 65 65 bool m_runTasks { true }; 66 66 bool m_shouldStopRunLoopWhenAllPromisesFinish { false }; 67 bool m_currentlyRunningTask { false }; 67 68 Vector<std::tuple<JSPromiseDeferred*, Task>> m_tasks; 68 69 }; -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r214950 r215103 937 937 // We need to clobber all potential pinned registers since we might be leaving the instance. 938 938 patchpoint->clobberLate(PinnedRegisterInfo::get().toSave()); 939 patchpoint->setGenerator([ unlinkedWasmToWasmCalls,functionIndex, returnType] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {939 patchpoint->setGenerator([functionIndex, returnType] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 940 940 AllowMacroScratchRegisterUsage allowScratch(jit); 941 941 jit.call(params[returnType == Void ? 0 : 1].gpr()); -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r214905 r215103 50 50 } 51 51 52 staticMacroAssemblerCodeRef wasmToJs(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)52 MacroAssemblerCodeRef wasmToJs(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex) 53 53 { 54 54 // FIXME: This function doesn't properly abstract away the calling convention. … … 423 423 } 424 424 425 staticMacroAssemblerCodeRef wasmToWasm(unsigned importIndex)425 MacroAssemblerCodeRef wasmToWasm(unsigned importIndex) 426 426 { 427 427 const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get(); … … 463 463 } 464 464 465 WasmExitStubs exitStubGenerator(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)466 {467 WasmExitStubs stubs;468 stubs.wasmToJs = wasmToJs(vm, callLinkInfos, signatureIndex, importIndex);469 stubs.wasmToWasm = wasmToWasm(importIndex);470 return stubs;471 }472 473 465 } } // namespace JSC::Wasm 474 466 -
trunk/Source/JavaScriptCore/wasm/WasmBinding.h
r210229 r215103 39 39 namespace Wasm { 40 40 41 WasmExitStubs exitStubGenerator(VM*, Bag<CallLinkInfo>&, SignatureIndex, unsigned); 41 MacroAssemblerCodeRef wasmToWasm(unsigned importIndex); 42 MacroAssemblerCodeRef wasmToJs(VM*, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex, unsigned importIndex); 42 43 43 44 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp
r214970 r215103 53 53 Plan::Plan(VM& vm, Ref<ModuleInformation> info, AsyncWork work, CompletionTask&& task) 54 54 : m_moduleInformation(WTFMove(info)) 55 , m_vm(vm)56 55 , m_source(m_moduleInformation->source.data()) 57 56 , m_sourceLength(m_moduleInformation->source.size()) … … 59 58 , m_asyncWork(work) 60 59 { 61 m_completionTasks.append( WTFMove(task));60 m_completionTasks.append(std::make_pair(&vm, WTFMove(task))); 62 61 } 63 62 … … 70 69 Plan::Plan(VM& vm, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task) 71 70 : m_moduleInformation(makeRef(*new ModuleInformation(Vector<uint8_t>()))) 72 , m_vm(vm)73 71 , m_source(source) 74 72 , m_sourceLength(sourceLength) … … 76 74 , m_asyncWork(work) 77 75 { 78 m_completionTasks.append( WTFMove(task));76 m_completionTasks.append(std::make_pair(&vm, WTFMove(task))); 79 77 } 80 78 … … 105 103 } 106 104 107 void Plan::addCompletionTask( CompletionTask&& task)105 void Plan::addCompletionTask(VM& vm, CompletionTask&& task) 108 106 { 109 107 LockHolder locker(m_lock); 110 108 if (m_state != State::Completed) 111 m_completionTasks.append( WTFMove(task));109 m_completionTasks.append(std::make_pair(&vm, WTFMove(task))); 112 110 else 113 task (*this);111 task->run(vm, *this); 114 112 } 115 113 … … 183 181 184 182 const auto& functionLocations = m_moduleInformation->functionLocationInBinary; 185 if (!tryReserveCapacity(m_wasm ExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")183 if (!tryReserveCapacity(m_wasmToWasmExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs") 186 184 || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, functionLocations.size(), " unlinked WebAssembly to WebAssembly calls") 187 185 || !tryReserveCapacity(m_wasmInternalFunctions, functionLocations.size(), " WebAssembly functions") … … 197 195 if (import->kind != ExternalKind::Function) 198 196 continue; 199 unsigned importFunctionIndex = m_wasm ExitStubs.size();197 unsigned importFunctionIndex = m_wasmToWasmExitStubs.size(); 200 198 dataLogLnIf(verbose, "Processing import function number ", importFunctionIndex, ": ", makeString(import->module), ": ", makeString(import->field)); 201 SignatureIndex signatureIndex = m_moduleInformation->importFunctionSignatureIndices.at(import->kindIndex); 202 m_wasmExitStubs.uncheckedAppend(exitStubGenerator(&m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex)); 199 m_wasmToWasmExitStubs.uncheckedAppend(wasmToWasm(importFunctionIndex)); 203 200 } 204 201 … … 261 258 SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex]; 262 259 const Signature& signature = SignatureInformation::get(signatureIndex); 263 unsigned functionIndexSpace = m_wasm ExitStubs.size() + functionIndex;260 unsigned functionIndexSpace = m_wasmToWasmExitStubs.size() + functionIndex; 264 261 ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex); 265 262 ASSERT(validateFunction(functionStart, functionLength, signature, m_moduleInformation.get())); … … 317 314 if (m_moduleInformation->isImportedFunctionFromFunctionIndexSpace(call.functionIndex)) { 318 315 // FIXME imports could have been linked in B3, instead of generating a patchpoint. This condition should be replaced by a RELEASE_ASSERT. https://bugs.webkit.org/show_bug.cgi?id=166462 319 executableAddress = m_wasm ExitStubs.at(call.functionIndex).wasmToWasm.code().executableAddress();316 executableAddress = m_wasmToWasmExitStubs.at(call.functionIndex).code().executableAddress(); 320 317 } else 321 executableAddress = m_wasmInternalFunctions.at(call.functionIndex - m_wasm ExitStubs.size())->wasmEntrypoint.compilation->code().executableAddress();318 executableAddress = m_wasmInternalFunctions.at(call.functionIndex - m_wasmToWasmExitStubs.size())->wasmEntrypoint.compilation->code().executableAddress(); 322 319 MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(executableAddress)); 323 320 } … … 328 325 moveToState(State::Completed); 329 326 for (auto& task : m_completionTasks) 330 task (*this);327 task.second->run(*task.first, *this); 331 328 m_completed.notifyAll(); 332 329 } … … 342 339 } 343 340 344 void Plan::cancel()341 bool Plan::tryRemoveVMAndCancelIfLast(VM& vm) 345 342 { 346 343 LockHolder locker(m_lock); 347 if (m_state != State::Completed) { 344 345 bool removedAnyTasks = false; 346 m_completionTasks.removeAllMatching([&] (const std::pair<VM*, CompletionTask>& pair) { 347 bool shouldRemove = pair.first == &vm; 348 removedAnyTasks |= shouldRemove; 349 return shouldRemove; 350 }); 351 352 if (!removedAnyTasks) 353 return false; 354 355 if (m_state == State::Completed) { 356 // We trivially cancel anything that's completed. 357 return true; 358 } 359 360 if (m_completionTasks.isEmpty()) { 348 361 m_currentIndex = m_moduleInformation->functionLocationInBinary.size(); 349 fail(locker, ASCIILiteral("WebAssembly Plan was canceled. If you see this error message please file a bug at bugs.webkit.org!")); 350 } 362 fail(locker, ASCIILiteral("WebAssembly Plan was cancelled. If you see this error message please file a bug at bugs.webkit.org!")); 363 return true; 364 } 365 366 return false; 351 367 } 352 368 -
trunk/Source/JavaScriptCore/wasm/WasmPlan.h
r214970 r215103 33 33 #include "WasmModuleInformation.h" 34 34 #include <wtf/Bag.h> 35 #include <wtf/SharedTask.h> 35 36 #include <wtf/ThreadSafeRefCounted.h> 36 37 #include <wtf/Vector.h> … … 46 47 class Plan : public ThreadSafeRefCounted<Plan> { 47 48 public: 48 static void dontFinalize(Plan&) { } 49 typedef std::function<void(Plan&)> CompletionTask; 49 typedef void CallbackType(VM&, Plan&); 50 using CompletionTask = RefPtr<SharedTask<CallbackType>>; 51 static CompletionTask dontFinalize() { return createSharedTask<CallbackType>([](VM&, Plan&) { }); } 50 52 enum AsyncWork : uint8_t { FullCompile, Validation }; 51 53 // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle. … … 57 59 JS_EXPORT_PRIVATE ~Plan(); 58 60 59 void addCompletionTask(CompletionTask&&); 61 // If you guarantee the ordering here, you can rely on FIFO of the 62 // completion tasks being called. 63 void addCompletionTask(VM&, CompletionTask&&); 60 64 61 65 bool parseAndValidateModule(); … … 92 96 } 93 97 94 Vector< WasmExitStubs>&& takeWasmExitStubs()98 Vector<MacroAssemblerCodeRef>&& takeWasmToWasmExitStubs() 95 99 { 96 100 RELEASE_ASSERT(!failed() && !hasWork()); 97 return WTFMove(m_wasm ExitStubs);101 return WTFMove(m_wasmToWasmExitStubs); 98 102 } 99 103 100 104 void setMode(MemoryMode mode) { m_mode = mode; } 101 105 MemoryMode mode() const { return m_mode; } 102 VM& vm() const { return m_vm; }103 106 104 107 enum class State : uint8_t { … … 117 120 118 121 void waitForCompletion(); 119 void cancel(); 122 // Returns true if it cancelled the plan. 123 bool tryRemoveVMAndCancelIfLast(VM&); 120 124 121 125 private: … … 132 136 Ref<ModuleInformation> m_moduleInformation; 133 137 Bag<CallLinkInfo> m_callLinkInfos; 134 Vector< WasmExitStubs> m_wasmExitStubs;138 Vector<MacroAssemblerCodeRef> m_wasmToWasmExitStubs; 135 139 Vector<std::unique_ptr<WasmInternalFunction>> m_wasmInternalFunctions; 136 140 Vector<CompilationContext> m_compilationContexts; 137 141 138 VM& m_vm; 139 Vector<CompletionTask, 1> m_completionTasks; 142 Vector<std::pair<VM*, CompletionTask>, 1> m_completionTasks; 140 143 141 144 Vector<Vector<UnlinkedWasmToWasmCall>> m_unlinkedWasmToWasmCalls; -
trunk/Source/JavaScriptCore/wasm/WasmWorklist.cpp
r214970 r215103 218 218 LockHolder locker(*m_lock); 219 219 iterate(locker, [&] (QueueElement& element) { 220 if (&element.plan->vm() == &vm) {221 element.plan->cancel();220 bool didCancel = element.plan->tryRemoveVMAndCancelIfLast(vm); 221 if (didCancel) 222 222 return IterateResult::DropAndContinue; 223 }224 223 return IterateResult::Continue; 225 224 }); 226 225 227 226 for (auto& thread : m_threads) { 228 if (thread->element.plan && &thread->element.plan->vm() == &vm) { 229 // We don't have to worry about the deadlocking since the thread can't block without clearing the plan and must hold the lock to do so. 230 thread->element.plan->cancel(); 231 thread->synchronize.wait(*m_lock); 227 if (thread->element.plan) { 228 bool didCancel = thread->element.plan->tryRemoveVMAndCancelIfLast(vm); 229 if (didCancel) { 230 // We don't have to worry about the deadlocking since the thread can't block without clearing the plan and must hold the lock to do so. 231 thread->synchronize.wait(*m_lock); 232 } 232 233 } 233 234 } -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.cpp
r214905 r215103 33 33 #include "JSWebAssemblyMemory.h" 34 34 #include "JSWebAssemblyModule.h" 35 #include "WasmBinding.h" 35 36 #include "WasmPlanInlines.h" 37 38 #include <wtf/CurrentTime.h> 36 39 37 40 namespace JSC { … … 39 42 const ClassInfo JSWebAssemblyCodeBlock::s_info = { "WebAssemblyCodeBlock", nullptr, 0, CREATE_METHOD_TABLE(JSWebAssemblyCodeBlock) }; 40 43 41 JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock(VM& vm, JSWebAssemblyModule* owner, Wasm::MemoryMode mode, Ref<Wasm::Plan>&& plan, unsigned calleeCount)44 JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock(VM& vm, Ref<Wasm::CodeBlock>&& codeBlock, const Wasm::ModuleInformation& moduleInformation) 42 45 : Base(vm, vm.webAssemblyCodeBlockStructure.get()) 43 , m_plan(WTFMove(plan)) 44 , m_mode(mode) 45 , m_calleeCount(calleeCount) 46 , m_codeBlock(WTFMove(codeBlock)) 46 47 { 47 m_module.set(vm, this, owner); 48 ASSERT(!module()->codeBlock(mode)); 49 module()->setCodeBlock(vm, mode, this); 50 m_callees.resize(m_calleeCount * 2); 51 } 52 53 void JSWebAssemblyCodeBlock::initialize() 54 { 55 if (initialized()) 56 return; 57 58 VM& vm = plan().vm(); 59 ASSERT_UNUSED(vm, vm.currentThreadIsHoldingAPILock()); 60 RELEASE_ASSERT(!plan().hasWork()); 61 62 if (plan().failed()) { 63 m_errorMessage = plan().errorMessage(); 64 m_plan = nullptr; 65 return; 48 // FIXME: We should not need to do this synchronously. 49 // https://bugs.webkit.org/show_bug.cgi?id=170567 50 m_wasmToJSExitStubs.reserveCapacity(m_codeBlock->functionImportCount()); 51 for (unsigned importIndex = 0; importIndex < m_codeBlock->functionImportCount(); ++importIndex) { 52 Wasm::SignatureIndex signatureIndex = moduleInformation.importFunctionSignatureIndices.at(importIndex); 53 m_wasmToJSExitStubs.uncheckedAppend(Wasm::wasmToJs(&vm, m_callLinkInfos, signatureIndex, importIndex)); 54 importWasmToJSStub(importIndex) = m_wasmToJSExitStubs[importIndex].code().executableAddress(); 66 55 } 67 68 RELEASE_ASSERT(plan().mode() == mode());69 ASSERT(plan().internalFunctionCount() == m_calleeCount);70 71 m_callLinkInfos = plan().takeCallLinkInfos();72 m_wasmExitStubs = plan().takeWasmExitStubs();73 74 // The code a module emits to call into JS relies on us to set this up.75 for (unsigned i = 0; i < m_wasmExitStubs.size(); i++)76 importWasmToJSStub(i) = m_wasmExitStubs[i].wasmToJs.code().executableAddress();77 78 plan().initializeCallees([&] (unsigned calleeIndex, Ref<Wasm::Callee>&& jsEntrypointCallee, Ref<Wasm::Callee>&& wasmEntrypointCallee) {79 setJSEntrypointCallee(calleeIndex, WTFMove(jsEntrypointCallee));80 setWasmEntrypointCallee(calleeIndex, WTFMove(wasmEntrypointCallee));81 });82 83 m_plan = nullptr;84 56 } 85 57 … … 91 63 bool JSWebAssemblyCodeBlock::isSafeToRun(JSWebAssemblyMemory* memory) const 92 64 { 93 if (!runnable()) 94 return false; 95 96 Wasm::MemoryMode codeMode = mode(); 97 Wasm::MemoryMode memoryMode = memory->memory().mode(); 98 switch (codeMode) { 99 case Wasm::MemoryMode::BoundsChecking: 100 return true; 101 case Wasm::MemoryMode::Signaling: 102 // Code being in Signaling mode means that it performs no bounds checks. 103 // Its memory, even if empty, absolutely must also be in Signaling mode 104 // because the page protection detects out-of-bounds accesses. 105 return memoryMode == Wasm::MemoryMode::Signaling; 106 case Wasm::MemoryMode::NumberOfMemoryModes: 107 break; 108 } 109 RELEASE_ASSERT_NOT_REACHED(); 110 return false; 65 return m_codeBlock->isSafeToRun(memory->memory().mode()); 111 66 } 112 67 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.h
r214905 r215103 34 34 #include "WasmCallee.h" 35 35 #include "WasmFormat.h" 36 #include "WasmModule.h" 36 37 #include <wtf/Bag.h> 37 38 #include <wtf/Vector.h> … … 51 52 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 52 53 53 static JSWebAssemblyCodeBlock* create(VM& vm, JSWebAssemblyModule* owner, Wasm::MemoryMode mode, Ref<Wasm::Plan>&& plan, unsigned calleeCount, unsigned functionImportCount)54 static JSWebAssemblyCodeBlock* create(VM& vm, Ref<Wasm::CodeBlock> codeBlock, const Wasm::ModuleInformation& moduleInformation) 54 55 { 55 auto* result = new (NotNull, allocateCell<JSWebAssemblyCodeBlock>(vm.heap, allocationSize( functionImportCount))) JSWebAssemblyCodeBlock(vm, owner, mode, WTFMove(plan), calleeCount);56 auto* result = new (NotNull, allocateCell<JSWebAssemblyCodeBlock>(vm.heap, allocationSize(moduleInformation.importFunctionCount()))) JSWebAssemblyCodeBlock(vm, WTFMove(codeBlock), moduleInformation); 56 57 result->finishCreation(vm); 57 58 return result; … … 63 64 } 64 65 65 unsigned functionImportCount() const { return m_wasmExitStubs.size(); } 66 Wasm::MemoryMode mode() const { return m_mode; } 66 unsigned functionImportCount() const { return m_codeBlock->functionImportCount(); } 67 67 JSWebAssemblyModule* module() const { return m_module.get(); } 68 68 69 // Don't call intialize directly, this should be called for you, as needed, by JSWebAssemblyInstance::finalizeCreation.70 void initialize();71 bool initialized() const { return !m_plan; }72 73 Wasm::Plan& plan() const { ASSERT(!initialized()); return *m_plan; }74 75 bool runnable() const { return initialized() && !m_errorMessage; }76 String& errorMessage() { ASSERT(!runnable()); return m_errorMessage; }77 69 bool isSafeToRun(JSWebAssemblyMemory*) const; 78 70 79 71 // These two callee getters are only valid once the callees have been populated. 72 80 73 Wasm::Callee& jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace) 81 74 { 82 RELEASE_ASSERT(functionIndexSpace >= functionImportCount()); 83 unsigned calleeIndex = functionIndexSpace - functionImportCount(); 84 RELEASE_ASSERT(calleeIndex < m_calleeCount); 85 return *m_callees[calleeIndex].get(); 75 return m_codeBlock->jsEntrypointCalleeFromFunctionIndexSpace(functionIndexSpace); 86 76 } 87 77 Wasm::Callee& wasmEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace) 88 78 { 89 RELEASE_ASSERT(functionIndexSpace >= functionImportCount()); 90 unsigned calleeIndex = functionIndexSpace - functionImportCount(); 91 RELEASE_ASSERT(calleeIndex < m_calleeCount); 92 return *m_callees[calleeIndex + m_calleeCount].get(); 79 return m_codeBlock->wasmEntrypointCalleeFromFunctionIndexSpace(functionIndexSpace); 93 80 } 94 81 95 82 void* wasmToJsCallStubForImport(unsigned importIndex) 96 83 { 97 RELEASE_ASSERT(importIndex < m_wasmExitStubs.size()); 98 return m_wasmExitStubs[importIndex].wasmToJs.code().executableAddress(); 84 return importWasmToJSStub(importIndex); 99 85 } 100 86 … … 105 91 106 92 private: 107 void setJSEntrypointCallee(unsigned calleeIndex, Ref<Wasm::Callee>&& callee) 108 { 109 RELEASE_ASSERT(calleeIndex < m_calleeCount); 110 m_callees[calleeIndex] = WTFMove(callee); 111 } 112 void setWasmEntrypointCallee(unsigned calleeIndex, Ref<Wasm::Callee>&& callee) 113 { 114 RELEASE_ASSERT(calleeIndex < m_calleeCount); 115 m_callees[calleeIndex + m_calleeCount] = WTFMove(callee); 116 } 117 118 JSWebAssemblyCodeBlock(VM&, JSWebAssemblyModule*, Wasm::MemoryMode, Ref<Wasm::Plan>&&, unsigned calleeCount); 93 JSWebAssemblyCodeBlock(VM&, Ref<Wasm::CodeBlock>&&, const Wasm::ModuleInformation&); 119 94 DECLARE_EXPORT_INFO; 120 95 static const bool needsDestruction = true; … … 142 117 143 118 WriteBarrier<JSWebAssemblyModule> m_module; 119 Ref<Wasm::CodeBlock> m_codeBlock; 120 Vector<MacroAssemblerCodeRef> m_wasmToJSExitStubs; 144 121 UnconditionalFinalizer m_unconditionalFinalizer; 145 122 Bag<CallLinkInfo> m_callLinkInfos; 146 Vector<Wasm::WasmExitStubs> m_wasmExitStubs;147 Vector<RefPtr<Wasm::Callee>> m_callees;148 // The plan that is compiling this code block.149 RefPtr<Wasm::Plan> m_plan;150 String m_errorMessage;151 Wasm::MemoryMode m_mode;152 unsigned m_calleeCount;153 123 }; 154 124 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r214711 r215103 95 95 } 96 96 97 void JSWebAssemblyInstance::addUnitializedCodeBlock(VM& vm, Ref<Wasm::Plan> plan) 98 { 99 auto* codeBlock = JSWebAssemblyCodeBlock::create( 100 vm, module(), memoryMode(), WTFMove(plan), module()->moduleInformation().internalFunctionCount(), module()->moduleInformation().importFunctionCount()); 101 m_codeBlock.set(vm, this, codeBlock); 102 ASSERT(!codeBlock->initialized()); 103 } 104 105 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec) 97 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock) 106 98 { 107 99 auto scope = DECLARE_THROW_SCOPE(vm); 108 codeBlock()->initialize(); 109 110 if (!codeBlock()->runnable()) { 111 throwException(exec, scope, JSWebAssemblyLinkError::create(exec, vm, globalObject()->WebAssemblyLinkErrorStructure(), codeBlock()->errorMessage())); 100 if (!wasmCodeBlock->runnable()) { 101 throwException(exec, scope, JSWebAssemblyLinkError::create(exec, vm, globalObject()->WebAssemblyLinkErrorStructure(), wasmCodeBlock->errorMessage())); 112 102 return; 113 103 } 114 RELEASE_ASSERT(codeBlock()->isSafeToRun(memory())); 104 105 RELEASE_ASSERT(wasmCodeBlock->isSafeToRun(memory()->memory().mode())); 106 m_codeBlock.set(vm, this, 107 JSWebAssemblyCodeBlock::create(vm, wasmCodeBlock.copyRef(), m_module->module().moduleInformation())); 115 108 116 109 auto* moduleRecord = jsCast<WebAssemblyModuleRecord*>(m_moduleNamespaceObject->moduleRecord()); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
r214905 r215103 40 40 class WebAssemblyToJSCallee; 41 41 42 namespace Wasm {43 class Plan;44 }45 46 47 42 class JSWebAssemblyInstance : public JSDestructibleObject { 48 43 public: … … 55 50 56 51 JSWebAssemblyCodeBlock* codeBlock() const { return m_codeBlock.get(); } 57 bool initialized() const { return codeBlock() && codeBlock()->initialized(); } 58 void addUnitializedCodeBlock(VM&, Ref<Wasm::Plan>); 59 void finalizeCreation(VM&, ExecState*); 52 void finalizeCreation(VM&, ExecState*, Ref<Wasm::CodeBlock>&&); 60 53 61 54 JSWebAssemblyModule* module() const { return m_module.get(); } -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp
r214919 r215103 44 44 const ClassInfo JSWebAssemblyModule::s_info = { "WebAssembly.Module", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyModule) }; 45 45 46 JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, RefPtr<Wasm::Plan>&& plan)46 JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, Wasm::Module::ValidationResult&& result) 47 47 { 48 ASSERT(!plan->hasWork());49 48 auto scope = DECLARE_THROW_SCOPE(vm); 50 if ( plan->failed()) {51 throwException(exec, scope, JSWebAssemblyCompileError::create(exec, vm, structure->globalObject()->WebAssemblyCompileErrorStructure(), plan->errorMessage()));49 if (!result.hasValue()) { 50 throwException(exec, scope, JSWebAssemblyCompileError::create(exec, vm, structure->globalObject()->WebAssemblyCompileErrorStructure(), result.error())); 52 51 return nullptr; 53 52 } 54 53 55 auto* module = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, *plan.get());54 auto* module = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, result.value().releaseNonNull()); 56 55 module->finishCreation(vm); 57 56 return module; … … 63 62 } 64 63 65 JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Wasm::Plan& plan)64 JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Ref<Wasm::Module>&& module) 66 65 : Base(vm, structure) 67 , m_module Information(plan.takeModuleInformation())66 , m_module(WTFMove(module)) 68 67 { 69 68 } … … 76 75 // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module. 77 76 SymbolTable* exportSymbolTable = SymbolTable::create(vm); 78 for (auto& exp : m_moduleInformation->exports) { 77 const Wasm::ModuleInformation& moduleInformation = m_module->moduleInformation(); 78 for (auto& exp : moduleInformation.exports) { 79 79 auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary); 80 80 String field = String::fromUTF8(exp.field); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
r214919 r215103 32 32 #include "JSWebAssemblyCodeBlock.h" 33 33 #include "UnconditionalFinalizer.h" 34 #include "WasmModule.h" 34 35 #include "WasmModuleInformation.h" 35 36 #include <wtf/Bag.h> … … 50 51 typedef JSDestructibleObject Base; 51 52 52 static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, RefPtr<Wasm::Plan>&&); 53 DECLARE_INFO; 54 55 static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, Wasm::Module::ValidationResult&&); 53 56 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 54 57 55 DECLARE_INFO; 56 57 const Wasm::ModuleInformation& moduleInformation() const { return m_moduleInformation.get(); } 58 const Wasm::ModuleInformation& moduleInformation() const { return m_module->moduleInformation(); } 58 59 SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); } 59 60 Wasm::SignatureIndex signatureIndexFromFunctionIndexSpace(unsigned functionIndexSpace) const 60 61 { 61 return m_module Information->signatureIndexFromFunctionIndexSpace(functionIndexSpace);62 return m_module->signatureIndexFromFunctionIndexSpace(functionIndexSpace); 62 63 } 63 64 WebAssemblyToJSCallee* callee() const { return m_callee.get(); } … … 67 68 const Vector<uint8_t>& source() const { return moduleInformation().source; } 68 69 70 Wasm::Module& module() { return m_module.get(); } 71 69 72 private: 70 73 friend class JSWebAssemblyCodeBlock; … … 72 75 void setCodeBlock(VM&, Wasm::MemoryMode, JSWebAssemblyCodeBlock*); 73 76 74 JSWebAssemblyModule(VM&, Structure*, Wasm::Plan&);77 JSWebAssemblyModule(VM&, Structure*, Ref<Wasm::Module>&&); 75 78 void finishCreation(VM&); 76 79 static void destroy(JSCell*); 77 80 static void visitChildren(JSCell*, SlotVisitor&); 78 81 79 Ref<Wasm::Module Information> m_moduleInformation;82 Ref<Wasm::Module> m_module; 80 83 WriteBarrier<SymbolTable> m_exportSymbolTable; 81 84 WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes]; -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r214905 r215103 160 160 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, Wasm::Callee& jsEntrypoint, Wasm::Callee& wasmEntrypoint, Wasm::SignatureIndex signatureIndex) 161 161 { 162 ASSERT(&jsEntrypoint != &wasmEntrypoint); 163 162 164 NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name); 163 165 Structure* structure = globalObject->webAssemblyFunctionStructure(); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
r214970 r215103 59 59 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(ExecState* exec) 60 60 { 61 auto& vm = exec->vm();61 VM& vm = exec->vm(); 62 62 auto scope = DECLARE_THROW_SCOPE(vm); 63 63 … … 79 79 RETURN_IF_EXCEPTION(scope, { }); 80 80 81 // There are three possible cases: 82 // 1) The instance already has an initialized CodeBlock (runnable), so we just need to finalizeCreation. 83 // 2) The instance has no CodeBlock, so we need to make one and compile the code for it. 84 // 3) The instance already has an uninitialized CodeBlock, so we need to wait for the compilation to finish. 85 86 if (!instance->initialized()) { 87 if (instance->codeBlock()) 88 Wasm::ensureWorklist().completePlanSynchronously(instance->codeBlock()->plan()); 89 else { 90 Ref<Wasm::Plan> plan = adoptRef(*new Plan(vm, makeRef(const_cast<Wasm::ModuleInformation&>(module->moduleInformation())), Plan::FullCompile, Plan::dontFinalize)); 91 plan->setMode(instance->memoryMode()); 92 instance->addUnitializedCodeBlock(vm, plan.copyRef()); 93 94 auto& worklist = Wasm::ensureWorklist(); 95 worklist.enqueue(plan.copyRef()); 96 worklist.completePlanSynchronously(plan.get()); 97 } 98 } 99 100 instance->finalizeCreation(vm, exec); 81 instance->finalizeCreation(vm, exec, module->module().compileSync(vm, instance->memoryMode())); 101 82 RETURN_IF_EXCEPTION(scope, { }); 102 83 return JSValue::encode(instance); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
r214919 r215103 79 79 RETURN_IF_EXCEPTION(scope, { }); 80 80 81 RefPtr<Wasm::Plan> plan = adoptRef(new Wasm::Plan(vm, WTFMove(source), Wasm::Plan::Validation, Wasm::Plan::dontFinalize)); 82 if (!plan->parseAndValidateModule()) 83 return throwException(exec, scope, JSWebAssemblyCompileError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyCompileErrorStructure(), plan->errorMessage())); 84 return JSWebAssemblyModule::createStub(vm, exec, structure, WTFMove(plan)); 81 return JSWebAssemblyModule::createStub(vm, exec, structure, Wasm::Module::validateSync(vm, WTFMove(source))); 85 82 } 86 83 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp
r214970 r215103 66 66 */ 67 67 68 static EncodedJSValuereject(ExecState* exec, CatchScope& catchScope, JSPromiseDeferred* promise)68 static void reject(ExecState* exec, CatchScope& catchScope, JSPromiseDeferred* promise) 69 69 { 70 70 Exception* exception = catchScope.exception(); … … 72 72 catchScope.clearException(); 73 73 promise->reject(exec, exception->value()); 74 return JSValue::encode(promise->promise());75 74 } 76 75 … … 91 90 vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies)); 92 91 93 Ref<Plan> plan = adoptRef(*new Plan(vm, WTFMove(source), Plan::Validation, [promise, globalObject] (Plan& p) mutable { 94 RefPtr<Plan> plan = makeRef(p); 95 p.vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, globalObject, plan = WTFMove(plan)] () mutable { 96 VM& vm = plan->vm(); 92 Wasm::Module::validateAsync(vm, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([promise, globalObject] (VM& vm, Wasm::Module::ValidationResult&& result) mutable { 93 vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, globalObject, result = WTFMove(result), &vm] () mutable { 97 94 auto scope = DECLARE_CATCH_SCOPE(vm); 98 95 ExecState* exec = globalObject->globalExec(); 99 JSValue module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove( plan));96 JSValue module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove(result)); 100 97 if (scope.exception()) { 101 98 reject(exec, scope, promise); … … 107 104 })); 108 105 109 Wasm::ensureWorklist().enqueue(WTFMove(plan));110 106 return JSValue::encode(promise->promise()); 111 107 } 112 108 113 109 enum class Resolve { WithInstance, WithModuleAndInstance }; 114 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Re solve entries)110 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind) 115 111 { 116 112 auto scope = DECLARE_CATCH_SCOPE(vm); 117 instance->finalizeCreation(vm, exec );113 instance->finalizeCreation(vm, exec, WTFMove(codeBlock)); 118 114 if (scope.exception()) { 119 115 reject(exec, scope, promise); … … 121 117 } 122 118 123 if ( entries== Resolve::WithInstance)119 if (resolveKind == Resolve::WithInstance) 124 120 promise->resolve(exec, instance); 125 121 else { … … 131 127 } 132 128 133 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve entries)129 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve resolveKind) 134 130 { 135 131 auto scope = DECLARE_CATCH_SCOPE(vm); … … 141 137 } 142 138 143 // There are three possible cases:144 // 1) The instance already has an initialized CodeBlock, so we have no more work to do.145 // 2) The instance has no CodeBlock, so we need to make one and compile the code for it.146 // 3) The instance already has an uninitialized CodeBlock, so someone else is compiling code and we just need to wait for them.147 148 if (instance->initialized()) {149 resolve(vm, exec, promise, instance, module, entries);150 return;151 }152 153 139 Vector<Strong<JSCell>> dependencies; 154 140 // The instance keeps the module alive. 155 141 dependencies.append(Strong<JSCell>(vm, instance)); 156 142 vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies)); 157 158 if (instance->codeBlock()) { 159 instance->codeBlock()->plan().addCompletionTask([promise, instance, module, entries] (Plan& p) { 160 RefPtr<Plan> plan = makeRef(p); 161 p.vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, entries, plan = WTFMove(plan)] () { 162 ExecState* exec = instance->globalObject()->globalExec(); 163 resolve(plan->vm(), exec, promise, instance, module, entries); 164 }); 165 }); 166 return; 167 } 168 ASSERT(!instance->codeBlock()); 169 170 // FIXME: This re-parses the module header, which shouldn't be necessary. 171 // https://bugs.webkit.org/show_bug.cgi?id=170205 172 Ref<Plan> plan = adoptRef(*new Plan(vm, makeRef(const_cast<Wasm::ModuleInformation&>(module->moduleInformation())), Plan::FullCompile, [promise, instance, module, entries] (Plan& p) { 173 RefPtr<Plan> plan = makeRef(p); 174 p.vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, entries, plan = WTFMove(plan)] () { 175 VM& vm = plan->vm(); 143 // Note: This completion task may or may not get called immediately. 144 module->module().compileAsync(vm, instance->memoryMode(), createSharedTask<Wasm::CodeBlock::CallbackType>([promise, instance, module, resolveKind] (VM& vm, Ref<Wasm::CodeBlock>&& refCodeBlock) mutable { 145 RefPtr<Wasm::CodeBlock> codeBlock = WTFMove(refCodeBlock); 146 vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, resolveKind, &vm, codeBlock = WTFMove(codeBlock)] () mutable { 176 147 ExecState* exec = instance->globalObject()->globalExec(); 177 resolve(vm, exec, promise, instance, module, entries);148 resolve(vm, exec, promise, instance, module, codeBlock.releaseNonNull(), resolveKind); 178 149 }); 179 150 })); 180 181 instance->addUnitializedCodeBlock(vm, plan.copyRef());182 plan->setMode(instance->memoryMode());183 Wasm::ensureWorklist().enqueue(WTFMove(plan));184 151 } 185 152 … … 196 163 vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies)); 197 164 198 Ref<Plan> plan = adoptRef(*new Plan(vm, WTFMove(source), Plan::Validation, [promise, importObject, globalObject] (Plan& p) mutable { 199 RefPtr<Plan> plan = makeRef(p); 200 p.vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, importObject, globalObject, plan = WTFMove(plan)] () mutable { 201 VM& vm = plan->vm(); 165 Wasm::Module::validateAsync(vm, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([promise, importObject, globalObject] (VM& vm, Wasm::Module::ValidationResult&& result) mutable { 166 vm.promiseDeferredTimer->scheduleWorkSoon(promise, [promise, importObject, globalObject, result = WTFMove(result), &vm] () mutable { 202 167 auto scope = DECLARE_CATCH_SCOPE(vm); 203 168 ExecState* exec = globalObject->globalExec(); 204 JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), plan.copyRef());169 JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove(result)); 205 170 if (scope.exception()) { 206 171 reject(exec, scope, promise); … … 211 176 }); 212 177 })); 213 214 Wasm::ensureWorklist().enqueue(WTFMove(plan));215 178 } 216 179 … … 249 212 uint8_t* base = getWasmBufferFromValue(exec, exec->argument(0), byteOffset, byteSize); 250 213 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 251 Wasm::Plan plan(vm, base + byteOffset, byteSize, Plan::Validation, Plan::dontFinalize );214 Wasm::Plan plan(vm, base + byteOffset, byteSize, Plan::Validation, Plan::dontFinalize()); 252 215 // FIXME: We might want to throw an OOM exception here if we detect that something will OOM. 253 216 // https://bugs.webkit.org/show_bug.cgi?id=166015
Note:
See TracChangeset
for help on using the changeset viewer.