Ignore:
Timestamp:
Mar 16, 2017, 2:19:23 PM (8 years ago)
Author:
[email protected]
Message:

FTL should support global and eval code
https://bugs.webkit.org/show_bug.cgi?id=169656

Reviewed by Geoffrey Garen and Saam Barati.

JSTests:

Added basic performance tests of global and eval code. These tests will run a lot faster in with
the FTL because of the object allocation.

  • microbenchmarks/eval-code-ftl-reentry.js: Added.
  • microbenchmarks/eval-code-ftl.js: Added.
  • microbenchmarks/global-code-ftl.js: Added.
  • stress/arith-log-on-various-types.js: This was a flaky fail with concurrent JIT, so I stopped running it with concurrent JIT. The failure was its assertion about how many times something gets compiled.

Source/JavaScriptCore:

Turned off the restriction against global and eval code running in the FTL, and then fixed all of
the things that didn't work.

This is a big speed-up on microbenchmarks that I wrote for this patch. One of the reasons why we
hadn't done this earlier is that we've never seen a benchmark that needed it. Global and eval
code rarely gets FTL-hot. Still, this seems like possibly a small JetStream speed-up.

  • dfg/DFGJITCode.cpp:

(JSC::DFG::JITCode::setOSREntryBlock): I outlined this for better debugging.

  • dfg/DFGJITCode.h:

(JSC::DFG::JITCode::setOSREntryBlock): Deleted.

  • dfg/DFGNode.h:

(JSC::DFG::Node::isSemanticallySkippable): It turns out that global code often has InvalidationPoints before LoopHints. They are also skippable from the standpoint of OSR entrypoint analysis.

  • dfg/DFGOperations.cpp: Don't do any normal compiles of global code - just do OSR compiles.
  • ftl/FTLCapabilities.cpp: Enable FTL for global and eval code.

(JSC::FTL::canCompile):

  • ftl/FTLCompile.cpp: Just debugging clean-ups.

(JSC::FTL::compile):

  • ftl/FTLJITFinalizer.cpp: Implement finalize() and ensure that we only do things with the entrypoint buffer if we have one. We won't have one for eval code that we aren't OSR entering into.

(JSC::FTL::JITFinalizer::finalize):
(JSC::FTL::JITFinalizer::finalizeFunction):
(JSC::FTL::JITFinalizer::finalizeCommon):

  • ftl/FTLJITFinalizer.h:
  • ftl/FTLLink.cpp: When entering a function normally, we need the "entrypoint" to put the arity check code. Global and eval code don't need this.

(JSC::FTL::link):

  • ftl/FTLOSREntry.cpp: Fix a dataLog statement.

(JSC::FTL::prepareOSREntry):

  • ftl/FTLOSRExitCompiler.cpp: Remove dead code that happened to assert that we're exiting from a function.

(JSC::FTL::compileStub):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ftl/FTLLink.cpp

    r209764 r214069  
    128128    switch (graph.m_plan.mode) {
    129129    case FTLMode: {
    130         CCallHelpers::JumpList mainPathJumps;
    131    
    132         jit.load32(
    133             frame.withOffset(sizeof(Register) * CallFrameSlot::argumentCount),
    134             GPRInfo::regT1);
    135         mainPathJumps.append(jit.branch32(
    136             CCallHelpers::AboveOrEqual, GPRInfo::regT1,
    137             CCallHelpers::TrustedImm32(codeBlock->numParameters())));
    138         jit.emitFunctionPrologue();
    139         jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    140         jit.storePtr(GPRInfo::callFrameRegister, &vm.topCallFrame);
    141         CCallHelpers::Call callArityCheck = jit.call();
    142 
    143         auto noException = jit.branch32(CCallHelpers::GreaterThanOrEqual, GPRInfo::returnValueGPR, CCallHelpers::TrustedImm32(0));
    144         jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
    145         jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
    146         jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
    147         CCallHelpers::Call callLookupExceptionHandlerFromCallerFrame = jit.call();
    148         jit.jumpToExceptionHandler();
    149         noException.link(&jit);
    150 
    151         if (!ASSERT_DISABLED) {
    152             jit.load64(vm.addressOfException(), GPRInfo::regT1);
    153             jit.jitAssertIsNull(GPRInfo::regT1);
     130        if (codeBlock->codeType() == FunctionCode) {
     131            CCallHelpers::JumpList mainPathJumps;
     132   
     133            jit.load32(
     134                frame.withOffset(sizeof(Register) * CallFrameSlot::argumentCount),
     135                GPRInfo::regT1);
     136            mainPathJumps.append(jit.branch32(
     137                                     CCallHelpers::AboveOrEqual, GPRInfo::regT1,
     138                                     CCallHelpers::TrustedImm32(codeBlock->numParameters())));
     139            jit.emitFunctionPrologue();
     140            jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     141            jit.storePtr(GPRInfo::callFrameRegister, &vm.topCallFrame);
     142            CCallHelpers::Call callArityCheck = jit.call();
     143
     144            auto noException = jit.branch32(CCallHelpers::GreaterThanOrEqual, GPRInfo::returnValueGPR, CCallHelpers::TrustedImm32(0));
     145            jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
     146            jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
     147            jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
     148            CCallHelpers::Call callLookupExceptionHandlerFromCallerFrame = jit.call();
     149            jit.jumpToExceptionHandler();
     150            noException.link(&jit);
     151
     152            if (!ASSERT_DISABLED) {
     153                jit.load64(vm.addressOfException(), GPRInfo::regT1);
     154                jit.jitAssertIsNull(GPRInfo::regT1);
     155            }
     156
     157            jit.move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
     158            jit.emitFunctionEpilogue();
     159            mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
     160            jit.emitFunctionPrologue();
     161            CCallHelpers::Call callArityFixup = jit.call();
     162            jit.emitFunctionEpilogue();
     163            mainPathJumps.append(jit.jump());
     164
     165            linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
     166            if (linkBuffer->didFailToAllocate()) {
     167                state.allocationFailed = true;
     168                return;
     169            }
     170            linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
     171            linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, lookupExceptionHandlerFromCallerFrame);
     172            linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
     173            linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
    154174        }
    155 
    156         jit.move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
    157         jit.emitFunctionEpilogue();
    158         mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
    159         jit.emitFunctionPrologue();
    160         CCallHelpers::Call callArityFixup = jit.call();
    161         jit.emitFunctionEpilogue();
    162         mainPathJumps.append(jit.jump());
    163 
    164         linkBuffer = std::make_unique<LinkBuffer>(vm, jit, codeBlock, JITCompilationCanFail);
    165         if (linkBuffer->didFailToAllocate()) {
    166             state.allocationFailed = true;
    167             return;
    168         }
    169         linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
    170         linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, lookupExceptionHandlerFromCallerFrame);
    171         linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
    172         linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
    173 
     175       
    174176        state.jitCode->initializeAddressForCall(MacroAssemblerCodePtr(bitwise_cast<void*>(state.generatedFunction)));
    175177        break;
Note: See TracChangeset for help on using the changeset viewer.