Changeset 103604 in webkit


Ignore:
Timestamp:
Dec 22, 2011, 9:47:17 PM (14 years ago)
Author:
[email protected]
Message:

DFG should not speculate array even when predictions say that the base is not an array
https://bugs.webkit.org/show_bug.cgi?id=75160
<rdar://problem/10622646>
<rdar://problem/10622649>

Reviewed by Oliver Hunt.

Added the ability to call slow path when the base is known to not be an array.
Also rationalized the logic for deciding when the index is not an int, and
cleaned up the logic for deciding when to speculate typed array.

Neutral for the most part, with odd speed-ups and slow-downs. The slow-downs can
likely be mitigated by having the notion of a polymorphic array access, where we
try, but don't speculate, to access the array one way before either trying some
other ways or calling slow path.

  • bytecode/PredictedType.h:

(JSC::isActionableMutableArrayPrediction):
(JSC::isActionableArrayPrediction):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGNode.h:

(JSC::DFG::Node::shouldSpeculateInt8Array):
(JSC::DFG::Node::shouldSpeculateInt16Array):
(JSC::DFG::Node::shouldSpeculateInt32Array):
(JSC::DFG::Node::shouldSpeculateUint8Array):
(JSC::DFG::Node::shouldSpeculateUint16Array):
(JSC::DFG::Node::shouldSpeculateUint32Array):
(JSC::DFG::Node::shouldSpeculateFloat32Array):
(JSC::DFG::Node::shouldSpeculateFloat64Array):

  • dfg/DFGPropagator.cpp:

(JSC::DFG::Propagator::byValIsPure):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r103599 r103604  
     12011-12-22  Filip Pizlo  <[email protected]>
     2
     3        DFG should not speculate array even when predictions say that the base is not an array
     4        https://bugs.webkit.org/show_bug.cgi?id=75160
     5        <rdar://problem/10622646>
     6        <rdar://problem/10622649>
     7
     8        Reviewed by Oliver Hunt.
     9       
     10        Added the ability to call slow path when the base is known to not be an array.
     11        Also rationalized the logic for deciding when the index is not an int, and
     12        cleaned up the logic for deciding when to speculate typed array.
     13       
     14        Neutral for the most part, with odd speed-ups and slow-downs. The slow-downs can
     15        likely be mitigated by having the notion of a polymorphic array access, where we
     16        try, but don't speculate, to access the array one way before either trying some
     17        other ways or calling slow path.
     18
     19        * bytecode/PredictedType.h:
     20        (JSC::isActionableMutableArrayPrediction):
     21        (JSC::isActionableArrayPrediction):
     22        * dfg/DFGAbstractState.cpp:
     23        (JSC::DFG::AbstractState::execute):
     24        * dfg/DFGNode.h:
     25        (JSC::DFG::Node::shouldSpeculateInt8Array):
     26        (JSC::DFG::Node::shouldSpeculateInt16Array):
     27        (JSC::DFG::Node::shouldSpeculateInt32Array):
     28        (JSC::DFG::Node::shouldSpeculateUint8Array):
     29        (JSC::DFG::Node::shouldSpeculateUint16Array):
     30        (JSC::DFG::Node::shouldSpeculateUint32Array):
     31        (JSC::DFG::Node::shouldSpeculateFloat32Array):
     32        (JSC::DFG::Node::shouldSpeculateFloat64Array):
     33        * dfg/DFGPropagator.cpp:
     34        (JSC::DFG::Propagator::byValIsPure):
     35        * dfg/DFGSpeculativeJIT.cpp:
     36        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
     37        * dfg/DFGSpeculativeJIT32_64.cpp:
     38        (JSC::DFG::SpeculativeJIT::compile):
     39        * dfg/DFGSpeculativeJIT64.cpp:
     40        (JSC::DFG::SpeculativeJIT::compile):
     41
    1422011-12-22  Gavin Barraclough  <[email protected]>
    243
  • trunk/Source/JavaScriptCore/bytecode/PredictedType.h

    r103023 r103604  
    152152}
    153153
     154inline bool isActionableMutableArrayPrediction(PredictedType value)
     155{
     156    return isArrayPrediction(value)
     157        || isByteArrayPrediction(value)
     158        || isInt8ArrayPrediction(value)
     159        || isInt16ArrayPrediction(value)
     160        || isInt32ArrayPrediction(value)
     161        || isUint8ArrayPrediction(value)
     162        || isUint16ArrayPrediction(value)
     163        || isUint32ArrayPrediction(value)
     164#if CPU(X86) || CPU(X86_64)
     165        || isFloat32ArrayPrediction(value)
     166#endif
     167        || isFloat64ArrayPrediction(value);
     168}
     169
     170inline bool isActionableArrayPrediction(PredictedType value)
     171{
     172    return isStringPrediction(value)
     173        || isActionableMutableArrayPrediction(value);
     174}
     175
    154176inline bool isArrayOrOtherPrediction(PredictedType value)
    155177{
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r103594 r103604  
    403403           
    404404    case GetByVal: {
    405         PredictedType indexPrediction = m_graph[node.child2()].prediction();
    406         if (!(indexPrediction & PredictInt32) && indexPrediction) {
     405        if (!node.prediction() || !m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) {
     406            m_isValid = false;
     407            break;
     408        }
     409        if (!isActionableArrayPrediction(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger()) {
    407410            clobberStructures(nodeIndex);
    408411            forNode(nodeIndex).makeTop();
     
    470473            break;
    471474        }
     475        ASSERT(m_graph[node.child1()].shouldSpeculateArray());
    472476        forNode(node.child1()).filter(PredictArray);
    473477        forNode(node.child2()).filter(PredictInt32);
     
    478482    case PutByVal:
    479483    case PutByValAlias: {
    480         PredictedType indexPrediction = m_graph[node.child2()].prediction();
    481         if (!(indexPrediction & PredictInt32) && indexPrediction) {
     484        if (!m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) {
     485            m_isValid = false;
     486            break;
     487        }
     488        if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) {
     489            ASSERT(node.op == PutByVal);
    482490            clobberStructures(nodeIndex);
    483491            forNode(nodeIndex).makeTop();
     
    539547            break;
    540548        }
    541            
     549        ASSERT(m_graph[node.child1()].shouldSpeculateArray());
    542550        forNode(node.child1()).filter(PredictArray);
    543551        forNode(node.child2()).filter(PredictInt32);
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r103255 r103604  
    932932    bool shouldSpeculateInt8Array()
    933933    {
    934         return prediction() == PredictInt8Array;
     934        return isInt8ArrayPrediction(prediction());
    935935    }
    936936   
    937937    bool shouldSpeculateInt16Array()
    938938    {
    939         return prediction() == PredictInt16Array;
     939        return isInt16ArrayPrediction(prediction());
    940940    }
    941941   
    942942    bool shouldSpeculateInt32Array()
    943943    {
    944         return prediction() == PredictInt32Array;
     944        return isInt32ArrayPrediction(prediction());
    945945    }
    946946   
    947947    bool shouldSpeculateUint8Array()
    948948    {
    949         return prediction() == PredictUint8Array;
     949        return isUint8ArrayPrediction(prediction());
    950950    }
    951951   
    952952    bool shouldSpeculateUint16Array()
    953953    {
    954         return prediction() == PredictUint16Array;
     954        return isUint16ArrayPrediction(prediction());
    955955    }
    956956   
    957957    bool shouldSpeculateUint32Array()
    958958    {
    959         return prediction() == PredictUint32Array;
     959        return isUint32ArrayPrediction(prediction());
    960960    }
    961961   
     
    963963    {
    964964#if CPU(X86) || CPU(X86_64)
    965         return !!(prediction() & PredictFloat32Array);
     965        return isFloat32ArrayPrediction(prediction());
    966966#else
    967967        return false;
     
    971971    bool shouldSpeculateFloat64Array()
    972972    {
    973         return prediction() == PredictFloat64Array;
     973        return isFloat64ArrayPrediction(prediction());
    974974    }
    975975   
  • trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp

    r103255 r103604  
    10881088    bool byValIsPure(Node& node)
    10891089    {
    1090         PredictedType prediction = m_graph[node.child2()].prediction();
    1091         return (prediction & PredictInt32) || !prediction;
     1090        return m_graph[node.child2()].shouldSpeculateInteger()
     1091            && ((node.op == PutByVal || node.op == PutByValAlias)
     1092                ? isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())
     1093                : isActionableArrayPrediction(m_graph[node.child1()].prediction()));
    10921094    }
    10931095   
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r103306 r103604  
    23772377void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
    23782378{
     2379    if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2380        terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2381        return;
     2382    }
     2383       
    23792384    SpeculateCellOperand base(this, node.child1());
    23802385    GPRReg baseReg = base.gpr();
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r103587 r103604  
    22062206
    22072207    case GetByVal: {
    2208         PredictedType basePrediction = at(node.child2()).prediction();
    2209         if (!(basePrediction & PredictInt32) && basePrediction) {
     2208        if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2209            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2210            break;
     2211        }
     2212       
     2213        if (!at(node.child2()).shouldSpeculateInteger() || !isActionableArrayPrediction(at(node.child1()).prediction())) {
    22102214            SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right.
    22112215            JSValueOperand property(this, node.child2());
     
    22922296            break;           
    22932297        }
     2298       
     2299        ASSERT(at(node.child1()).shouldSpeculateArray());
    22942300
    22952301        SpeculateStrictInt32Operand property(this, node.child2());
     
    23262332
    23272333    case PutByVal: {
    2328         PredictedType basePrediction = at(node.child2()).prediction();
    2329         if (!(basePrediction & PredictInt32) && basePrediction) {
     2334        if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2335            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2336            break;
     2337        }
     2338       
     2339        if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArrayPrediction(at(node.child1()).prediction())) {
    23302340            SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right.
    23312341            JSValueOperand property(this, node.child2());
     
    24102420            break;           
    24112421        }
     2422       
     2423        ASSERT(at(node.child1()).shouldSpeculateArray());
    24122424
    24132425        JSValueOperand value(this, node.child3());
     
    24732485
    24742486    case PutByValAlias: {
     2487        if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2488            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2489            break;
     2490        }
     2491       
     2492        ASSERT(isActionableMutableArrayPrediction(at(node.child1()).prediction()));
     2493        ASSERT(at(node.child2()).shouldSpeculateInteger());
     2494
    24752495        SpeculateCellOperand base(this, node.child1());
    24762496        SpeculateStrictInt32Operand property(this, node.child2());
     
    25362556            break;           
    25372557        }
     2558
     2559        ASSERT(at(node.child1()).shouldSpeculateArray());
    25382560
    25392561        JSValueOperand value(this, node.child3());
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r103587 r103604  
    22872287
    22882288    case GetByVal: {
    2289         PredictedType basePrediction = at(node.child2()).prediction();
    2290         if (!(basePrediction & PredictInt32) && basePrediction) {
     2289        if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2290            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2291            break;
     2292        }
     2293       
     2294        if (!at(node.child2()).shouldSpeculateInteger() || !isActionableArrayPrediction(at(node.child1()).prediction())) {
    22912295            JSValueOperand base(this, node.child1());
    22922296            JSValueOperand property(this, node.child2());
     
    23712375            break;           
    23722376        }
     2377       
     2378        ASSERT(at(node.child1()).shouldSpeculateArray());
    23732379
    23742380        SpeculateCellOperand base(this, node.child1());
     
    23992405
    24002406    case PutByVal: {
    2401         PredictedType basePrediction = at(node.child2()).prediction();
    2402         if (!(basePrediction & PredictInt32) && basePrediction) {
     2407        if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2408            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2409            break;
     2410        }
     2411       
     2412        if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArrayPrediction(at(node.child1()).prediction())) {
    24032413            JSValueOperand arg1(this, node.child1());
    24042414            JSValueOperand arg2(this, node.child2());
     
    24772487            break;           
    24782488        }
     2489           
     2490        ASSERT(at(node.child1()).shouldSpeculateArray());
    24792491
    24802492        JSValueOperand value(this, node.child3());
     
    25382550
    25392551    case PutByValAlias: {
    2540         PredictedType basePrediction = at(node.child2()).prediction();
    2541         ASSERT_UNUSED(basePrediction, (basePrediction & PredictInt32) || !basePrediction);
     2552        if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) {
     2553            terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
     2554            break;
     2555        }
     2556       
     2557        ASSERT(isActionableMutableArrayPrediction(at(node.child1()).prediction()));
     2558        ASSERT(at(node.child2()).shouldSpeculateInteger());
    25422559
    25432560        SpeculateCellOperand base(this, node.child1());
     
    26032620            break;           
    26042621        }
     2622       
     2623        ASSERT(at(node.child1()).shouldSpeculateArray());
    26052624
    26062625        JSValueOperand value(this, node.child3());
Note: See TracChangeset for help on using the changeset viewer.