Changeset 228411 in webkit


Ignore:
Timestamp:
Feb 12, 2018 5:12:28 PM (6 years ago)
Author:
sbarati@apple.com
Message:

Add a GetIndexMask node and make it an input to GetByVal for array and typed array accesses in DFG SSA
https://bugs.webkit.org/show_bug.cgi?id=182633
<rdar://problem/37441037>

Reviewed by Keith Miller.

This patch introduces a GetIndexMask node to DFG SSA. This is an input to
GetByVal for the GetByVal variants that do conservative index masking.
The reason I'm adding this node is I realized there were loads of
the butterfly index mask inside loops that B3 couldn't reason about
because B3 can't arbitrarily hoist loads out of loops if those loops
have side exits (because the side exit might be protecting the safety of the
load). However, for these loops I analyzed, the DFG would be able to hoist
these loads out of loops because it knows about JS semantics to correctly
reason about the safety of hoisting the load.

This is a 1% speedup on JetStream on Mac and iOS in my testing.

This patch also adds some infrastructure for eliminating and doing CSE on
varargs nodes. Because this patch makes GetByVal a varargs node, I ran into
issues we never had before. We never had a varargs node that could be CSEd or be
hoisted out of a loop until I made GetByVal varargs. To make it all work,
I added a CheckVarargs node. This is just like Check, but it's varargs.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGAdjacencyList.h:

(JSC::DFG::AdjacencyList::AdjacencyList):

  • dfg/DFGArgumentsEliminationPhase.cpp:
  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGBasicBlock.cpp:

(JSC::DFG::BasicBlock::replaceTerminal):

  • dfg/DFGBasicBlock.h:

(JSC::DFG::BasicBlock::findTerminal const):

  • dfg/DFGBasicBlockInlines.h:

(JSC::DFG::BasicBlock::replaceTerminal):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCFGSimplificationPhase.cpp:

(JSC::DFG::CFGSimplificationPhase::mergeBlocks):

  • dfg/DFGCPSRethreadingPhase.cpp:

(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):

  • dfg/DFGCSEPhase.cpp:
  • dfg/DFGCleanUpPhase.cpp:

(JSC::DFG::CleanUpPhase::run):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::fixUpsilons):

  • dfg/DFGDCEPhase.cpp:

(JSC::DFG::DCEPhase::run):
(JSC::DFG::DCEPhase::fixupBlock):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupChecksInBlock):

  • dfg/DFGHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGHeapLocation.h:
  • dfg/DFGIntegerCheckCombiningPhase.cpp:

(JSC::DFG::IntegerCheckCombiningPhase::handleBlock):

  • dfg/DFGIntegerRangeOptimizationPhase.cpp:
  • dfg/DFGLICMPhase.cpp:

(JSC::DFG::LICMPhase::attemptHoist):

  • dfg/DFGMayExit.cpp:
  • dfg/DFGNode.cpp:

(JSC::DFG::Node::remove):
(JSC::DFG::Node::convertToIdentityOn):

  • dfg/DFGNode.h:

(JSC::DFG::Node::replaceWith):

  • dfg/DFGNodeType.h:
  • dfg/DFGObjectAllocationSinkingPhase.cpp:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGPureValue.cpp:

(JSC::DFG::PureValue::dump const):

  • dfg/DFGPureValue.h:

(JSC::DFG::PureValue::PureValue):

  • dfg/DFGPutStackSinkingPhase.cpp:
  • dfg/DFGSSAConversionPhase.cpp:

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

  • dfg/DFGSSALoweringPhase.cpp:

(JSC::DFG::SSALoweringPhase::handleNode):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithString):
(JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithSymbol):
(JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStoreBarrierClusteringPhase.cpp:
  • dfg/DFGValidate.cpp:
  • dfg/DFGVarargsForwardingPhase.cpp:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayMask):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharAt):
(JSC::FTL::DFG::LowerDFGToB3::maskedIndex):
(JSC::FTL::DFG::LowerDFGToB3::pointerIntoTypedArray):

Location:
trunk/Source/JavaScriptCore
Files:
44 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r228402 r228411  
     12018-02-12  Saam Barati  <sbarati@apple.com>
     2
     3        Add a GetIndexMask node and make it an input to GetByVal for array and typed array accesses in DFG SSA
     4        https://bugs.webkit.org/show_bug.cgi?id=182633
     5        <rdar://problem/37441037>
     6
     7        Reviewed by Keith Miller.
     8
     9        This patch introduces a GetIndexMask node to DFG SSA. This is an input to
     10        GetByVal for the GetByVal variants that do conservative index masking.
     11        The reason I'm adding this node is I realized there were loads of
     12        the butterfly index mask inside loops that B3 couldn't reason about
     13        because B3 can't arbitrarily hoist loads out of loops if those loops
     14        have side exits (because the side exit might be protecting the safety of the
     15        load). However, for these loops I analyzed, the DFG would be able to hoist
     16        these loads out of loops because it knows about JS semantics to correctly
     17        reason about the safety of hoisting the load.
     18       
     19        This is a 1% speedup on JetStream on Mac and iOS in my testing.
     20       
     21        This patch also adds some infrastructure for eliminating and doing CSE on
     22        varargs nodes. Because this patch makes GetByVal a varargs node, I ran into
     23        issues we never had before. We never had a varargs node that could be CSEd or be
     24        hoisted out of a loop until I made GetByVal varargs. To make it all work,
     25        I added a CheckVarargs node. This is just like Check, but it's varargs.
     26
     27        * dfg/DFGAbstractInterpreterInlines.h:
     28        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     29        * dfg/DFGAdjacencyList.h:
     30        (JSC::DFG::AdjacencyList::AdjacencyList):
     31        * dfg/DFGArgumentsEliminationPhase.cpp:
     32        * dfg/DFGBackwardsPropagationPhase.cpp:
     33        (JSC::DFG::BackwardsPropagationPhase::propagate):
     34        * dfg/DFGBasicBlock.cpp:
     35        (JSC::DFG::BasicBlock::replaceTerminal):
     36        * dfg/DFGBasicBlock.h:
     37        (JSC::DFG::BasicBlock::findTerminal const):
     38        * dfg/DFGBasicBlockInlines.h:
     39        (JSC::DFG::BasicBlock::replaceTerminal):
     40        * dfg/DFGByteCodeParser.cpp:
     41        (JSC::DFG::ByteCodeParser::parseBlock):
     42        * dfg/DFGCFGSimplificationPhase.cpp:
     43        (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
     44        * dfg/DFGCPSRethreadingPhase.cpp:
     45        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
     46        (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
     47        * dfg/DFGCSEPhase.cpp:
     48        * dfg/DFGCleanUpPhase.cpp:
     49        (JSC::DFG::CleanUpPhase::run):
     50        * dfg/DFGClobberize.h:
     51        (JSC::DFG::clobberize):
     52        * dfg/DFGConstantFoldingPhase.cpp:
     53        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     54        (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
     55        * dfg/DFGDCEPhase.cpp:
     56        (JSC::DFG::DCEPhase::run):
     57        (JSC::DFG::DCEPhase::fixupBlock):
     58        * dfg/DFGDoesGC.cpp:
     59        (JSC::DFG::doesGC):
     60        * dfg/DFGFixupPhase.cpp:
     61        (JSC::DFG::FixupPhase::fixupNode):
     62        (JSC::DFG::FixupPhase::fixupChecksInBlock):
     63        * dfg/DFGHeapLocation.cpp:
     64        (WTF::printInternal):
     65        * dfg/DFGHeapLocation.h:
     66        * dfg/DFGIntegerCheckCombiningPhase.cpp:
     67        (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
     68        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
     69        * dfg/DFGLICMPhase.cpp:
     70        (JSC::DFG::LICMPhase::attemptHoist):
     71        * dfg/DFGMayExit.cpp:
     72        * dfg/DFGNode.cpp:
     73        (JSC::DFG::Node::remove):
     74        (JSC::DFG::Node::convertToIdentityOn):
     75        * dfg/DFGNode.h:
     76        (JSC::DFG::Node::replaceWith):
     77        * dfg/DFGNodeType.h:
     78        * dfg/DFGObjectAllocationSinkingPhase.cpp:
     79        * dfg/DFGPredictionPropagationPhase.cpp:
     80        * dfg/DFGPureValue.cpp:
     81        (JSC::DFG::PureValue::dump const):
     82        * dfg/DFGPureValue.h:
     83        (JSC::DFG::PureValue::PureValue):
     84        * dfg/DFGPutStackSinkingPhase.cpp:
     85        * dfg/DFGSSAConversionPhase.cpp:
     86        (JSC::DFG::SSAConversionPhase::run):
     87        * dfg/DFGSSALoweringPhase.cpp:
     88        (JSC::DFG::SSALoweringPhase::handleNode):
     89        * dfg/DFGSafeToExecute.h:
     90        (JSC::DFG::safeToExecute):
     91        * dfg/DFGSpeculativeJIT.cpp:
     92        (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
     93        (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
     94        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
     95        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
     96        (JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithString):
     97        (JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithSymbol):
     98        (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
     99        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
     100        * dfg/DFGSpeculativeJIT.h:
     101        * dfg/DFGSpeculativeJIT32_64.cpp:
     102        (JSC::DFG::SpeculativeJIT::compile):
     103        * dfg/DFGSpeculativeJIT64.cpp:
     104        (JSC::DFG::SpeculativeJIT::compile):
     105        * dfg/DFGStoreBarrierClusteringPhase.cpp:
     106        * dfg/DFGValidate.cpp:
     107        * dfg/DFGVarargsForwardingPhase.cpp:
     108        * ftl/FTLCapabilities.cpp:
     109        (JSC::FTL::canCompile):
     110        * ftl/FTLLowerDFGToB3.cpp:
     111        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     112        (JSC::FTL::DFG::LowerDFGToB3::compileGetArrayMask):
     113        (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
     114        (JSC::FTL::DFG::LowerDFGToB3::compileStringCharAt):
     115        (JSC::FTL::DFG::LowerDFGToB3::maskedIndex):
     116        (JSC::FTL::DFG::LowerDFGToB3::pointerIntoTypedArray):
     117
    11182018-02-12  Mark Lam  <mark.lam@apple.com>
    2119
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r228035 r228411  
    17321732            break;
    17331733        case Array::Undecided: {
    1734             JSValue index = forNode(node->child2()).value();
     1734            JSValue index = forNode(m_graph.child(node, 1)).value();
    17351735            if (index && index.isInt32() && index.asInt32() >= 0) {
    17361736                setConstant(node, jsUndefined());
     
    25262526        break;
    25272527    }
     2528
     2529    case GetArrayMask:
     2530        forNode(node).setType(SpecInt32Only);
     2531        break;
    25282532
    25292533    case GetVectorLength: {
     
    33453349        break;
    33463350           
     3351    case CheckVarargs:
    33473352    case Check: {
    33483353        // Simplify out checks that don't actually do checking.
    3349         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
    3350             Edge edge = node->children.child(i);
     3354        m_graph.doToChildren(node, [&] (Edge edge) {
    33513355            if (!edge)
    3352                 break;
    3353             if (edge.isProved() || edge.willNotHaveCheck()) {
     3356                return;
     3357            if (edge.isProved() || edge.willNotHaveCheck())
    33543358                m_state.setFoundConstants(true);
    3355                 break;
    3356             }
    3357         }
     3359        });
    33583360        break;
    33593361    }
  • trunk/Source/JavaScriptCore/dfg/DFGAdjacencyList.h

    r218794 r228411  
    6262        setFirstChild(firstChild);
    6363        setNumChildren(numChildren);
     64        // We need to make sure this is the empty value so equivalent adjacency
     65        // lists produce identical hashes.
     66        m_words[2] = Edge();
    6467    }
    6568   
  • trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp

    r228035 r228411  
    315315                   
    316316                case GetByVal:
    317                     escapeBasedOnArrayMode(node->arrayMode(), node->child1(), node);
    318                     escape(node->child2(), node);
    319                     escape(node->child3(), node);
     317                    escapeBasedOnArrayMode(node->arrayMode(), m_graph.varArgChild(node, 0), node);
     318                    escape(m_graph.varArgChild(node, 1), node);
     319                    escape(m_graph.varArgChild(node, 2), node);
     320                    escape(m_graph.varArgChild(node, 3), node);
    320321                    break;
    321322
     
    323324                    // FIXME: It would not be hard to support NewArrayWithSpread here if it is only over Spread(CreateRest) nodes.
    324325                    escape(node->child2(), node);
     326                    break;
     327
     328                case GetArrayMask:
    325329                    break;
    326330               
     
    372376
    373377                case Check:
     378                case CheckVarargs:
    374379                    m_graph.doToChildren(
    375380                        node,
     
    720725                        break;
    721726                   
    722                     // Meh, this is kind of hackish - we use an Identity so that we can reuse the
    723                     // getArrayLength() helper.
    724727                    node->convertToIdentityOn(getArrayLength(candidate));
     728                    break;
     729                }
     730
     731                case GetArrayMask: {
     732                    Node* candidate = node->child1().node();
     733                    if (!isEliminatedAllocation(candidate))
     734                        break;
     735                   
     736                    // NOTE: This is valid because the only user of this node at the moment is GetByVal.
     737                    // If the candidate is eliminated, it must also be eliminated for all GetByVal users.
     738                    // Therefore, we'll transform those GetByVal nodes to no longer use us. If we introduce
     739                    // other users of this node, we'll need to change this code. That would be easy: just
     740                    // introduce a ComputeArrayMask node, and transform this into ComputeArrayMask(getArrayLength(candidate)).
     741                    node->convertToConstant(m_graph.freeze(jsNumber(0)));
    725742                    break;
    726743                }
     
    734751                    // https://bugs.webkit.org/show_bug.cgi?id=143076
    735752                   
    736                     Node* candidate = node->child1().node();
     753                    Node* candidate = m_graph.varArgChild(node, 0).node();
    737754                    if (!isEliminatedAllocation(candidate))
    738755                        break;
     
    743760                   
    744761                    Node* result = nullptr;
    745                     if (node->child2()->isInt32Constant()) {
    746                         unsigned index = node->child2()->asUInt32();
     762                    if (m_graph.varArgChild(node, 1)->isInt32Constant()) {
     763                        unsigned index = m_graph.varArgChild(node, 1)->asUInt32();
    747764                        InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
    748765                        index += numberOfArgumentsToSkip;
     
    765782                                insertionSet.insertNode(
    766783                                    nodeIndex, SpecNone, CheckInBounds, node->origin,
    767                                     node->child2(), Edge(getArrayLength(candidate), Int32Use));
     784                                    m_graph.varArgChild(node, 1), Edge(getArrayLength(candidate), Int32Use));
    768785                            }
    769786                           
     
    781798                        result = insertionSet.insertNode(
    782799                            nodeIndex, node->prediction(), op, node->origin, OpInfo(numberOfArgumentsToSkip),
    783                             node->child1(), node->child2());
     800                            m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1));
    784801                    }
    785802
     
    945962                                }
    946963                               
    947                                 node->remove();
     964                                node->remove(m_graph);
    948965                                node->origin.exitOK = canExit;
    949966                                break;
     
    10101027                                }
    10111028                               
    1012                                 node->remove();
     1029                                node->remove(m_graph);
    10131030                                node->origin.exitOK = canExit;
    10141031                                break;
     
    11871204                    if (!isEliminatedAllocation(node->child1().node()))
    11881205                        break;
    1189                     node->remove();
     1206                    node->remove(m_graph);
    11901207                    break;
    11911208                }
     
    11961213                        break;
    11971214                    node->child1() = Edge(); // Remove the cell check since we've proven it's not needed and FTL lowering might botch this.
    1198                     node->remove();
     1215                    node->remove(m_graph);
    11991216                    break;
    12001217                   
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r224276 r228411  
    205205        case MovHint:
    206206        case Check:
     207        case CheckVarargs:
    207208            break;
    208209           
     
    352353           
    353354        case GetByVal: {
    354             node->child1()->mergeFlags(NodeBytecodeUsesAsValue);
    355             node->child2()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
     355            m_graph.varArgChild(node, 0)->mergeFlags(NodeBytecodeUsesAsValue);
     356            m_graph.varArgChild(node, 1)->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
    356357            break;
    357358        }
  • trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp

    r224689 r228411  
    7373}
    7474
    75 void BasicBlock::replaceTerminal(Node* node)
     75void BasicBlock::replaceTerminal(Graph& graph, Node* node)
    7676{
    7777    NodeAndIndex result = findTerminal();
     
    8080    else {
    8181        m_nodes.insert(result.index + 1, node);
    82         result.node->remove();
     82        result.node->remove(graph);
    8383    }
    8484   
  • trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h

    r224689 r228411  
    8888            // The bitter end can contain Phantoms and the like. There will probably only be one or two nodes after the terminal. They are all no-ops and will not have any checked children.
    8989            case Check: // This is here because it's our universal no-op.
     90            case CheckVarargs:
    9091            case Phantom:
    9192            case PhantomLocal:
     
    117118    }
    118119   
    119     void replaceTerminal(Node*);
     120    void replaceTerminal(Graph&, Node*);
    120121   
    121122    size_t numNodes() const { return phis.size() + size(); }
  • trunk/Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h

    r206525 r228411  
    5353{
    5454    Node* result = graph.addNode(type, params...);
    55     replaceTerminal(result);
     55    replaceTerminal(graph, result);
    5656    return result;
    5757}
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r228031 r228411  
    49804980            else {
    49814981                ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Read);
    4982                 Node* getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property);
     4982                addVarArgChild(base);
     4983                addVarArgChild(property);
     4984                addVarArgChild(0); // Leave room for property storage.
     4985                if (isFTL(m_graph.m_plan.mode))
     4986                    addVarArgChild(0); // Leave room for the array mask.
     4987                Node* getByVal = addToGraph(Node::VarArg, GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction));
    49834988                m_exitOK = false; // GetByVal must be treated as if it clobbers exit state, since FixupPhase may make it generic.
    49844989                set(VirtualRegister(currentInstruction[1].u.operand), getByVal);
  • trunk/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp

    r217287 r228411  
    340340        ASSERT(terminal->isTerminal());
    341341        NodeOrigin boundaryNodeOrigin = terminal->origin;
    342         terminal->remove();
     342        terminal->remove(m_graph);
    343343        ASSERT(terminal->refCount() == 1);
    344344       
  • trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp

    r221637 r228411  
    188188            if (otherNode->op() == GetLocal) {
    189189                // Replace all references to this GetLocal with otherNode.
    190                 node->replaceWith(otherNode);
     190                node->replaceWith(m_graph, otherNode);
    191191                return;
    192192            }
    193193           
    194194            ASSERT(otherNode->op() == SetLocal);
    195             node->replaceWith(otherNode->child1().node());
     195            node->replaceWith(m_graph, otherNode->child1().node());
    196196            return;
    197197        }
     
    241241                // keep the last MovHinted value of that local alive.
    242242               
    243                 node->remove();
     243                node->remove(m_graph);
    244244                return;
    245245            }
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r222115 r228411  
    450450           
    451451                if (m_node->op() == Identity || m_node->op() == IdentityWithProfile) {
    452                     m_node->replaceWith(m_node->child1().node());
     452                    m_node->replaceWith(m_graph, m_node->child1().node());
    453453                    m_changed = true;
    454454                } else {
     
    533533                return;
    534534
    535             m_node->replaceWith(match);
     535            m_node->replaceWith(m_graph, match);
    536536            m_changed = true;
    537537        }
     
    565565                match.ensureIsNode(m_insertionSet, m_block, 0)->owner = m_block;
    566566                ASSERT(match.isNode());
    567                 m_node->replaceWith(match.asNode());
     567                m_node->replaceWith(m_graph, match.asNode());
    568568                m_changed = true;
    569569            }
     
    653653               
    654654                if (m_node->op() == Identity || m_node->op() == IdentityWithProfile) {
    655                     m_node->replaceWith(m_node->child1().node());
     655                    m_node->replaceWith(m_graph, m_node->child1().node());
    656656                    m_changed = true;
    657657                } else
     
    694694            Node* candidate = result.iterator->value[i];
    695695            if (m_graph.m_ssaDominators->dominates(candidate->owner, m_block)) {
    696                 m_node->replaceWith(candidate);
     696                m_node->replaceWith(m_graph, candidate);
    697697                m_changed = true;
    698698                return;
     
    861861                        if (m_graph.m_ssaDominators->dominates(candidate->owner, m_block)) {
    862862                            ASSERT(candidate);
    863                             match->replaceWith(candidate);
     863                            match->replaceWith(m_graph, candidate);
    864864                            match.setNode(candidate);
    865865                            replaced = true;
     
    872872            }
    873873            ASSERT(match.asNode());
    874             m_node->replaceWith(match.asNode());
     874            m_node->replaceWith(m_graph, match.asNode());
    875875            m_changed = true;
    876876        }
  • trunk/Source/JavaScriptCore/dfg/DFGCleanUpPhase.cpp

    r203808 r228411  
    6565                        kill = true;
    6666                    break;
     67                case CheckVarargs:
     68                    kill = true;
     69                    m_graph.doToChildren(node, [&] (Edge edge) {
     70                        kill &= !edge;
     71                    });
     72                    break;
    6773                default:
    6874                    break;
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r227742 r228411  
    141141    case Phantom:
    142142    case Check:
     143    case CheckVarargs:
    143144    case ExtractOSREntryLocal:
    144145    case ExtractCatchLocal:
     
    794795            if (mode.isInBounds()) {
    795796                read(DirectArgumentsProperties);
    796                 def(HeapLocation(indexedPropertyLoc, DirectArgumentsProperties, node->child1(), node->child2()), LazyNode(node));
     797                def(HeapLocation(indexedPropertyLoc, DirectArgumentsProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    797798                return;
    798799            }
     
    803804        case Array::ScopedArguments:
    804805            read(ScopeProperties);
    805             def(HeapLocation(indexedPropertyLoc, ScopeProperties, node->child1(), node->child2()), LazyNode(node));
     806            def(HeapLocation(indexedPropertyLoc, ScopeProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    806807            return;
    807808           
     
    810811                read(Butterfly_publicLength);
    811812                read(IndexedInt32Properties);
    812                 def(HeapLocation(indexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), LazyNode(node));
     813                def(HeapLocation(indexedPropertyLoc, IndexedInt32Properties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    813814                return;
    814815            }
     
    821822                read(Butterfly_publicLength);
    822823                read(IndexedDoubleProperties);
    823                 def(HeapLocation(indexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), LazyNode(node));
     824                def(HeapLocation(indexedPropertyLoc, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    824825                return;
    825826            }
     
    832833                read(Butterfly_publicLength);
    833834                read(IndexedContiguousProperties);
    834                 def(HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), LazyNode(node));
     835                def(HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    835836                return;
    836837            }
     
    865866            read(TypedArrayProperties);
    866867            read(MiscFields);
    867             def(HeapLocation(indexedPropertyLoc, TypedArrayProperties, node->child1(), node->child2()), LazyNode(node));
     868            def(HeapLocation(indexedPropertyLoc, TypedArrayProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
    868869            return;
    869870        // We should not get an AnyTypedArray in a GetByVal as AnyTypedArray is only created from intrinsics, which
     
    12031204    }
    12041205       
     1206    case GetArrayMask:
     1207        read(JSObject_butterflyMask);
     1208        def(HeapLocation(ArrayMaskLoc, JSObject_butterflyMask, node->child1()), LazyNode(node));
     1209        return;
     1210
    12051211    case GetArrayLength: {
    12061212        ArrayMode mode = node->arrayMode();
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r227136 r228411  
    185185                if (value.m_structure.isSubsetOf(set)) {
    186186                    m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
    187                     node->remove();
     187                    node->remove(m_graph);
    188188                    eliminated = true;
    189189                    break;
     
    197197                    if (constant.isCell() && constant.asCell()->inherits(m_graph.m_vm, node->classInfo())) {
    198198                        m_interpreter.execute(indexInBlock);
    199                         node->remove();
     199                        node->remove(m_graph);
    200200                        eliminated = true;
    201201                        break;
     
    207207                if (value.m_structure.isSubClassOf(node->classInfo())) {
    208208                    m_interpreter.execute(indexInBlock);
    209                     node->remove();
     209                    node->remove(m_graph);
    210210                    eliminated = true;
    211211                    break;
     
    245245                        if (set.contains(m_graph.registerStructure(structure))) {
    246246                            m_interpreter.execute(indexInBlock);
    247                             node->remove();
     247                            node->remove(m_graph);
    248248                            eliminated = true;
    249249                            break;
     
    265265                    if (allGood) {
    266266                        m_interpreter.execute(indexInBlock);
    267                         node->remove();
     267                        node->remove(m_graph);
    268268                        eliminated = true;
    269269                        break;
     
    277277                if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
    278278                    break;
    279                 node->remove();
     279                node->remove(m_graph);
    280280                eliminated = true;
    281281                break;
     
    286286                    break;
    287287               
    288                 node->remove();
     288                node->remove(m_graph);
    289289                eliminated = true;
    290290                break;
     
    294294                if (m_state.forNode(node->child1()).value() != node->cellOperand()->value())
    295295                    break;
    296                 node->remove();
     296                node->remove(m_graph);
    297297                eliminated = true;
    298298                break;
     
    303303                if (m_state.forNode(node->child1()).m_type & SpecEmpty)
    304304                    break;
    305                 node->remove();
     305                node->remove(m_graph);
    306306                eliminated = true;
    307307                break;
     
    327327
    328328                if (constantUid == uid) {
    329                     node->remove();
     329                    node->remove(m_graph);
    330330                    eliminated = true;
    331331                }
     
    338338                if (left && right && left.isInt32() && right.isInt32()
    339339                    && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
    340                     node->remove();
     340                    node->remove(m_graph);
    341341                    eliminated = true;
    342342                    break;
     
    708708                    }
    709709                }
     710                break;
     711            }
     712
     713            case CheckVarargs: {
     714                alreadyHandled = true;
     715                m_interpreter.execute(indexInBlock);
     716                unsigned targetIndex = 0;
     717                for (unsigned i = 0; i < node->numChildren(); ++i) {
     718                    Edge& edge = m_graph.varArgChild(node, i);
     719                    if (!edge)
     720                        continue;
     721                    if (edge.isProved() || edge.willNotHaveCheck()) {
     722                        edge = Edge();
     723                        changed = true;
     724                        continue;
     725                    }
     726                    Edge& dst = m_graph.varArgChild(node, targetIndex++);
     727                    std::swap(dst, edge);
     728                }
     729                node->children.setNumChildren(targetIndex);
    710730                break;
    711731            }
     
    9991019            case DoubleConstant:
    10001020            case Int52Constant:
    1001                 node->remove();
     1021                node->remove(m_graph);
    10021022                break;
    10031023            default:
  • trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp

    r221637 r228411  
    7272                        continue;
    7373                    break;
     74                case CheckVarargs: {
     75                    bool isEmpty = true;
     76                    m_graph.doToChildren(node, [&] (Edge edge) {
     77                        isEmpty &= !edge;
     78                    });
     79                    if (isEmpty)
     80                        continue;
     81                    break;
     82                }
    7483                default:
    7584                    break;
     
    127136            }
    128137           
    129             node->remove();
     138            node->remove(m_graph);
    130139            node->setRefCount(1);
    131140        }
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r228018 r228411  
    230230    case ConstantStoragePointer:
    231231    case Check:
     232    case CheckVarargs:
    232233    case CheckTypeInfoFlags:
    233234    case MultiGetByOffset:
     
    241242    case GetIndexedPropertyStorage:
    242243    case GetArrayLength:
     244    case GetArrayMask:
    243245    case GetVectorLength:
    244246    case ArrayPush:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r228035 r228411  
    711711                node->arrayMode().refine(
    712712                    m_graph, node,
    713                     node->child1()->prediction(),
    714                     node->child2()->prediction(),
     713                    m_graph.varArgChild(node, 0)->prediction(),
     714                    m_graph.varArgChild(node, 1)->prediction(),
    715715                    SpecNone));
    716716           
    717             blessArrayOperation(node->child1(), node->child2(), node->child3());
     717            blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
    718718           
    719719            ArrayMode arrayMode = node->arrayMode();
     
    794794                break;
    795795            case Array::Generic:
    796                 if (node->child1()->shouldSpeculateObject()) {
    797                     if (node->child2()->shouldSpeculateString()) {
    798                         fixEdge<ObjectUse>(node->child1());
    799                         fixEdge<StringUse>(node->child2());
     796                if (m_graph.varArgChild(node, 0)->shouldSpeculateObject()) {
     797                    if (m_graph.varArgChild(node, 1)->shouldSpeculateString()) {
     798                        fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
     799                        fixEdge<StringUse>(m_graph.varArgChild(node, 1));
    800800                        break;
    801801                    }
    802802
    803                     if (node->child2()->shouldSpeculateSymbol()) {
    804                         fixEdge<ObjectUse>(node->child1());
    805                         fixEdge<SymbolUse>(node->child2());
     803                    if (m_graph.varArgChild(node, 1)->shouldSpeculateSymbol()) {
     804                        fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
     805                        fixEdge<SymbolUse>(m_graph.varArgChild(node, 1));
    806806                        break;
    807807                    }
    808808                }
    809809#if USE(JSVALUE32_64)
    810                 fixEdge<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
     810                fixEdge<CellUse>(m_graph.varArgChild(node, 0)); // Speculating cell due to register pressure on 32-bit.
    811811#endif
    812812                break;
     
    814814                break;
    815815            default:
    816                 fixEdge<KnownCellUse>(node->child1());
    817                 fixEdge<Int32Use>(node->child2());
     816                fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
     817                fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
    818818                break;
    819819            }
     
    15681568        }
    15691569
     1570        case CheckVarargs:
    15701571        case Check: {
    15711572            m_graph.doToChildren(
     
    15871588        case Phantom:
    15881589            // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
    1589             node->remove();
     1590            node->remove(m_graph);
    15901591            break;
    15911592
     
    17661767                if (node->child1()->shouldSpeculateInt32()) {
    17671768                    fixEdge<Int32Use>(node->child1());
    1768                     node->remove();
     1769                    node->remove(m_graph);
    17691770                    break;
    17701771                }
     
    17721773                if (enableInt52()) {
    17731774                    fixEdge<AnyIntUse>(node->child1());
    1774                     node->remove();
     1775                    node->remove(m_graph);
    17751776                    break;
    17761777                }
     
    17811782            if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
    17821783                fixEdge<NumberUse>(node->child1());
    1783                 node->remove();
     1784                node->remove(m_graph);
    17841785            } else if (typeSet->doesTypeConformTo(TypeString)) {
    17851786                fixEdge<StringUse>(node->child1());
    1786                 node->remove();
     1787                node->remove(m_graph);
    17871788            } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
    17881789                fixEdge<BooleanUse>(node->child1());
    1789                 node->remove();
     1790                node->remove(m_graph);
    17901791            } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
    17911792                fixEdge<OtherUse>(node->child1());
    1792                 node->remove();
     1793                node->remove(m_graph);
    17931794            } else if (typeSet->doesTypeConformTo(TypeObject)) {
    17941795                StructureSet set;
     
    21832184        case ExtractValueFromWeakMapGet:
    21842185        case CPUIntrinsic:
     2186        case GetArrayMask:
    21852187            break;
    21862188#else
     
    34643466            case MovHint:
    34653467            case Check:
     3468            case CheckVarargs:
    34663469                m_graph.doToChildren(
    34673470                    node,
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r225307 r228411  
    8989        return;
    9090
     91    case ArrayMaskLoc:
     92        out.print("ArrayMaskLoc");
     93        return;
     94
    9195    case VectorLengthLoc:
    9296        out.print("VectorLengthLoc");
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r225307 r228411  
    3838   
    3939    ArrayLengthLoc,
     40    ArrayMaskLoc,
    4041    VectorLengthLoc,
    4142    ButterflyLoc,
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp

    r222007 r228411  
    285285               
    286286            case ArrayBounds:
    287                 node->remove();
     287                node->remove(m_graph);
    288288                m_changed = true;
    289289                break;
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp

    r223318 r228411  
    13311331                    if (nonNegative && lessThanLength) {
    13321332                        executeNode(block->at(nodeIndex));
    1333                         node->remove();
     1333                        node->remove(m_graph);
    13341334                        changed = true;
    13351335                    }
     
    13411341                        break;
    13421342
    1343                     auto iter = m_relationships.find(node->child2().node());
     1343                    auto iter = m_relationships.find(m_graph.varArgChild(node, 1).node());
    13441344                    if (iter == m_relationships.end())
    13451345                        break;
  • trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp

    r228035 r228411  
    344344        }
    345345
    346         // It just so happens that all of the nodes we currently know how to hoist
    347         // don't have var-arg children. That may change and then we can fix this
    348         // code. But for now we just assert that's the case.
    349         DFG_ASSERT(m_graph, node, !(node->flags() & NodeHasVarArgs), node->op(), node->flags());
    350        
    351         nodeRef = m_graph.addNode(Check, originalOrigin, node->children);
     346        nodeRef = m_graph.addNode((node->flags() & NodeHasVarArgs) ? CheckVarargs : Check, originalOrigin, node->children);
    352347       
    353348        return true;
  • trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp

    r227410 r228411  
    5959    case Phantom:
    6060    case Check:
     61    case CheckVarargs:
    6162    case Identity:
    6263    case IdentityWithProfile:
  • trunk/Source/JavaScriptCore/dfg/DFGNode.cpp

    r227107 r228411  
    8282}
    8383
    84 void Node::remove()
    85 {
    86     ASSERT(!(flags() & NodeHasVarArgs));
    87    
    88     children = children.justChecks();
    89    
    90     setOpAndDefaultFlags(Check);
     84void Node::remove(Graph& graph)
     85{
     86    if (flags() & NodeHasVarArgs) {
     87        unsigned targetIndex = 0;
     88        for (unsigned i = 0; i < numChildren(); ++i) {
     89            Edge& edge = graph.varArgChild(this, i);
     90            if (!edge)
     91                continue;
     92            if (edge.willHaveCheck()) {
     93                Edge& dst = graph.varArgChild(this, targetIndex++);
     94                std::swap(dst, edge);
     95                continue;
     96            }
     97            edge = Edge();
     98        }
     99        setOpAndDefaultFlags(CheckVarargs);
     100        children.setNumChildren(targetIndex);
     101    } else {
     102        children = children.justChecks();
     103        setOpAndDefaultFlags(Check);
     104    }
    91105}
    92106
     
    103117{
    104118    children.reset();
     119    clearFlags(NodeHasVarArgs);
    105120    child1() = child->defaultEdge();
    106121    NodeFlags output = canonicalResultRepresentation(this->result());
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r227462 r228411  
    431431    }
    432432
    433     void remove();
     433    void remove(Graph&);
    434434
    435435    void convertToCheckStructure(RegisteredStructureSet* set)
     
    452452    }
    453453   
    454     void replaceWith(Node* other)
    455     {
    456         remove();
     454    void replaceWith(Graph& graph, Node* other)
     455    {
     456        remove(graph);
    457457        setReplacement(other);
    458458    }
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r227723 r228411  
    8080    macro(Phantom, NodeMustGenerate) \
    8181    macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
     82    macro(CheckVarargs, NodeMustGenerate | NodeHasVarArgs) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
    8283    macro(Upsilon, 0) \
    8384    macro(Phi, 0) \
     
    172173    /* this must be the directly subsequent property put. Note that PutByVal */\
    173174    /* opcodes use VarArgs beause they may have up to 4 children. */\
    174     macro(GetByVal, NodeResultJS | NodeMustGenerate) \
     175    macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    175176    macro(GetByValWithThis, NodeResultJS | NodeMustGenerate) \
    176177    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
     
    220221    macro(MultiPutByOffset, NodeMustGenerate) \
    221222    macro(GetArrayLength, NodeResultInt32) \
     223    macro(GetArrayMask, NodeResultInt32) \
    222224    macro(GetVectorLength, NodeResultInt32) \
    223225    macro(GetTypedArrayByteOffset, NodeResultInt32) \
  • trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp

    r227970 r228411  
    962962                if (Node* value = heapResolve(location)) {
    963963                    if (allocation->structures().isSubsetOf(validStructures))
    964                         node->replaceWith(value);
     964                        node->replaceWith(m_graph, value);
    965965                    else {
    966966                        Node* structure = heapResolve(PromotedHeapLocation(allocation->identifier(), StructurePLoc));
     
    10721072
    10731073        case Check:
     1074        case CheckVarargs:
    10741075            m_graph.doToChildren(
    10751076                node,
     
    11041105            if (Node* value = heapResolve(PromotedHeapLocation(target->identifier(), exactRead))) {
    11051106                ASSERT(!value->replacement());
    1106                 node->replaceWith(value);
     1107                node->replaceWith(m_graph, value);
    11071108            }
    11081109            Node* identifier = target->get(exactRead);
     
    19291930
    19301931                    default:
    1931                         node->remove();
     1932                        node->remove(m_graph);
    19321933                        break;
    19331934                    }
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r227723 r228411  
    10661066        }
    10671067
     1068        case GetArrayMask:
    10681069        case PutByValAlias:
    10691070        case DoubleAsInt32:
     
    11751176        case Phantom:
    11761177        case Check:
     1178        case CheckVarargs:
    11771179        case PutGlobalVariable:
    11781180        case CheckTraps:
  • trunk/Source/JavaScriptCore/dfg/DFGPureValue.cpp

    r172129 r228411  
    3838    out.print("(");
    3939    CommaPrinter comma;
    40     for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
    41         if (children().child(i))
    42             out.print(comma, children().child(i));
     40    if (defaultFlags(m_op) & NodeHasVarArgs)
     41        out.print(comma, " VarArgs: firstChild=", m_children.firstChild(), " numChildren=", m_children.numChildren());
     42    else {
     43        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
     44            if (children().child(i))
     45                out.print(comma, children().child(i));
     46        }
    4347    }
    4448    if (m_info)
  • trunk/Source/JavaScriptCore/dfg/DFGPureValue.h

    r206525 r228411  
    4242    PureValue(NodeType op, const AdjacencyList& children, uintptr_t info)
    4343        : m_op(op)
    44         , m_children(children.sanitized())
     44        , m_children(defaultFlags(op) & NodeHasVarArgs ? children : children.sanitized())
    4545        , m_info(info)
    4646    {
    47         ASSERT(!(defaultFlags(op) & NodeHasVarArgs));
    4847    }
    4948   
  • trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp

    r228035 r228411  
    573573                    continue;
    574574               
    575                 node->remove();
     575                node->remove(m_graph);
    576576            }
    577577        }
  • trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp

    r225893 r228411  
    350350                                variable->local(), variable->flushFormat()));
    351351                    } else
    352                         node->remove();
     352                        node->remove(m_graph);
    353353                   
    354354                    if (verbose)
     
    368368                    node->children.reset();
    369369                   
    370                     node->remove();
     370                    node->remove(m_graph);
    371371                    if (verbose)
    372372                        dataLog("Replacing node ", node, " with ", valueForOperand.operand(variable->local()), "\n");
     
    377377                case Flush: {
    378378                    node->children.reset();
    379                     node->remove();
     379                    node->remove(m_graph);
    380380                    break;
    381381                }
     
    385385                    VariableAccessData* variable = node->variableAccessData();
    386386                    node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
    387                     node->remove();
     387                    node->remove(m_graph);
    388388                    break;
    389389                }
    390390                   
    391391                case SetArgument: {
    392                     node->remove();
     392                    node->remove(m_graph);
    393393                    break;
    394394                }
  • trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp

    r217202 r228411  
    6969    {
    7070        switch (m_node->op()) {
    71         case GetByVal:
    7271        case AtomicsAdd:
    7372        case AtomicsAnd:
     
    8281            lowerBoundsCheck(m_graph.child(m_node, 0), m_graph.child(m_node, 1), m_graph.child(m_node, 2));
    8382            break;
     83
     84        case GetByVal: {
     85            lowerBoundsCheck(m_graph.varArgChild(m_node, 0), m_graph.varArgChild(m_node, 1), m_graph.varArgChild(m_node, 2));
     86            auto insertGetMask = [&] () {
     87                Node* mask = m_insertionSet.insertNode(
     88                    m_nodeIndex, SpecInt32Only, GetArrayMask,
     89                    m_node->origin, Edge(m_graph.varArgChild(m_node, 0).node(), ObjectUse));
     90                m_graph.varArgChild(m_node, 3) = Edge(mask, Int32Use);
     91            };
     92            auto arrayMode = m_node->arrayMode();
     93            switch (arrayMode.type()) {
     94            case Array::Int32:
     95            case Array::Contiguous:
     96            case Array::Double:
     97            case Array::ArrayStorage:
     98            case Array::SlowPutArrayStorage:
     99                // FIXME: Also support this in the DFG:
     100                // https://bugs.webkit.org/show_bug.cgi?id=182711
     101                insertGetMask();
     102                break;
     103            default:
     104                // FIXME: Pass in GetArrayLength on GetByVal's over Scoped/Direct Arguments.
     105                // https://bugs.webkit.org/show_bug.cgi?id=182714
     106                if (arrayMode.isSomeTypedArrayView())
     107                    insertGetMask();
     108                break;
     109            }
     110            break;
     111        }
    84112           
    85113        case PutByVal:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r227723 r228411  
    373373    case ConstantStoragePointer:
    374374    case Check:
     375    case CheckVarargs:
    375376    case MultiPutByOffset:
    376377    case ValueRep:
     
    477478    case StringCharAt:
    478479    case StringCharCodeAt:
    479         return node->arrayMode().alreadyChecked(graph, node, state.forNode(node->child1()));
     480        return node->arrayMode().alreadyChecked(graph, node, state.forNode(graph.child(node, 0)));
     481
     482    case GetArrayMask:
     483        return state.forNode(node->child1()).isType(SpecObject);
    480484
    481485    case ArrayPush:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r228035 r228411  
    7272    : m_compileOkay(true)
    7373    , m_jit(jit)
     74    , m_graph(m_jit.graph())
    7475    , m_currentNode(0)
    7576    , m_lastGeneratedNode(LastNodeType)
     
    21452146void SpeculativeJIT::compileGetByValOnString(Node* node)
    21462147{
    2147     SpeculateCellOperand base(this, node->child1());
    2148     SpeculateStrictInt32Operand property(this, node->child2());
    2149     StorageOperand storage(this, node->child3());
     2148    SpeculateCellOperand base(this, m_graph.child(node, 0));
     2149    SpeculateStrictInt32Operand property(this, m_graph.child(node, 1));
     2150    StorageOperand storage(this, m_graph.child(node, 2));
    21502151    GPRReg baseReg = base.gpr();
    21512152    GPRReg propertyReg = property.gpr();
     
    21642165#endif
    21652166
    2166     ASSERT(ArrayMode(Array::String).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     2167    ASSERT(ArrayMode(Array::String).alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.child(node, 0))));
    21672168
    21682169    // unsigned comparison so we can filter out negative indices and indices that are too large
     
    29132914    ASSERT(isInt(type));
    29142915   
    2915     SpeculateCellOperand base(this, node->child1());
    2916     SpeculateStrictInt32Operand property(this, node->child2());
    2917     StorageOperand storage(this, node->child3());
     2916    SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2917    SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2918    StorageOperand storage(this, m_graph.varArgChild(node, 2));
    29182919
    29192920    GPRReg baseReg = base.gpr();
     
    29242925    GPRReg resultReg = result.gpr();
    29252926
    2926     ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     2927    ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.varArgChild(node, 0))));
    29272928
    29282929    emitTypedArrayBoundsCheck(node, baseReg, propertyReg);
     
    31463147    ASSERT(isFloat(type));
    31473148   
    3148     SpeculateCellOperand base(this, node->child1());
    3149     SpeculateStrictInt32Operand property(this, node->child2());
    3150     StorageOperand storage(this, node->child3());
     3149    SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     3150    SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     3151    StorageOperand storage(this, m_graph.varArgChild(node, 2));
    31513152
    31523153    GPRReg baseReg = base.gpr();
     
    31543155    GPRReg storageReg = storage.gpr();
    31553156
    3156     ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     3157    ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.varArgChild(node, 0))));
    31573158
    31583159    FPRTemporary result(this);
     
    32183219void SpeculativeJIT::compileGetByValForObjectWithString(Node* node)
    32193220{
    3220     SpeculateCellOperand arg1(this, node->child1());
    3221     SpeculateCellOperand arg2(this, node->child2());
     3221    SpeculateCellOperand arg1(this, m_graph.varArgChild(node, 0));
     3222    SpeculateCellOperand arg2(this, m_graph.varArgChild(node, 1));
    32223223
    32233224    GPRReg arg1GPR = arg1.gpr();
    32243225    GPRReg arg2GPR = arg2.gpr();
    32253226
    3226     speculateObject(node->child1(), arg1GPR);
    3227     speculateString(node->child2(), arg2GPR);
     3227    speculateObject(m_graph.varArgChild(node, 0), arg1GPR);
     3228    speculateString(m_graph.varArgChild(node, 1), arg2GPR);
    32283229
    32293230    flushRegisters();
     
    32383239void SpeculativeJIT::compileGetByValForObjectWithSymbol(Node* node)
    32393240{
    3240     SpeculateCellOperand arg1(this, node->child1());
    3241     SpeculateCellOperand arg2(this, node->child2());
     3241    SpeculateCellOperand arg1(this, m_graph.varArgChild(node, 0));
     3242    SpeculateCellOperand arg2(this, m_graph.varArgChild(node, 1));
    32423243
    32433244    GPRReg arg1GPR = arg1.gpr();
    32443245    GPRReg arg2GPR = arg2.gpr();
    32453246
    3246     speculateObject(node->child1(), arg1GPR);
    3247     speculateSymbol(node->child2(), arg2GPR);
     3247    speculateObject(m_graph.varArgChild(node, 0), arg1GPR);
     3248    speculateSymbol(m_graph.varArgChild(node, 1), arg2GPR);
    32483249
    32493250    flushRegisters();
     
    64326433void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node)
    64336434{
    6434     SpeculateCellOperand base(this, node->child1());
    6435     SpeculateStrictInt32Operand property(this, node->child2());
     6435    SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     6436    SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
    64366437    GPRTemporary result(this);
    64376438#if USE(JSVALUE32_64)
     
    64546455        return;
    64556456   
    6456     ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     6457    ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.varArgChild(node, 0))));
    64576458   
    64586459    speculationCheck(
     
    64896490void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node)
    64906491{
    6491     SpeculateCellOperand base(this, node->child1());
    6492     SpeculateStrictInt32Operand property(this, node->child2());
     6492    SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     6493    SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
    64936494    GPRTemporary result(this);
    64946495#if USE(JSVALUE32_64)
     
    65136514        return;
    65146515   
    6515     ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     6516    ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.varArgChild(node, 0))));
    65166517   
    65176518    speculationCheck(
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r227723 r228411  
    33523352    // The JIT, while also provides MacroAssembler functionality.
    33533353    JITCompiler& m_jit;
     3354    Graph& m_graph;
    33543355
    33553356    // The current node being generated.
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r227723 r228411  
    25512551            break;
    25522552        case Array::Undecided: {
    2553             SpeculateStrictInt32Operand index(this, node->child2());
     2553            SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 1));
    25542554            GPRTemporary resultTag(this, Reuse, index);
    25552555            GPRTemporary resultPayload(this);
     
    25622562                m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
    25632563
    2564             use(node->child1());
     2564            use(m_graph.varArgChild(node, 0));
    25652565            index.use();
    25662566
     
    25712571        }
    25722572        case Array::Generic: {
    2573             if (node->child1().useKind() == ObjectUse) {
    2574                 if (node->child2().useKind() == StringUse) {
     2573            if (m_graph.varArgChild(node, 0).useKind() == ObjectUse) {
     2574                if (m_graph.varArgChild(node, 1).useKind() == StringUse) {
    25752575                    compileGetByValForObjectWithString(node);
    25762576                    break;
     
    25832583            }
    25842584
    2585             SpeculateCellOperand base(this, node->child1()); // Save a register, speculate cell. We'll probably be right.
    2586             JSValueOperand property(this, node->child2());
     2585            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0)); // Save a register, speculate cell. We'll probably be right.
     2586            JSValueOperand property(this, m_graph.varArgChild(node, 1));
    25872587            GPRReg baseGPR = base.gpr();
    25882588            JSValueRegs propertyRegs = property.jsValueRegs();
     
    26002600        case Array::Contiguous: {
    26012601            if (node->arrayMode().isInBounds()) {
    2602                 SpeculateStrictInt32Operand property(this, node->child2());
    2603                 StorageOperand storage(this, node->child3());
     2602                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2603                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    26042604           
    26052605                GPRReg propertyReg = property.gpr();
     
    26572657            }
    26582658
    2659             SpeculateCellOperand base(this, node->child1());
    2660             SpeculateStrictInt32Operand property(this, node->child2());
    2661             StorageOperand storage(this, node->child3());
     2659            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2660            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2661            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    26622662           
    26632663            GPRReg baseReg = base.gpr();
     
    26912691        case Array::Double: {
    26922692            if (node->arrayMode().isInBounds()) {
    2693                 SpeculateStrictInt32Operand property(this, node->child2());
    2694                 StorageOperand storage(this, node->child3());
     2693                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2694                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    26952695           
    26962696                GPRReg propertyReg = property.gpr();
     
    27102710            }
    27112711
    2712             SpeculateCellOperand base(this, node->child1());
    2713             SpeculateStrictInt32Operand property(this, node->child2());
    2714             StorageOperand storage(this, node->child3());
     2712            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2713            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2714            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    27152715           
    27162716            GPRReg baseReg = base.gpr();
     
    27472747        case Array::SlowPutArrayStorage: {
    27482748            if (node->arrayMode().isInBounds()) {
    2749                 SpeculateStrictInt32Operand property(this, node->child2());
    2750                 StorageOperand storage(this, node->child3());
     2749                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2750                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    27512751                GPRReg propertyReg = property.gpr();
    27522752                GPRReg storageReg = storage.gpr();
     
    27682768            }
    27692769
    2770             SpeculateCellOperand base(this, node->child1());
    2771             SpeculateStrictInt32Operand property(this, node->child2());
    2772             StorageOperand storage(this, node->child3());
     2770            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2771            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2772            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    27732773            GPRReg propertyReg = property.gpr();
    27742774            GPRReg storageReg = storage.gpr();
     
    50845084    case Phantom:
    50855085    case Check:
     5086    case CheckVarargs:
    50865087        DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
    50875088        noResult(node);
     
    52065207    case CPUIntrinsic:
    52075208    case AssertNotEmpty:
     5209    case GetArrayMask:
    52085210        DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
    52095211        break;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r228035 r228411  
    26892689            break;
    26902690        case Array::Undecided: {
    2691             SpeculateStrictInt32Operand index(this, node->child2());
     2691            SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 1));
    26922692            GPRTemporary result(this, Reuse, index);
    26932693            GPRReg indexGPR = index.gpr();
     
    26972697                m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
    26982698
    2699             use(node->child1());
     2699            use(m_graph.varArgChild(node, 0));
    27002700            index.use();
    27012701
     
    27052705        }
    27062706        case Array::Generic: {
    2707             if (node->child1().useKind() == ObjectUse) {
    2708                 if (node->child2().useKind() == StringUse) {
     2707            if (m_graph.varArgChild(node, 0).useKind() == ObjectUse) {
     2708                if (m_graph.varArgChild(node, 1).useKind() == StringUse) {
    27092709                    compileGetByValForObjectWithString(node);
    27102710                    break;
    27112711                }
    27122712
    2713                 if (node->child2().useKind() == SymbolUse) {
     2713                if (m_graph.varArgChild(node, 1).useKind() == SymbolUse) {
    27142714                    compileGetByValForObjectWithSymbol(node);
    27152715                    break;
    27162716                }
    27172717            }
    2718             JSValueOperand base(this, node->child1());
    2719             JSValueOperand property(this, node->child2());
     2718            JSValueOperand base(this, m_graph.varArgChild(node, 0));
     2719            JSValueOperand property(this, m_graph.varArgChild(node, 1));
    27202720            GPRReg baseGPR = base.gpr();
    27212721            GPRReg propertyGPR = property.gpr();
     
    27322732        case Array::Contiguous: {
    27332733            if (node->arrayMode().isInBounds()) {
    2734                 SpeculateCellOperand base(this, node->child1());
    2735                 SpeculateStrictInt32Operand property(this, node->child2());
    2736                 StorageOperand storage(this, node->child3());
     2734                SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2735                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2736                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    27372737
    27382738                GPRReg baseReg = base.gpr();
     
    27652765            }
    27662766           
    2767             SpeculateCellOperand base(this, node->child1());
    2768             SpeculateStrictInt32Operand property(this, node->child2());
    2769             StorageOperand storage(this, node->child3());
     2767            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2768            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2769            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    27702770           
    27712771            GPRReg baseReg = base.gpr();
     
    27992799        case Array::Double: {
    28002800            if (node->arrayMode().isInBounds()) {
    2801                 SpeculateCellOperand base(this, node->child1());
    2802                 SpeculateStrictInt32Operand property(this, node->child2());
    2803                 StorageOperand storage(this, node->child3());
     2801                SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2802                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2803                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    28042804
    28052805                GPRReg baseReg = base.gpr();
     
    28242824            }
    28252825
    2826             SpeculateCellOperand base(this, node->child1());
    2827             SpeculateStrictInt32Operand property(this, node->child2());
    2828             StorageOperand storage(this, node->child3());
     2826            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2827            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2828            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    28292829           
    28302830            GPRReg baseReg = base.gpr();
     
    28622862        case Array::SlowPutArrayStorage: {
    28632863            if (node->arrayMode().isInBounds()) {
    2864                 SpeculateStrictInt32Operand property(this, node->child2());
    2865                 StorageOperand storage(this, node->child3());
     2864                SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2865                StorageOperand storage(this, m_graph.varArgChild(node, 2));
    28662866           
    28672867                GPRReg propertyReg = property.gpr();
     
    28812881            }
    28822882
    2883             SpeculateCellOperand base(this, node->child1());
    2884             SpeculateStrictInt32Operand property(this, node->child2());
    2885             StorageOperand storage(this, node->child3());
     2883            SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
     2884            SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
     2885            StorageOperand storage(this, m_graph.varArgChild(node, 2));
    28862886           
    28872887            GPRReg baseReg = base.gpr();
     
    52635263    case Phantom:
    52645264    case Check:
     5265    case CheckVarargs:
    52655266        DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
    52665267        noResult(node);
     
    56935694    case IdentityWithProfile:
    56945695    case CPUIntrinsic:
     5696    case GetArrayMask:
    56955697        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
    56965698        break;
  • trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierClusteringPhase.cpp

    r228035 r228411  
    121121            NodeOrigin origin = node->origin;
    122122            m_neededBarriers.append(ChildAndOrigin(node->child1().node(), origin.semantic));
    123             node->remove();
     123            node->remove(m_graph);
    124124           
    125125            if (!m_barrierPoints[nodeIndex])
  • trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp

    r227107 r228411  
    753753
    754754                case Check:
     755                case CheckVarargs:
    755756                    // FIXME: This is probably not correct.
    756757                    break;
  • trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp

    r221954 r228411  
    107107                break;
    108108               
     109            case CheckVarargs:
    109110            case Check: {
    110111                bool sawEscape = false;
     
    265266            switch (node->op()) {
    266267            case Check:
     268            case CheckVarargs:
    267269            case MovHint:
    268270            case PutHint:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r227723 r228411  
    174174    case ConstantStoragePointer:
    175175    case Check:
     176    case CheckVarargs:
    176177    case CountExecution:
    177178    case SuperSamplerBegin:
     
    330331    case InitializeEntrypointArguments:
    331332    case CPUIntrinsic:
     333    case GetArrayMask:
    332334        // These are OK.
    333335        break;
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r228035 r228411  
    571571            break;
    572572        case DFG::Check:
     573        case CheckVarargs:
    573574            compileNoOp();
    574575            break;
     
    746747        case GetArrayLength:
    747748            compileGetArrayLength();
     749            break;
     750        case GetArrayMask:
     751            compileGetArrayMask();
    748752            break;
    749753        case GetVectorLength:
     
    36233627    }
    36243628   
     3629    void compileGetArrayMask()
     3630    {
     3631        setInt32(m_out.load32NonNegative(lowObject(m_node->child1()), m_heaps.JSObject_butterflyMask));
     3632    }
     3633
    36253634    void compileGetArrayLength()
    36263635    {
     
    36943703        case Array::Int32:
    36953704        case Array::Contiguous: {
    3696             LValue index = lowInt32(m_node->child2());
    3697             LValue storage = lowStorage(m_node->child3());
     3705            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
     3706            LValue storage = lowStorage(m_graph.varArgChild(m_node, 2));
    36983707           
    36993708            IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
    37003709                m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
    37013710
    3702             LValue base = lowCell(m_node->child1());
     3711            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3712            LValue mask = lowInt32(m_graph.varArgChild(m_node, 3));
    37033713
    37043714            if (m_node->arrayMode().isInBounds()) {
    3705                 LValue result = m_out.load64(maskedIndex(heap, storage, index, base, m_node->child2()));
     3715                LValue result = m_out.load64(maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    37063716                LValue isHole = m_out.isZero64(result);
    37073717                if (m_node->arrayMode().isSaneChain()) {
     
    37273737            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
    37283738
    3729             LValue fastResultValue = m_out.load64(maskedIndex(heap, storage, index, base, m_node->child2()));
     3739            LValue fastResultValue = m_out.load64(maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    37303740            ValueFromBlock fastResult = m_out.anchor(fastResultValue);
    37313741            m_out.branch(
     
    37433753           
    37443754        case Array::Double: {
    3745             LValue base = lowCell(m_node->child1());
    3746             LValue index = lowInt32(m_node->child2());
    3747             LValue storage = lowStorage(m_node->child3());
     3755            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3756            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
     3757            LValue storage = lowStorage(m_graph.varArgChild(m_node, 2));
     3758            LValue mask = lowInt32(m_graph.varArgChild(m_node, 3));
    37483759           
    37493760            IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
     
    37513762            if (m_node->arrayMode().isInBounds()) {
    37523763                LValue result = m_out.loadDouble(
    3753                     maskedIndex(heap, storage, index, base, m_node->child2()));
     3764                    maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    37543765               
    37553766                if (!m_node->arrayMode().isSaneChain()) {
     
    37743785            LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
    37753786            LValue doubleValue = m_out.loadDouble(
    3776                 maskedIndex(heap, storage, index, base, m_node->child2()));
     3787                maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    37773788            m_out.branch(
    37783789                m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
     
    37943805
    37953806        case Array::Undecided: {
    3796             LValue index = lowInt32(m_node->child2());
     3807            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
    37973808
    37983809            speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
     
    38023813           
    38033814        case Array::DirectArguments: {
    3804             LValue base = lowCell(m_node->child1());
    3805             LValue index = lowInt32(m_node->child2());
     3815            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3816            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
    38063817           
    38073818            speculate(
     
    38453856           
    38463857        case Array::ScopedArguments: {
    3847             LValue base = lowCell(m_node->child1());
    3848             LValue index = lowInt32(m_node->child2());
     3858            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3859            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
    38493860           
    38503861            speculate(
     
    38983909           
    38993910        case Array::Generic: {
    3900             if (m_node->child1().useKind() == ObjectUse) {
    3901                 if (m_node->child2().useKind() == StringUse) {
     3911            if (m_graph.varArgChild(m_node, 0).useKind() == ObjectUse) {
     3912                if (m_graph.varArgChild(m_node, 1).useKind() == StringUse) {
    39023913                    setJSValue(vmCall(
    39033914                        Int64, m_out.operation(operationGetByValObjectString), m_callFrame,
    3904                         lowObject(m_node->child1()), lowString(m_node->child2())));
     3915                        lowObject(m_graph.varArgChild(m_node, 0)), lowString(m_graph.varArgChild(m_node, 1))));
    39053916                    return;
    39063917                }
    39073918
    3908                 if (m_node->child2().useKind() == SymbolUse) {
     3919                if (m_graph.varArgChild(m_node, 1).useKind() == SymbolUse) {
    39093920                    setJSValue(vmCall(
    39103921                        Int64, m_out.operation(operationGetByValObjectSymbol), m_callFrame,
    3911                         lowObject(m_node->child1()), lowSymbol(m_node->child2())));
     3922                        lowObject(m_graph.varArgChild(m_node, 0)), lowSymbol(m_graph.varArgChild(m_node, 1))));
    39123923                    return;
    39133924                }
     
    39153926            setJSValue(vmCall(
    39163927                Int64, m_out.operation(operationGetByVal), m_callFrame,
    3917                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
     3928                lowJSValue(m_graph.varArgChild(m_node, 0)), lowJSValue(m_graph.varArgChild(m_node, 1))));
    39183929            return;
    39193930        }
     
    39213932        case Array::ArrayStorage:
    39223933        case Array::SlowPutArrayStorage: {
    3923             LValue base = lowCell(m_node->child1());
    3924             LValue index = lowInt32(m_node->child2());
    3925             LValue storage = lowStorage(m_node->child3());
     3934            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3935            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
     3936            LValue storage = lowStorage(m_graph.varArgChild(m_node, 2));
     3937            LValue mask = lowInt32(m_graph.varArgChild(m_node, 3));
    39263938
    39273939            IndexedAbstractHeap& heap = m_heaps.ArrayStorage_vector;
    39283940
    39293941            if (m_node->arrayMode().isInBounds()) {
    3930                 LValue result = m_out.load64(maskedIndex(heap, storage, index, base, m_node->child2()));
     3942                LValue result = m_out.load64(maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    39313943                speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
    39323944                setJSValue(result);
     
    39433955
    39443956            LBasicBlock lastNext = m_out.appendTo(inBounds, slowCase);
    3945             LValue result = m_out.load64(maskedIndex(heap, storage, index, base, m_node->child2()));
     3957            LValue result = m_out.load64(maskedIndex(heap, storage, index, mask, m_graph.varArgChild(m_node, 1)));
    39463958            ValueFromBlock fastResult = m_out.anchor(result);
    39473959            m_out.branch(
     
    39653977           
    39663978        default: {
    3967             LValue base = lowCell(m_node->child1());
    3968             LValue index = lowInt32(m_node->child2());
    3969             LValue storage = lowStorage(m_node->child3());
     3979            LValue base = lowCell(m_graph.varArgChild(m_node, 0));
     3980            LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
     3981            LValue storage = lowStorage(m_graph.varArgChild(m_node, 2));
     3982            LValue mask = lowInt32(m_graph.varArgChild(m_node, 3));
    39703983           
    39713984            TypedArrayType type = m_node->arrayMode().typedArrayType();
    39723985           
    39733986            if (isTypedView(type)) {
    3974                 TypedPointer pointer = pointerIntoTypedArray(base, storage, index, type);
     3987                TypedPointer pointer = pointerIntoTypedArray(base, storage, index, type, mask);
    39753988               
    39763989                if (isInt(type)) {
     
    59675980    void compileStringCharAt()
    59685981    {
    5969         LValue base = lowCell(m_node->child1());
    5970         LValue index = lowInt32(m_node->child2());
    5971         LValue storage = lowStorage(m_node->child3());
     5982        LValue base = lowCell(m_graph.child(m_node, 0));
     5983        LValue index = lowInt32(m_graph.child(m_node, 1));
     5984        LValue storage = lowStorage(m_graph.child(m_node, 2));
    59725985           
    59735986        LBasicBlock fastPath = m_out.newBlock();
     
    60036016            m_out.load8ZeroExt32(m_out.baseIndex(
    60046017                m_heaps.characters8, storage, m_out.zeroExtPtr(indexForAccess),
    6005                 provenValue(m_node->child2()))));
     6018                provenValue(m_graph.child(m_node, 1)))));
    60066019        m_out.jump(bitsContinuation);
    60076020           
     
    60116024            m_out.baseIndex(
    60126025                m_heaps.characters16, storage, m_out.zeroExtPtr(indexForAccess),
    6013                 provenValue(m_node->child2())));
     6026                provenValue(m_graph.child(m_node, 1))));
    60146027        ValueFromBlock char16Bit = m_out.anchor(char16BitValue);
    60156028        m_out.branch(
     
    1119511208    }
    1119611209
    11197     TypedPointer maskedIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, LValue baseObject, Edge edge, ptrdiff_t offset = 0)
     11210    TypedPointer maskedIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, LValue mask, Edge edge, ptrdiff_t offset = 0)
    1119811211    {
    1119911212        if (m_indexMaskingMode == IndexMaskingDisabled)
    1120011213            return baseIndex(heap, storage, index, edge, offset);
    1120111214
    11202         LValue mask = m_out.zeroExtPtr(m_out.load32(baseObject, m_heaps.JSObject_butterflyMask));
    1120311215        return m_out.baseIndex(
    11204             heap, storage, m_out.zeroExtPtr(index), provenValue(edge), offset, mask);
     11216            heap, storage, m_out.zeroExtPtr(index), provenValue(edge), offset, m_out.zeroExtPtr(mask));
    1120511217    }
    1120611218
     
    1327913291    }
    1328013292   
    13281     TypedPointer pointerIntoTypedArray(LValue base, LValue storage, LValue index, TypedArrayType type)
    13282     {
    13283         if (m_indexMaskingMode == IndexMaskingEnabled)
    13284             index = m_out.bitAnd(index, m_out.load32(base, m_heaps.JSObject_butterflyMask));
     13293    TypedPointer pointerIntoTypedArray(LValue base, LValue storage, LValue index, TypedArrayType type, LValue mask = nullptr)
     13294    {
     13295        if (m_indexMaskingMode == IndexMaskingEnabled) {
     13296            if (!mask)
     13297                mask = m_out.load32(base, m_heaps.JSObject_butterflyMask);
     13298            index = m_out.bitAnd(index, mask);
     13299        }
    1328513300        LValue offset = m_out.shl(m_out.zeroExtPtr(index), m_out.constIntPtr(logElementSize(type)));
    1328613301
Note: See TracChangeset for help on using the changeset viewer.