Changeset 215103 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Apr 7, 2017, 11:25:14 AM (8 years ago)
Author:
[email protected]
Message:

WebAssembly: Make to a compilation API that allows for multi-VM concurrent compilations of Wasm Modules
https://bugs.webkit.org/show_bug.cgi?id=170488

Reviewed by JF Bastien.

Source/JavaScriptCore:

This patch adds a class called Wasm::Module. It contains the bits from
JSWebAssemblyModule that were not VM specific. JSWebAssemblyModule
now has a Ref<Wasm::Module>. Similarly, there is now a Wasm::CodeBlock,
which owns the non-VM-specific bits that JSWebAssemblyCodeBlock used
to own.

This patch also simplifies how we verify and compile code. Wasm::Module
now has an API for both sync/async validation and compilation. This
API abstracts away how Wasm::Plan works.

This is hopefully the last patch needed before we can implement
window.postMessage for a JSWebAssemblyModule. I think all that's
needed now to implement postMessage is simply creating a new
JSWebAssemblyModule with the underlying Wasm::Module.

This patch is neutral on WasmBench.

Finally, this patch changes the promise deferred timer to
allow for new tasks to be added while we're executing
a task. Before, we'd deadlock if this happened.

(functionTestWasmModuleFunctions):

  • runtime/PromiseDeferredTimer.cpp:

(JSC::PromiseDeferredTimer::doWork):
(JSC::PromiseDeferredTimer::scheduleWorkSoon):

  • runtime/PromiseDeferredTimer.h:
  • wasm/WasmB3IRGenerator.cpp:
  • wasm/WasmBinding.cpp:

(JSC::Wasm::wasmToJs):
(JSC::Wasm::wasmToWasm):
(JSC::Wasm::exitStubGenerator): Deleted.

  • wasm/WasmBinding.h:
  • wasm/WasmCodeBlock.cpp: Added.

(JSC::Wasm::CodeBlock::CodeBlock):
(JSC::Wasm::CodeBlock::waitUntilFinished):
(JSC::Wasm::CodeBlock::compileAsync):
(JSC::Wasm::CodeBlock::isSafeToRun):

  • wasm/WasmCodeBlock.h: Added.

(JSC::Wasm::CodeBlock::create):
(JSC::Wasm::CodeBlock::compilationFinished):
(JSC::Wasm::CodeBlock::runnable):
(JSC::Wasm::CodeBlock::errorMessage):
(JSC::Wasm::CodeBlock::functionImportCount):
(JSC::Wasm::CodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):

  • wasm/WasmModule.cpp: Added.

(JSC::Wasm::Module::Module):
(JSC::Wasm::makeValidationResult):
(JSC::Wasm::Module::validateSyncImpl):
(JSC::Wasm::Module::getOrCreateCodeBlock):
(JSC::Wasm::Module::compileSync):
(JSC::Wasm::Module::makeValidationCallback):
(JSC::Wasm::Module::compileAsync):

  • wasm/WasmModule.h: Added.

(JSC::Wasm::Module::create):
(JSC::Wasm::Module::validateSync):
(JSC::Wasm::Module::validateAsync):
(JSC::Wasm::Module::signatureIndexFromFunctionIndexSpace):
(JSC::Wasm::Module::moduleInformation):
(JSC::Wasm::Module::nonNullCodeBlock):

  • wasm/WasmPlan.cpp:

(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::addCompletionTask):
(JSC::Wasm::Plan::prepare):
(JSC::Wasm::Plan::compileFunctions):
(JSC::Wasm::Plan::complete):
(JSC::Wasm::Plan::tryRemoveVMAndCancelIfLast):
(JSC::Wasm::Plan::cancel): Deleted.

  • wasm/WasmPlan.h:

(JSC::Wasm::Plan::dontFinalize):
(JSC::Wasm::Plan::takeWasmToWasmExitStubs):
(JSC::Wasm::Plan::mode):
(JSC::Wasm::Plan::takeWasmExitStubs): Deleted.
(JSC::Wasm::Plan::vm): Deleted.

  • wasm/WasmWorklist.cpp:

(JSC::Wasm::Worklist::stopAllPlansForVM):

  • wasm/js/JSWebAssemblyCodeBlock.cpp:

(JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
(JSC::JSWebAssemblyCodeBlock::isSafeToRun):
(JSC::JSWebAssemblyCodeBlock::initialize): Deleted.

  • wasm/js/JSWebAssemblyCodeBlock.h:

(JSC::JSWebAssemblyCodeBlock::create):
(JSC::JSWebAssemblyCodeBlock::functionImportCount):
(JSC::JSWebAssemblyCodeBlock::jsEntrypointCalleeFromFunctionIndexSpace):
(JSC::JSWebAssemblyCodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace):
(JSC::JSWebAssemblyCodeBlock::wasmToJsCallStubForImport):
(JSC::JSWebAssemblyCodeBlock::mode): Deleted.
(JSC::JSWebAssemblyCodeBlock::initialized): Deleted.
(JSC::JSWebAssemblyCodeBlock::plan): Deleted.
(JSC::JSWebAssemblyCodeBlock::runnable): Deleted.
(JSC::JSWebAssemblyCodeBlock::errorMessage): Deleted.
(JSC::JSWebAssemblyCodeBlock::setJSEntrypointCallee): Deleted.
(JSC::JSWebAssemblyCodeBlock::setWasmEntrypointCallee): Deleted.

  • wasm/js/JSWebAssemblyInstance.cpp:

(JSC::JSWebAssemblyInstance::finalizeCreation):
(JSC::JSWebAssemblyInstance::addUnitializedCodeBlock): Deleted.

  • wasm/js/JSWebAssemblyInstance.h:

(JSC::JSWebAssemblyInstance::initialized): Deleted.

  • wasm/js/JSWebAssemblyModule.cpp:

(JSC::JSWebAssemblyModule::createStub):
(JSC::JSWebAssemblyModule::JSWebAssemblyModule):
(JSC::JSWebAssemblyModule::finishCreation):

  • wasm/js/JSWebAssemblyModule.h:

(JSC::JSWebAssemblyModule::moduleInformation):
(JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace):
(JSC::JSWebAssemblyModule::module):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::WebAssemblyFunction::create):

  • wasm/js/WebAssemblyInstanceConstructor.cpp:

(JSC::constructJSWebAssemblyInstance):

  • wasm/js/WebAssemblyModuleConstructor.cpp:

(JSC::WebAssemblyModuleConstructor::createModule):

  • wasm/js/WebAssemblyPrototype.cpp:

(JSC::reject):
(JSC::webAssemblyCompileFunc):
(JSC::resolve):
(JSC::instantiate):
(JSC::compileAndInstantiate):
(JSC::webAssemblyValidateFunc):

Source/WTF:

  • wtf/SharedTask.h: Make SharedTaskFunctor forward its arguments.
Location:
trunk/Source/JavaScriptCore
Files:
4 added
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r215073 r215103  
    939939    wasm/WasmCallee.cpp
    940940    wasm/WasmCallingConvention.cpp
     941    wasm/WasmCodeBlock.cpp
    941942    wasm/WasmContext.cpp
    942943    wasm/WasmFaultSignalHandler.cpp
     
    944945    wasm/WasmMemory.cpp
    945946    wasm/WasmMemoryInformation.cpp
     947    wasm/WasmModule.cpp
    946948    wasm/WasmModuleInformation.cpp
    947949    wasm/WasmModuleParser.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r215088 r215103  
     12017-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
    11312017-04-07  Carlos Garcia Campos  <[email protected]>
    2132
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r215073 r215103  
    13221322                52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    13231323                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, ); }; };
    13241326                527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */; };
    13251327                52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    14911493                72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */; };
    14921494                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, ); }; };
    14931497                7905BB681D12050E0019FE57 /* InlineAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7905BB661D12050E0019FE57 /* InlineAccess.cpp */; };
    14941498                7905BB691D12050E0019FE57 /* InlineAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 7905BB671D12050E0019FE57 /* InlineAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    38323836                52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; };
    38333837                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>"; };
    38343840                527773DD1AAF83AC00BDE7E8 /* RuntimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuntimeType.cpp; sourceTree = "<group>"; };
    38353841                52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = "<group>"; };
     
    40444050                72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterSetterFunction.h; sourceTree = "<group>"; };
    40454051                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>"; };
    40464054                7905BB661D12050E0019FE57 /* InlineAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineAccess.cpp; sourceTree = "<group>"; };
    40474055                7905BB671D12050E0019FE57 /* InlineAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineAccess.h; sourceTree = "<group>"; };
     
    63226330                                53FD04D11D7AB187003287D3 /* WasmCallingConvention.cpp */,
    63236331                                53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */,
     6332                                526AC4B41E977C5D003500E1 /* WasmCodeBlock.cpp */,
     6333                                526AC4B51E977C5D003500E1 /* WasmCodeBlock.h */,
    63246334                                AD412B311E7B2E8A008AF157 /* WasmContext.cpp */,
    63256335                                AD412B321E7B2E8A008AF157 /* WasmContext.h */,
     
    63286338                                7BC547D21B69599B00959B58 /* WasmFormat.h */,
    63296339                                53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */,
     6340                                790081361E95A8EC0052D7CD /* WasmModule.cpp */,
     6341                                790081371E95A8EC0052D7CD /* WasmModule.h */,
    63306342                                535557151D9DFA32006D583B /* WasmMemory.cpp */,
    63316343                                535557131D9D9EA5006D583B /* WasmMemory.h */,
     
    87758787                                0F070A491D543A93006E7232 /* HeapCellInlines.h in Headers */,
    87768788                                0F32BD111BB34F190093A57F /* HeapHelperPool.h in Headers */,
     8789                                526AC4B71E977C5D003500E1 /* WasmCodeBlock.h in Headers */,
    87778790                                C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */,
    87788791                                2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
     
    89238936                                BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
    89248937                                A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
     8938                                790081391E95A8EC0052D7CD /* WasmModule.h in Headers */,
    89258939                                A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
    89268940                                0FF4B4C71E8893C500DBBE86 /* AirCFG.h in Headers */,
     
    1036710381                                0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */,
    1036810382                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
     10383                                790081381E95A8EC0052D7CD /* WasmModule.cpp in Sources */,
    1036910384                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
    1037010385                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
     
    1054710562                                140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,
    1054810563                                70B7919B1C024A46002481E2 /* JSGeneratorFunction.cpp in Sources */,
     10564                                526AC4B61E977C5D003500E1 /* WasmCodeBlock.cpp in Sources */,
    1054910565                                797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */,
    1055010566                                147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */,
  • trunk/Source/JavaScriptCore/jsc.cpp

    r214936 r215103  
    31923192        CRASH();
    31933193
    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()));
    31953195    Wasm::ensureWorklist().enqueue(plan.copyRef());
    31963196    Wasm::ensureWorklist().completePlanSynchronously(plan.get());
  • trunk/Source/JavaScriptCore/runtime/PromiseDeferredTimer.cpp

    r214970 r215103  
    4545{
    4646    ASSERT(m_vm->currentThreadIsHoldingAPILock());
    47     LockHolder locker(m_taskLock);
     47    m_taskLock.lock();
    4848    cancelTimer();
    49     if (!m_runTasks)
     49    if (!m_runTasks) {
     50        m_taskLock.unlock();
    5051        return;
     52    }
    5153
    5254    while (!m_tasks.isEmpty()) {
     
    5860        // We may have already canceled these promises.
    5961        if (m_pendingPromises.contains(ticket)) {
     62            // Allow tasks we run now to schedule work.
     63            m_currentlyRunningTask = true;
     64            m_taskLock.unlock();
     65
    6066            task();
    6167            m_vm->drainMicrotasks();
     68
     69            m_taskLock.lock();
     70            m_currentlyRunningTask = false;
    6271        }
    6372    }
    6473
    65     if (m_pendingPromises.isEmpty() && m_shouldStopRunLoopWhenAllPromisesFinish)
     74    if (m_pendingPromises.isEmpty() && m_shouldStopRunLoopWhenAllPromisesFinish) {
    6675#if USE(CF)
    6776        CFRunLoopStop(m_runLoop.get());
     
    6978        RunLoop::current().stop();
    7079#endif
     80    }
     81
     82    m_taskLock.unlock();
    7183}
    7284
     
    122134    LockHolder locker(m_taskLock);
    123135    m_tasks.append(std::make_tuple(ticket, WTFMove(task)));
    124     if (!isScheduled())
     136    if (!isScheduled() && !m_currentlyRunningTask)
    125137        scheduleTimer(0);
    126138}
  • trunk/Source/JavaScriptCore/runtime/PromiseDeferredTimer.h

    r214970 r215103  
    6565    bool m_runTasks { true };
    6666    bool m_shouldStopRunLoopWhenAllPromisesFinish { false };
     67    bool m_currentlyRunningTask { false };
    6768    Vector<std::tuple<JSPromiseDeferred*, Task>> m_tasks;
    6869};
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r214950 r215103  
    937937                // We need to clobber all potential pinned registers since we might be leaving the instance.
    938938                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) {
    940940                    AllowMacroScratchRegisterUsage allowScratch(jit);
    941941                    jit.call(params[returnType == Void ? 0 : 1].gpr());
  • trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp

    r214905 r215103  
    5050}
    5151
    52 static MacroAssemblerCodeRef wasmToJs(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
     52MacroAssemblerCodeRef wasmToJs(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
    5353{
    5454    // FIXME: This function doesn't properly abstract away the calling convention.
     
    423423}
    424424
    425 static MacroAssemblerCodeRef wasmToWasm(unsigned importIndex)
     425MacroAssemblerCodeRef wasmToWasm(unsigned importIndex)
    426426{
    427427    const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
     
    463463}
    464464
    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 
    473465} } // namespace JSC::Wasm
    474466
  • trunk/Source/JavaScriptCore/wasm/WasmBinding.h

    r210229 r215103  
    3939namespace Wasm {
    4040
    41 WasmExitStubs exitStubGenerator(VM*, Bag<CallLinkInfo>&, SignatureIndex, unsigned);
     41MacroAssemblerCodeRef wasmToWasm(unsigned importIndex);
     42MacroAssemblerCodeRef wasmToJs(VM*, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex, unsigned importIndex);
    4243
    4344} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp

    r214970 r215103  
    5353Plan::Plan(VM& vm, Ref<ModuleInformation> info, AsyncWork work, CompletionTask&& task)
    5454    : m_moduleInformation(WTFMove(info))
    55     , m_vm(vm)
    5655    , m_source(m_moduleInformation->source.data())
    5756    , m_sourceLength(m_moduleInformation->source.size())
     
    5958    , m_asyncWork(work)
    6059{
    61     m_completionTasks.append(WTFMove(task));
     60    m_completionTasks.append(std::make_pair(&vm, WTFMove(task)));
    6261}
    6362
     
    7069Plan::Plan(VM& vm, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task)
    7170    : m_moduleInformation(makeRef(*new ModuleInformation(Vector<uint8_t>())))
    72     , m_vm(vm)
    7371    , m_source(source)
    7472    , m_sourceLength(sourceLength)
     
    7674    , m_asyncWork(work)
    7775{
    78     m_completionTasks.append(WTFMove(task));
     76    m_completionTasks.append(std::make_pair(&vm, WTFMove(task)));
    7977}
    8078
     
    105103}
    106104
    107 void Plan::addCompletionTask(CompletionTask&& task)
     105void Plan::addCompletionTask(VM& vm, CompletionTask&& task)
    108106{
    109107    LockHolder locker(m_lock);
    110108    if (m_state != State::Completed)
    111         m_completionTasks.append(WTFMove(task));
     109        m_completionTasks.append(std::make_pair(&vm, WTFMove(task)));
    112110    else
    113         task(*this);
     111        task->run(vm, *this);
    114112}
    115113
     
    183181
    184182    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
    185     if (!tryReserveCapacity(m_wasmExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")
     183    if (!tryReserveCapacity(m_wasmToWasmExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")
    186184        || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, functionLocations.size(), " unlinked WebAssembly to WebAssembly calls")
    187185        || !tryReserveCapacity(m_wasmInternalFunctions, functionLocations.size(), " WebAssembly functions")
     
    197195        if (import->kind != ExternalKind::Function)
    198196            continue;
    199         unsigned importFunctionIndex = m_wasmExitStubs.size();
     197        unsigned importFunctionIndex = m_wasmToWasmExitStubs.size();
    200198        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));
    203200    }
    204201
     
    261258        SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
    262259        const Signature& signature = SignatureInformation::get(signatureIndex);
    263         unsigned functionIndexSpace = m_wasmExitStubs.size() + functionIndex;
     260        unsigned functionIndexSpace = m_wasmToWasmExitStubs.size() + functionIndex;
    264261        ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex);
    265262        ASSERT(validateFunction(functionStart, functionLength, signature, m_moduleInformation.get()));
     
    317314                if (m_moduleInformation->isImportedFunctionFromFunctionIndexSpace(call.functionIndex)) {
    318315                    // 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_wasmExitStubs.at(call.functionIndex).wasmToWasm.code().executableAddress();
     316                    executableAddress = m_wasmToWasmExitStubs.at(call.functionIndex).code().executableAddress();
    320317                } else
    321                     executableAddress = m_wasmInternalFunctions.at(call.functionIndex - m_wasmExitStubs.size())->wasmEntrypoint.compilation->code().executableAddress();
     318                    executableAddress = m_wasmInternalFunctions.at(call.functionIndex - m_wasmToWasmExitStubs.size())->wasmEntrypoint.compilation->code().executableAddress();
    322319                MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(executableAddress));
    323320            }
     
    328325        moveToState(State::Completed);
    329326        for (auto& task : m_completionTasks)
    330             task(*this);
     327            task.second->run(*task.first, *this);
    331328        m_completed.notifyAll();
    332329    }
     
    342339}
    343340
    344 void Plan::cancel()
     341bool Plan::tryRemoveVMAndCancelIfLast(VM& vm)
    345342{
    346343    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()) {
    348361        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;
    351367}
    352368
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.h

    r214970 r215103  
    3333#include "WasmModuleInformation.h"
    3434#include <wtf/Bag.h>
     35#include <wtf/SharedTask.h>
    3536#include <wtf/ThreadSafeRefCounted.h>
    3637#include <wtf/Vector.h>
     
    4647class Plan : public ThreadSafeRefCounted<Plan> {
    4748public:
    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&) { }); }
    5052    enum AsyncWork : uint8_t { FullCompile, Validation };
    5153    // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
     
    5759    JS_EXPORT_PRIVATE ~Plan();
    5860
    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&&);
    6064
    6165    bool parseAndValidateModule();
     
    9296    }
    9397
    94     Vector<WasmExitStubs>&& takeWasmExitStubs()
     98    Vector<MacroAssemblerCodeRef>&& takeWasmToWasmExitStubs()
    9599    {
    96100        RELEASE_ASSERT(!failed() && !hasWork());
    97         return WTFMove(m_wasmExitStubs);
     101        return WTFMove(m_wasmToWasmExitStubs);
    98102    }
    99103
    100104    void setMode(MemoryMode mode) { m_mode = mode; }
    101105    MemoryMode mode() const { return m_mode; }
    102     VM& vm() const { return m_vm; }
    103106
    104107    enum class State : uint8_t {
     
    117120
    118121    void waitForCompletion();
    119     void cancel();
     122    // Returns true if it cancelled the plan.
     123    bool tryRemoveVMAndCancelIfLast(VM&);
    120124
    121125private:
     
    132136    Ref<ModuleInformation> m_moduleInformation;
    133137    Bag<CallLinkInfo> m_callLinkInfos;
    134     Vector<WasmExitStubs> m_wasmExitStubs;
     138    Vector<MacroAssemblerCodeRef> m_wasmToWasmExitStubs;
    135139    Vector<std::unique_ptr<WasmInternalFunction>> m_wasmInternalFunctions;
    136140    Vector<CompilationContext> m_compilationContexts;
    137141
    138     VM& m_vm;
    139     Vector<CompletionTask, 1> m_completionTasks;
     142    Vector<std::pair<VM*, CompletionTask>, 1> m_completionTasks;
    140143
    141144    Vector<Vector<UnlinkedWasmToWasmCall>> m_unlinkedWasmToWasmCalls;
  • trunk/Source/JavaScriptCore/wasm/WasmWorklist.cpp

    r214970 r215103  
    218218    LockHolder locker(*m_lock);
    219219    iterate(locker, [&] (QueueElement& element) {
    220         if (&element.plan->vm() == &vm) {
    221             element.plan->cancel();
     220        bool didCancel = element.plan->tryRemoveVMAndCancelIfLast(vm);
     221        if (didCancel)
    222222            return IterateResult::DropAndContinue;
    223         }
    224223        return IterateResult::Continue;
    225224    });
    226225
    227226    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            }
    232233        }
    233234    }
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.cpp

    r214905 r215103  
    3333#include "JSWebAssemblyMemory.h"
    3434#include "JSWebAssemblyModule.h"
     35#include "WasmBinding.h"
    3536#include "WasmPlanInlines.h"
     37
     38#include <wtf/CurrentTime.h>
    3639
    3740namespace JSC {
     
    3942const ClassInfo JSWebAssemblyCodeBlock::s_info = { "WebAssemblyCodeBlock", nullptr, 0, CREATE_METHOD_TABLE(JSWebAssemblyCodeBlock) };
    4043
    41 JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock(VM& vm, JSWebAssemblyModule* owner,  Wasm::MemoryMode mode, Ref<Wasm::Plan>&& plan, unsigned calleeCount)
     44JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock(VM& vm, Ref<Wasm::CodeBlock>&& codeBlock, const Wasm::ModuleInformation& moduleInformation)
    4245    : Base(vm, vm.webAssemblyCodeBlockStructure.get())
    43     , m_plan(WTFMove(plan))
    44     , m_mode(mode)
    45     , m_calleeCount(calleeCount)
     46    , m_codeBlock(WTFMove(codeBlock))
    4647{
    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();
    6655    }
    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;
    8456}
    8557
     
    9163bool JSWebAssemblyCodeBlock::isSafeToRun(JSWebAssemblyMemory* memory) const
    9264{
    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());
    11166}
    11267
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.h

    r214905 r215103  
    3434#include "WasmCallee.h"
    3535#include "WasmFormat.h"
     36#include "WasmModule.h"
    3637#include <wtf/Bag.h>
    3738#include <wtf/Vector.h>
     
    5152    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
    5253
    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)
    5455    {
    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);
    5657        result->finishCreation(vm);
    5758        return result;
     
    6364    }
    6465
    65     unsigned functionImportCount() const { return m_wasmExitStubs.size(); }
    66     Wasm::MemoryMode mode() const { return m_mode; }
     66    unsigned functionImportCount() const { return m_codeBlock->functionImportCount(); }
    6767    JSWebAssemblyModule* module() const { return m_module.get(); }
    6868
    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; }
    7769    bool isSafeToRun(JSWebAssemblyMemory*) const;
    7870
    7971    // These two callee getters are only valid once the callees have been populated.
     72
    8073    Wasm::Callee& jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
    8174    {
    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);
    8676    }
    8777    Wasm::Callee& wasmEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
    8878    {
    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);
    9380    }
    9481
    9582    void* wasmToJsCallStubForImport(unsigned importIndex)
    9683    {
    97         RELEASE_ASSERT(importIndex < m_wasmExitStubs.size());
    98         return m_wasmExitStubs[importIndex].wasmToJs.code().executableAddress();
     84        return importWasmToJSStub(importIndex);
    9985    }
    10086
     
    10591
    10692private:
    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&);
    11994    DECLARE_EXPORT_INFO;
    12095    static const bool needsDestruction = true;
     
    142117
    143118    WriteBarrier<JSWebAssemblyModule> m_module;
     119    Ref<Wasm::CodeBlock> m_codeBlock;
     120    Vector<MacroAssemblerCodeRef> m_wasmToJSExitStubs;
    144121    UnconditionalFinalizer m_unconditionalFinalizer;
    145122    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;
    153123};
    154124
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

    r214711 r215103  
    9595}
    9696
    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)
     97void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock)
    10698{
    10799    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()));
    112102        return;
    113103    }
    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()));
    115108
    116109    auto* moduleRecord = jsCast<WebAssemblyModuleRecord*>(m_moduleNamespaceObject->moduleRecord());
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h

    r214905 r215103  
    4040class WebAssemblyToJSCallee;
    4141
    42 namespace Wasm {
    43 class Plan;
    44 }
    45 
    46 
    4742class JSWebAssemblyInstance : public JSDestructibleObject {
    4843public:
     
    5550
    5651    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>&&);
    6053
    6154    JSWebAssemblyModule* module() const { return m_module.get(); }
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp

    r214919 r215103  
    4444const ClassInfo JSWebAssemblyModule::s_info = { "WebAssembly.Module", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyModule) };
    4545
    46 JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, RefPtr<Wasm::Plan>&& plan)
     46JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, Wasm::Module::ValidationResult&& result)
    4747{
    48     ASSERT(!plan->hasWork());
    4948    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()));
    5251        return nullptr;
    5352    }
    5453
    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());
    5655    module->finishCreation(vm);
    5756    return module;
     
    6362}
    6463
    65 JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Wasm::Plan& plan)
     64JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Ref<Wasm::Module>&& module)
    6665    : Base(vm, structure)
    67     , m_moduleInformation(plan.takeModuleInformation())
     66    , m_module(WTFMove(module))
    6867{
    6968}
     
    7675    // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.
    7776    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) {
    7979        auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
    8080        String field = String::fromUTF8(exp.field);
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h

    r214919 r215103  
    3232#include "JSWebAssemblyCodeBlock.h"
    3333#include "UnconditionalFinalizer.h"
     34#include "WasmModule.h"
    3435#include "WasmModuleInformation.h"
    3536#include <wtf/Bag.h>
     
    5051    typedef JSDestructibleObject Base;
    5152
    52     static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, RefPtr<Wasm::Plan>&&);
     53    DECLARE_INFO;
     54
     55    static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, Wasm::Module::ValidationResult&&);
    5356    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    5457
    55     DECLARE_INFO;
    56 
    57     const Wasm::ModuleInformation& moduleInformation() const { return m_moduleInformation.get(); }
     58    const Wasm::ModuleInformation& moduleInformation() const { return m_module->moduleInformation(); }
    5859    SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); }
    5960    Wasm::SignatureIndex signatureIndexFromFunctionIndexSpace(unsigned functionIndexSpace) const
    6061    {
    61         return m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace);
     62        return m_module->signatureIndexFromFunctionIndexSpace(functionIndexSpace);
    6263    }
    6364    WebAssemblyToJSCallee* callee() const { return m_callee.get(); }
     
    6768    const Vector<uint8_t>& source() const { return moduleInformation().source; }
    6869
     70    Wasm::Module& module() { return m_module.get(); }
     71
    6972private:
    7073    friend class JSWebAssemblyCodeBlock;
     
    7275    void setCodeBlock(VM&, Wasm::MemoryMode, JSWebAssemblyCodeBlock*);
    7376
    74     JSWebAssemblyModule(VM&, Structure*, Wasm::Plan&);
     77    JSWebAssemblyModule(VM&, Structure*, Ref<Wasm::Module>&&);
    7578    void finishCreation(VM&);
    7679    static void destroy(JSCell*);
    7780    static void visitChildren(JSCell*, SlotVisitor&);
    7881
    79     Ref<Wasm::ModuleInformation> m_moduleInformation;
     82    Ref<Wasm::Module> m_module;
    8083    WriteBarrier<SymbolTable> m_exportSymbolTable;
    8184    WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes];
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r214905 r215103  
    160160WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, Wasm::Callee& jsEntrypoint, Wasm::Callee& wasmEntrypoint, Wasm::SignatureIndex signatureIndex)
    161161{
     162    ASSERT(&jsEntrypoint != &wasmEntrypoint);
     163
    162164    NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
    163165    Structure* structure = globalObject->webAssemblyFunctionStructure();
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp

    r214970 r215103  
    5959static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(ExecState* exec)
    6060{
    61     auto& vm = exec->vm();
     61    VM& vm = exec->vm();
    6262    auto scope = DECLARE_THROW_SCOPE(vm);
    6363
     
    7979    RETURN_IF_EXCEPTION(scope, { });
    8080
    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()));
    10182    RETURN_IF_EXCEPTION(scope, { });
    10283    return JSValue::encode(instance);
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp

    r214919 r215103  
    7979    RETURN_IF_EXCEPTION(scope, { });
    8080
    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)));
    8582}
    8683
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp

    r214970 r215103  
    6666 */
    6767
    68 static EncodedJSValue reject(ExecState* exec, CatchScope& catchScope, JSPromiseDeferred* promise)
     68static void reject(ExecState* exec, CatchScope& catchScope, JSPromiseDeferred* promise)
    6969{
    7070    Exception* exception = catchScope.exception();
     
    7272    catchScope.clearException();
    7373    promise->reject(exec, exception->value());
    74     return JSValue::encode(promise->promise());
    7574}
    7675
     
    9190    vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
    9291
    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 {
    9794            auto scope = DECLARE_CATCH_SCOPE(vm);
    9895            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));
    10097            if (scope.exception()) {
    10198                reject(exec, scope, promise);
     
    107104    }));
    108105
    109     Wasm::ensureWorklist().enqueue(WTFMove(plan));
    110106    return JSValue::encode(promise->promise());
    111107}
    112108
    113109enum class Resolve { WithInstance, WithModuleAndInstance };
    114 static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Resolve entries)
     110static void resolve(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyInstance* instance, JSWebAssemblyModule* module, Ref<Wasm::CodeBlock>&& codeBlock, Resolve resolveKind)
    115111{
    116112    auto scope = DECLARE_CATCH_SCOPE(vm);
    117     instance->finalizeCreation(vm, exec);
     113    instance->finalizeCreation(vm, exec, WTFMove(codeBlock));
    118114    if (scope.exception()) {
    119115        reject(exec, scope, promise);
     
    121117    }
    122118
    123     if (entries == Resolve::WithInstance)
     119    if (resolveKind == Resolve::WithInstance)
    124120        promise->resolve(exec, instance);
    125121    else {
     
    131127}
    132128
    133 static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve entries)
     129static void instantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSWebAssemblyModule* module, JSObject* importObject, Resolve resolveKind)
    134130{
    135131    auto scope = DECLARE_CATCH_SCOPE(vm);
     
    141137    }
    142138
    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 
    153139    Vector<Strong<JSCell>> dependencies;
    154140    // The instance keeps the module alive.
    155141    dependencies.append(Strong<JSCell>(vm, instance));
    156142    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 {
    176147            ExecState* exec = instance->globalObject()->globalExec();
    177             resolve(vm, exec, promise, instance, module, entries);
     148            resolve(vm, exec, promise, instance, module, codeBlock.releaseNonNull(), resolveKind);
    178149        });
    179150    }));
    180 
    181     instance->addUnitializedCodeBlock(vm, plan.copyRef());
    182     plan->setMode(instance->memoryMode());
    183     Wasm::ensureWorklist().enqueue(WTFMove(plan));
    184151}
    185152
     
    196163    vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
    197164
    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 {
    202167            auto scope = DECLARE_CATCH_SCOPE(vm);
    203168            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));
    205170            if (scope.exception()) {
    206171                reject(exec, scope, promise);
     
    211176        });
    212177    }));
    213 
    214     Wasm::ensureWorklist().enqueue(WTFMove(plan));
    215178}
    216179
     
    249212    uint8_t* base = getWasmBufferFromValue(exec, exec->argument(0), byteOffset, byteSize);
    250213    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());
    252215    // FIXME: We might want to throw an OOM exception here if we detect that something will OOM.
    253216    // https://bugs.webkit.org/show_bug.cgi?id=166015
Note: See TracChangeset for help on using the changeset viewer.