⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 194431 in webkit


Ignore:
Timestamp:
Dec 28, 2015, 2:46:51 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

FTL B3 should know that used registers are not the same thing as used registers. Rename the
latter to unavailable registers to avoid future confusion.
https://bugs.webkit.org/show_bug.cgi?id=152572

Reviewed by Saam Barati.

Prior to this change, we used the term "used registers" in two different senses:

  • The set of registers that are live at some point in the current compilation unit. A register is live at some point if it is read after that point on some path through that point.
  • The set of registers that are not available for scratch register use at some point. A register may not be available if it is live or if it is a callee-save register but it is not being saved by the current compilation.

In the old FTL LLVM code, we had some translations from the first sense into the second
sense. We forgot to do those in FTL B3, and so we get crashes, for example in V8/splay. That
benchmark highlighted this issue because it fired some lazy slow paths, and then used an
unsaved callee-save for scratch.

Curiously, we could merge these two definitions by observing that, in some sense, an unsaved
callee save is live at every point in a compilation in the sense that it may contain a value
that will be read when the compilation returns. That's pretty cool, but it feels strange to
me. This isn't how we would normally define liveness of registers. It's not how the
Air::TmpLiveness analysis would do it for any of its other clients.

So, this changes B3 to have two different concepts:

  • Used registers. These are the registers that are live.
  • Unavailable registers. These are the registers that are not available for scratch. It's always a superset of used registers.

This also changes FTLLower to use unavailableRegisters() pretty much everywhere that it
previously used usedRegisters().

This makes it possible to run V8/splay.

  • b3/B3StackmapGenerationParams.cpp:

(JSC::B3::StackmapGenerationParams::usedRegisters):
(JSC::B3::StackmapGenerationParams::unavailableRegisters):
(JSC::B3::StackmapGenerationParams::proc):

  • b3/B3StackmapGenerationParams.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compilePutById):
(JSC::FTL::DFG::LowerDFGToLLVM::getById):
(JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r194428 r194431  
     12015-12-27  Filip Pizlo  <fpizlo@apple.com>
     2
     3        FTL B3 should know that used registers are not the same thing as used registers. Rename the
     4        latter to unavailable registers to avoid future confusion.
     5        https://bugs.webkit.org/show_bug.cgi?id=152572
     6
     7        Reviewed by Saam Barati.
     8
     9        Prior to this change, we used the term "used registers" in two different senses:
     10
     11        - The set of registers that are live at some point in the current compilation unit. A
     12          register is live at some point if it is read after that point on some path through that
     13          point.
     14
     15        - The set of registers that are not available for scratch register use at some point. A
     16          register may not be available if it is live or if it is a callee-save register but it is
     17          not being saved by the current compilation.
     18
     19        In the old FTL LLVM code, we had some translations from the first sense into the second
     20        sense. We forgot to do those in FTL B3, and so we get crashes, for example in V8/splay. That
     21        benchmark highlighted this issue because it fired some lazy slow paths, and then used an
     22        unsaved callee-save for scratch.
     23 
     24        Curiously, we could merge these two definitions by observing that, in some sense, an unsaved
     25        callee save is live at every point in a compilation in the sense that it may contain a value
     26        that will be read when the compilation returns. That's pretty cool, but it feels strange to
     27        me. This isn't how we would normally define liveness of registers. It's not how the
     28        Air::TmpLiveness analysis would do it for any of its other clients.
     29
     30        So, this changes B3 to have two different concepts:
     31
     32        - Used registers. These are the registers that are live.
     33
     34        - Unavailable registers. These are the registers that are not available for scratch. It's
     35          always a superset of used registers.
     36
     37        This also changes FTLLower to use unavailableRegisters() pretty much everywhere that it
     38        previously used usedRegisters().
     39
     40        This makes it possible to run V8/splay.
     41
     42        * b3/B3StackmapGenerationParams.cpp:
     43        (JSC::B3::StackmapGenerationParams::usedRegisters):
     44        (JSC::B3::StackmapGenerationParams::unavailableRegisters):
     45        (JSC::B3::StackmapGenerationParams::proc):
     46        * b3/B3StackmapGenerationParams.h:
     47        * ftl/FTLLowerDFGToLLVM.cpp:
     48        (JSC::FTL::DFG::LowerDFGToLLVM::compilePutById):
     49        (JSC::FTL::DFG::LowerDFGToLLVM::getById):
     50        (JSC::FTL::DFG::LowerDFGToLLVM::lazySlowPath):
     51
    1522015-12-25  Andy Estes  <aestes@apple.com>
    253
  • trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp

    r193640 r194431  
    4242}
    4343
     44RegisterSet StackmapGenerationParams::unavailableRegisters() const
     45{
     46    RegisterSet result = usedRegisters();
     47   
     48    RegisterSet unsavedCalleeSaves = RegisterSet::vmCalleeSaveRegisters();
     49    for (const RegisterAtOffset& regAtOffset : m_context.code->calleeSaveRegisters())
     50        unsavedCalleeSaves.clear(regAtOffset.reg());
     51
     52    result.merge(unsavedCalleeSaves);
     53    return result;
     54}
     55
    4456Procedure& StackmapGenerationParams::proc() const
    4557{
  • trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.h

    r193640 r194431  
    6060    const RegisterSet& usedRegisters() const;
    6161
     62    // This is a useful helper if you want to do register allocation inside of a patchpoint. You
     63    // can only use callee-save registers if they were saved in the prologue. This gives you the
     64    // used register set that's useful for such settings by returning:
     65    //
     66    //     usedRegisters() | (RegisterSet::calleeSaveRegisters() - proc.calleeSaveRegisters())
     67    RegisterSet unavailableRegisters() const;
     68
    6269    // This is provided for convenience; it means that you don't have to capture it if you don't want to.
    6370    Procedure& proc() const;
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r194383 r194431  
    25872587                    jit.codeBlock(), node->origin.semantic,
    25882588                    state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic),
    2589                     params.usedRegisters(), JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()),
    2590                     GPRInfo::patchpointScratchRegister, ecmaMode,
     2589                    params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
     2590                    JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
    25912591                    node->op() == PutByIdDirect ? Direct : NotDirect);
    25922592
     
    26042604                        CCallHelpers::Label slowPathBegin = jit.label();
    26052605                        CCallHelpers::Call slowPathCall = callOperation(
    2606                             *state, params.usedRegisters(), jit, node->origin.semantic, &exceptions,
    2607                             generator->slowPathFunction(), InvalidGPRReg,
     2606                            *state, params.unavailableRegisters(), jit, node->origin.semantic,
     2607                            &exceptions, generator->slowPathFunction(), InvalidGPRReg,
    26082608                            CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
    26092609                            params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
     
    70927092                    jit.codeBlock(), node->origin.semantic,
    70937093                    state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic),
    7094                     params.usedRegisters(), JSValueRegs(params[1].gpr()), JSValueRegs(params[0].gpr()));
     7094                    params.unavailableRegisters(), JSValueRegs(params[1].gpr()),
     7095                    JSValueRegs(params[0].gpr()));
    70957096
    70967097                generator->generateFastPath(jit);
     
    71077108                        CCallHelpers::Label slowPathBegin = jit.label();
    71087109                        CCallHelpers::Call slowPathCall = callOperation(
    7109                             *state, params.usedRegisters(), jit, node->origin.semantic, &exceptions,
    7110                             operationGetByIdOptimize, params[0].gpr(),
     7110                            *state, params.unavailableRegisters(), jit, node->origin.semantic,
     7111                            &exceptions, operationGetByIdOptimize, params[0].gpr(),
    71117112                            CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
    71127113                            CCallHelpers::TrustedImmPtr(uid)).call();
     
    85178518                CCallHelpers::Label done = jit.label();
    85188519
    8519                 RegisterSet usedRegisters = params.usedRegisters();
     8520                RegisterSet usedRegisters = params.unavailableRegisters();
    85208521
    85218522                // FIXME: As part of handling exceptions, we need to create a concrete OSRExit here.
     
    85458546                                        vm->getCTIStub(
    85468547                                            lazySlowPathGenerationThunkGenerator).code()));
    8547                                    
     8548                               
    85488549                                CodeLocationJump linkedPatchableJump = CodeLocationJump(
    85498550                                    linkBuffer.locationOf(patchableJump));
Note: See TracChangeset for help on using the changeset viewer.