Changeset 252115 in webkit


Ignore:
Timestamp:
Nov 5, 2019 5:30:41 PM (4 years ago)
Author:
Tadeu Zagallo
Message:

[WebAssembly] Allow tiering up from LLInt to BBQ
https://bugs.webkit.org/show_bug.cgi?id=203793

Reviewed by Yusuke Suzuki.

Even though the interpreter was overall neutral on throughput, it's still a regression in pathological
cases where massive functions spend too long in the LLInt while compiling the function with OMG. This
patch makes it so that the LLInt can tier up to BBQ from the prologue, while still tiering up to OMG from
from loops. This is a huge speed up on the tsf-wasm subtest of JS2:

# BBQ -> OMG
Startup: 100.680
Runtime: 1.852
Score: 13.654

# LLInt -> OMG
Startup: 378.205
Runtime: 1.291
Score: 22.082

# LLInt -> BBQ -> OMG
Startup: 405.983
Runtime: 2.311
Score: 30.623

  • runtime/Options.cpp:

(JSC::overrideDefaults):

  • runtime/OptionsList.h:
  • wasm/WasmBBQPlan.cpp:

(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::compileFunction):

  • wasm/WasmEntryPlan.cpp:

(JSC::Wasm::EntryPlan::EntryPlan):

  • wasm/WasmEntryPlan.h:
  • wasm/WasmLLIntTierUpCounter.h:

(JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
(JSC::Wasm::LLIntTierUpCounter::optimizeSoon):

  • wasm/WasmOMGPlan.cpp:

(JSC::Wasm::OMGPlan::work):

  • wasm/WasmSlowPaths.cpp:

(JSC::LLInt::jitCompileAndSetHeuristics):

Location:
trunk/Source/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r252032 r252115  
     12019-11-05  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        [WebAssembly] Allow tiering up from LLInt to BBQ
     4        https://bugs.webkit.org/show_bug.cgi?id=203793
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Even though the interpreter was overall neutral on throughput, it's still a regression in pathological
     9        cases where massive functions spend too long in the LLInt while compiling the function with OMG. This
     10        patch makes it so that the LLInt can tier up to BBQ from the prologue, while still tiering up to OMG from
     11        from loops. This is a huge speed up on the tsf-wasm subtest of JS2:
     12
     13        # BBQ -> OMG
     14        Startup: 100.680
     15        Runtime: 1.852
     16        Score: 13.654
     17
     18        # LLInt -> OMG
     19        Startup: 378.205
     20        Runtime: 1.291
     21        Score: 22.082
     22
     23        # LLInt -> BBQ -> OMG
     24        Startup: 405.983
     25        Runtime: 2.311
     26        Score: 30.623
     27
     28        * runtime/Options.cpp:
     29        (JSC::overrideDefaults):
     30        * runtime/OptionsList.h:
     31        * wasm/WasmBBQPlan.cpp:
     32        (JSC::Wasm::BBQPlan::BBQPlan):
     33        (JSC::Wasm::BBQPlan::work):
     34        (JSC::Wasm::BBQPlan::compileFunction):
     35        * wasm/WasmEntryPlan.cpp:
     36        (JSC::Wasm::EntryPlan::EntryPlan):
     37        * wasm/WasmEntryPlan.h:
     38        * wasm/WasmLLIntTierUpCounter.h:
     39        (JSC::Wasm::LLIntTierUpCounter::optimizeAfterWarmUp):
     40        (JSC::Wasm::LLIntTierUpCounter::optimizeSoon):
     41        * wasm/WasmOMGPlan.cpp:
     42        (JSC::Wasm::OMGPlan::work):
     43        * wasm/WasmSlowPaths.cpp:
     44        (JSC::LLInt::jitCompileAndSetHeuristics):
     45
    1462019-11-04  Yusuke Suzuki  <ysuzuki@apple.com>
    247
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r251886 r252115  
    361361#endif
    362362
    363     if (Options::useWasmLLInt()) {
     363    if (Options::useWasmLLInt() && !Options::wasmLLIntTiersUpToBBQ()) {
    364364        Options::thresholdForOMGOptimizeAfterWarmUp() = 1500;
    365365        Options::thresholdForOMGOptimizeSoon() = 100;
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r251886 r252115  
    429429    v(Bool, useBBQTierUpChecks, true, Normal, "Enables tier up checks for our BBQ code.") \
    430430    v(Bool, useWebAssemblyOSR, true, Normal, nullptr) \
     431    v(Int32, thresholdForBBQOptimizeAfterWarmUp, 150, Normal, "The count before we tier up a function to BBQ.") \
     432    v(Int32, thresholdForBBQOptimizeSoon, 50, Normal, nullptr) \
    431433    v(Int32, thresholdForOMGOptimizeAfterWarmUp, 50000, Normal, "The count before we tier up a function to OMG.") \
    432434    v(Int32, thresholdForOMGOptimizeSoon, 500, Normal, nullptr) \
     
    443445    v(Bool, wasmBBQUsesAir, true, Normal, nullptr) \
    444446    v(Bool, useWasmLLInt, true, Normal, nullptr) \
     447    v(Bool, wasmLLIntTiersUpToBBQ, true, Normal, nullptr) \
    445448    v(Size, webAssemblyBBQAirModeThreshold, isIOS() ? (10 * MB) : 0, Normal, "If 0, we always use BBQ Air. If Wasm module code size hits this threshold, we compile Wasm module with B3 BBQ mode.") \
    446449    v(Bool, useWebAssemblyStreamingApi, enableWebAssemblyStreamingApi, Normal, "Allow to run WebAssembly's Streaming API") \
  • trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp

    r251886 r252115  
    5454}
    5555
     56BBQPlan::BBQPlan(Context* context, Ref<ModuleInformation> moduleInformation, uint32_t functionIndex, CodeBlock* codeBlock, CompletionTask&& completionTask)
     57    : EntryPlan(context, WTFMove(moduleInformation), WTFMove(completionTask))
     58    , m_codeBlock(codeBlock)
     59    , m_functionIndex(functionIndex)
     60{
     61    setMode(m_codeBlock->mode());
     62}
     63
    5664bool BBQPlan::prepareImpl()
    5765{
     
    8189    std::unique_ptr<InternalFunction> function = compileFunction(m_functionIndex, context, unlinkedWasmToWasmCalls, tierUp.get());
    8290
    83     Entrypoint bbqEntrypoint;
    8491    LinkBuffer linkBuffer(*context.wasmEntrypointJIT, nullptr, JITCompilationCanFail);
    8592    if (UNLIKELY(linkBuffer.didFailToAllocate())) {
     
    8996
    9097    size_t functionIndexSpace = m_functionIndex + m_moduleInformation->importFunctionCount();
    91     bbqEntrypoint.compilation = makeUnique<B3::Compilation>(
    92         FINALIZE_CODE(linkBuffer, B3CompilationPtrTag, "WebAssembly BBQ function[%i] name %s", m_functionIndex, makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
     98    SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[m_functionIndex];
     99    const Signature& signature = SignatureInformation::get(signatureIndex);
     100    function->entrypoint.compilation = makeUnique<B3::Compilation>(
     101        FINALIZE_WASM_CODE_FOR_MODE(CompilationMode::BBQMode, linkBuffer, B3CompilationPtrTag, "WebAssembly BBQ function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
    93102        WTFMove(context.wasmEntrypointByproducts));
    94 
    95     bbqEntrypoint.calleeSaveRegisters = WTFMove(function->entrypoint.calleeSaveRegisters);
    96103
    97104    MacroAssemblerCodePtr<WasmEntryPtrTag> entrypoint;
    98105    {
    99         Ref<BBQCallee> callee = BBQCallee::create(WTFMove(bbqEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls));
     106        Ref<BBQCallee> callee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls));
    100107        MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));
    101108        ASSERT(!m_codeBlock->m_bbqCallees[m_functionIndex]);
     
    110117        {
    111118            LLIntCallee& llintCallee = *m_codeBlock->m_llintCallees[m_functionIndex];
     119            auto locker = holdLock(llintCallee.tierUpCounter().m_lock);
    112120            llintCallee.setReplacement(callee.copyRef());
     121            llintCallee.tierUpCounter().m_compilationStatus = LLIntTierUpCounter::CompilationStatus::Compiled;
    113122        }
    114123        for (auto& call : callee->wasmToWasmCallsites()) {
     
    148157                if (JITCallee* replacementCallee = llintCallee->replacement())
    149158                    repatchCalls(replacementCallee->wasmToWasmCallsites());
     159                if (OMGForOSREntryCallee* osrEntryCallee = llintCallee->osrEntryCallee())
     160                    repatchCalls(osrEntryCallee->wasmToWasmCallsites());
    150161            }
    151162            if (BBQCallee* bbqCallee = m_codeBlock->m_bbqCallees[i].get()) {
     
    191202    SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
    192203    const Signature& signature = SignatureInformation::get(signatureIndex);
    193     unsigned functionIndexSpace = m_wasmToWasmExitStubs.size() + functionIndex;
     204    unsigned functionIndexSpace = m_moduleInformation->importFunctionCount() + functionIndex;
    194205    ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex);
    195206    ASSERT(validateFunction(function, signature, m_moduleInformation.get()));
  • trunk/Source/JavaScriptCore/wasm/WasmEntryPlan.cpp

    r251886 r252115  
    6464}
    6565
     66EntryPlan::EntryPlan(Context* context, Ref<ModuleInformation> moduleInformation, CompletionTask&& task)
     67    : Base(context, WTFMove(moduleInformation), WTFMove(task))
     68    , m_streamingParser(m_moduleInformation.get(), *this)
     69    , m_state(State::Initial)
     70    , m_asyncWork(AsyncWork::FullCompile)
     71{
     72}
     73
    6674EntryPlan::EntryPlan(Context* context, AsyncWork work, CompletionTask&& task)
    6775    : Base(context, WTFMove(task))
  • trunk/Source/JavaScriptCore/wasm/WasmEntryPlan.h

    r251886 r252115  
    5050    EntryPlan(Context*, Ref<ModuleInformation>, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
    5151    JS_EXPORT_PRIVATE EntryPlan(Context*, Vector<uint8_t>&&, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
     52    EntryPlan(Context*, Ref<ModuleInformation>, CompletionTask&&);
    5253    EntryPlan(Context*, AsyncWork, CompletionTask&&);
    5354
  • trunk/Source/JavaScriptCore/wasm/WasmLLIntTierUpCounter.h

    r251886 r252115  
    5151    void optimizeAfterWarmUp()
    5252    {
    53         setNewThreshold(Options::thresholdForOMGOptimizeAfterWarmUp(), nullptr);
     53        if (Options::wasmLLIntTiersUpToBBQ())
     54            setNewThreshold(Options::thresholdForBBQOptimizeAfterWarmUp(), nullptr);
     55        else
     56            setNewThreshold(Options::thresholdForOMGOptimizeAfterWarmUp(), nullptr);
    5457    }
    5558
     
    6164    void optimizeSoon()
    6265    {
    63         setNewThreshold(Options::thresholdForOMGOptimizeSoon(), nullptr);
     66        if (Options::wasmLLIntTiersUpToBBQ())
     67            setNewThreshold(Options::thresholdForBBQOptimizeSoon(), nullptr);
     68        else
     69            setNewThreshold(Options::thresholdForOMGOptimizeSoon(), nullptr);
    6470    }
    6571
  • trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp

    r251886 r252115  
    122122                bbqCallee->setReplacement(callee.copyRef());
    123123                bbqCallee->tierUpCount()->m_compilationStatusForOMG = TierUpCount::CompilationStatus::Compiled;
    124             } else if (LLIntCallee* llintCallee = m_codeBlock->m_llintCallees[m_functionIndex].get()) {
     124            }
     125            if (LLIntCallee* llintCallee = m_codeBlock->m_llintCallees[m_functionIndex].get()) {
    125126                auto locker = holdLock(llintCallee->tierUpCounter().m_lock);
    126127                llintCallee->setReplacement(callee.copyRef());
     
    164165                if (JITCallee* replacementCallee = llintCallee->replacement())
    165166                    repatchCalls(replacementCallee->wasmToWasmCallsites());
     167                if (OMGForOSREntryCallee* osrEntryCallee = llintCallee->osrEntryCallee())
     168                    repatchCalls(osrEntryCallee->wasmToWasmCallsites());
    166169            }
    167170            if (BBQCallee* bbqCallee = m_codeBlock->m_bbqCallees[i].get()) {
  • trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp

    r251911 r252115  
    111111    if (compile) {
    112112        uint32_t functionIndex = codeBlock->functionIndex();
    113         Ref<Wasm::OMGPlan> plan = adoptRef(*new Wasm::OMGPlan(instance->context(), Ref<Wasm::Module>(instance->module()), functionIndex, instance->memory()->mode(), Wasm::Plan::dontFinalize()));
    114 
    115         Wasm::ensureWorklist().enqueue(plan.copyRef());
     113        RefPtr<Wasm::Plan> plan;
     114        if (Options::wasmLLIntTiersUpToBBQ())
     115            plan = adoptRef(*new Wasm::BBQPlan(instance->context(), makeRef(const_cast<Wasm::ModuleInformation&>(instance->module().moduleInformation())), functionIndex, instance->codeBlock(), Wasm::Plan::dontFinalize()));
     116        else
     117            plan = adoptRef(*new Wasm::OMGPlan(instance->context(), Ref<Wasm::Module>(instance->module()), functionIndex, instance->memory()->mode(), Wasm::Plan::dontFinalize()));
     118
     119        Wasm::ensureWorklist().enqueue(makeRef(*plan));
    116120        if (UNLIKELY(!Options::useConcurrentJIT()))
    117121            plan->waitForCompletion();
Note: See TracChangeset for help on using the changeset viewer.