Ignore:
Timestamp:
Jan 30, 2014, 3:00:16 PM (11 years ago)
Author:
[email protected]
Message:

FTL should support GetById(Untyped:)
https://bugs.webkit.org/show_bug.cgi?id=127750

Reviewed by Oliver Hunt.

This was supposed to be easy. Indeed, the actual GetById UntypedUse case was easy. But
then it expanded coverage by a lot and I got to deal with three bugs. So, this has
some additional changes:

Also make it safe for LLVM to duplicate calls to patchpoints and stackmaps. Previously
we incorrectly assumed that if we emitted a patchpoint, then there would only be one
copy of that patchpoint (with that ID) in the resulting machine code and in the
stackmaps section. That's obviously a bad assumption - LLVM is allowed to do anything
it wants so long as the outcome of executing the code has a semantically equivalent
meaning to the IR we gave it, and duplicating code is trivially OK under this rule. We
should be OK with it, too. The solution is to add Vectors in a bunch of places that
previously just thought they only had one value. For example, an InlineCacheDescriptor
now has a Vector of generators - one generator for each copy that LLVM stamped out.
Normally there will only be one copy, of course - since duplication is usually
unprofitable. But, if LLVM decides that copying would be groovy then we will no longer
barf.

Also fix SSA conversion. It turns out that we mishandled the case where a block had
multiple Phi functions for the same local. If any of those CPS Phis fail to trivialize
in the Aycock-Horspool fixpoint, we need to insert an SSA Phi. Previously, it was
assuming that so long as the head CPS Phi was trivial, we could forego SSA Phi
insertion. That's wrong if the head CPS Phi trivialized but ended up pointing to a
non-trivial CPS Phi in the same block. This madness with trees of Phis occurs because
we try to save on compile times: no Phi ever has more than three children even if the
block has more than three predecessors; we just build out a tree of Phis to satisfy
all predecessors. So weird.

And finally, fix DFG->FTL OSR entry's reconstruction of 'this' in a constructor. That
reconstruction code, JITCode::reconstruct(), had a work-around for the case where we
were entering into a constructor at the prologue. In that case, 'this' is definitely
unavailable. But the OSR code does reconstructions at LoopHints, which aren't at the
prologue, and so 'this' should totally be available.

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGJITCode.cpp:

(JSC::DFG::JITCode::reconstruct):

  • dfg/DFGNode.h:

(JSC::DFG::Node::tryGetVariableAccessData):

  • dfg/DFGSSAConversionPhase.cpp:

(JSC::DFG::SSAConversionPhase::run):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLCompile.cpp:

(JSC::FTL::generateICFastPath):
(JSC::FTL::fixFunctionBasedOnStackMaps):

  • ftl/FTLInlineCacheDescriptor.h:
  • ftl/FTLJITFinalizer.cpp:

(JSC::FTL::JITFinalizer::codeSize):

  • ftl/FTLJSCall.cpp:

(JSC::FTL::JSCall::JSCall):

  • ftl/FTLJSCall.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileGetById):
(JSC::FTL::LowerDFGToLLVM::getById):

  • ftl/FTLOSREntry.cpp:

(JSC::FTL::prepareOSREntry):

  • ftl/FTLStackMaps.cpp:

(JSC::FTL::StackMaps::getRecordMap):

  • ftl/FTLStackMaps.h:
  • tests/stress/get-by-id-untyped.js: Added.

(foo):

File:
1 edited

Legend:

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

    r163070 r163119  
    16051605    void compileGetById()
    16061606    {
    1607         // UntypedUse is a bit harder to reason about and I'm not sure how best to do it, yet.
    1608         // Basically we need to emit a cell branch that takes you to the slow path, but the slow
    1609         // path is generated by the IC generator so we can't jump to it from here. And the IC
    1610         // generator currently doesn't know how to emit such a branch. So, for now, we just
    1611         // restrict this to CellUse.
    1612         ASSERT(m_node->child1().useKind() == CellUse);
    1613 
    1614         LValue base = lowCell(m_node->child1());
    1615         StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
    1616 
    1617         // Arguments: id, bytes, target, numArgs, args...
    1618         unsigned stackmapID = m_stackmapIDs++;
    1619        
    1620         if (Options::verboseCompilation())
    1621             dataLog("    Emitting GetById patchpoint with stackmap #", stackmapID, "\n");
    1622        
    1623         LValue call = m_out.call(
    1624             m_out.patchpointInt64Intrinsic(),
    1625             m_out.constInt64(stackmapID), m_out.constInt32(sizeOfGetById()),
    1626             constNull(m_out.ref8), m_out.constInt32(1), base);
    1627         setInstructionCallingConvention(call, LLVMAnyRegCallConv);
    1628         setJSValue(call);
    1629        
    1630         m_ftlState.getByIds.append(GetByIdDescriptor(stackmapID, m_node->codeOrigin, uid));
     1607        // Pretty much the only reason why we don't also support GetByIdFlush is because:
     1608        // https://bugs.webkit.org/show_bug.cgi?id=125711
     1609       
     1610        switch (m_node->child1().useKind()) {
     1611        case CellUse: {
     1612            setJSValue(getById(lowCell(m_node->child1())));
     1613            return;
     1614        }
     1615           
     1616        case UntypedUse: {
     1617            // This is pretty weird, since we duplicate the slow path both here and in the
     1618            // code generated by the IC. We should investigate making this less bad.
     1619            // https://bugs.webkit.org/show_bug.cgi?id=127830
     1620            LValue value = lowJSValue(m_node->child1());
     1621           
     1622            LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped cell case"));
     1623            LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped not cell case"));
     1624            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetById untyped continuation"));
     1625           
     1626            m_out.branch(isCell(value), cellCase, notCellCase);
     1627           
     1628            LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
     1629            ValueFromBlock cellResult = m_out.anchor(getById(value));
     1630            m_out.jump(continuation);
     1631           
     1632            m_out.appendTo(notCellCase, continuation);
     1633            ValueFromBlock notCellResult = m_out.anchor(vmCall(
     1634                m_out.operation(operationGetById),
     1635                m_callFrame, getUndef(m_out.intPtr), value,
     1636                m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
     1637            m_out.jump(continuation);
     1638           
     1639            m_out.appendTo(continuation, lastNext);
     1640            setJSValue(m_out.phi(m_out.int64, cellResult, notCellResult));
     1641            return;
     1642        }
     1643           
     1644        default:
     1645            RELEASE_ASSERT_NOT_REACHED();
     1646            return;
     1647        }
    16311648    }
    16321649   
     
    33963413    }
    33973414   
     3415    LValue getById(LValue base)
     3416    {
     3417        StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
     3418
     3419        // Arguments: id, bytes, target, numArgs, args...
     3420        unsigned stackmapID = m_stackmapIDs++;
     3421       
     3422        if (Options::verboseCompilation())
     3423            dataLog("    Emitting GetById patchpoint with stackmap #", stackmapID, "\n");
     3424       
     3425        LValue call = m_out.call(
     3426            m_out.patchpointInt64Intrinsic(),
     3427            m_out.constInt64(stackmapID), m_out.constInt32(sizeOfGetById()),
     3428            constNull(m_out.ref8), m_out.constInt32(1), base);
     3429        setInstructionCallingConvention(call, LLVMAnyRegCallConv);
     3430       
     3431        m_ftlState.getByIds.append(GetByIdDescriptor(stackmapID, m_node->codeOrigin, uid));
     3432       
     3433        return call;
     3434    }
     3435   
    33983436    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
    33993437    {
Note: See TracChangeset for help on using the changeset viewer.