Changeset 95930 in webkit


Ignore:
Timestamp:
Sep 25, 2011 7:25:02 PM (13 years ago)
Author:
fpizlo@apple.com
Message:

DFG static prediction code is no longer needed and should be removed
https://bugs.webkit.org/show_bug.cgi?id=68784

Reviewed by Oliver Hunt.

This gets rid of static prediction code, and ensures that we do not
try to compile code where dynamic predictions are not available.
This is accomplished by immediately performing an OSR exit wherever
a value is retrieved for which no predictions exist.

This also adds value profiling for this on functions used for calls.

The heuristics for deciding when to optimize code are also tweaked,
since it is now profitable to optimize sooner. This may need to be
tweaked further, but this patch only makes minimal changes.

This results in a 16% speed-up on Kraken/ai-astar, leading to a 3%
overall win on Kraken. It's neutral elsewhere.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::shouldOptimizeNow):
(JSC::CodeBlock::dumpValueProfiles):

  • bytecode/CodeBlock.h:
  • bytecode/PredictedType.cpp:

(JSC::predictionToString):

  • bytecode/PredictedType.h:

(JSC::isCellPrediction):
(JSC::isObjectPrediction):
(JSC::isFinalObjectPrediction):
(JSC::isStringPrediction):
(JSC::isArrayPrediction):
(JSC::isInt32Prediction):
(JSC::isDoublePrediction):
(JSC::isNumberPrediction):
(JSC::isBooleanPrediction):
(JSC::mergePredictions):

  • bytecode/PredictionTracker.h:

(JSC::PredictionTracker::predictArgument):
(JSC::PredictionTracker::predict):
(JSC::PredictionTracker::predictGlobalVar):

  • bytecode/ValueProfile.cpp:

(JSC::ValueProfile::computeUpdatedPrediction):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::set):
(JSC::DFG::ByteCodeParser::addCall):
(JSC::DFG::ByteCodeParser::getPrediction):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::predictArgumentTypes):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::predict):
(JSC::DFG::Graph::predictGlobalVar):
(JSC::DFG::Graph::getMethodCheckPrediction):
(JSC::DFG::Graph::getJSConstantPrediction):
(JSC::DFG::Graph::getPrediction):

  • dfg/DFGJITCodeGenerator.cpp:

(JSC::DFG::JITCodeGenerator::writeBarrier):
(JSC::DFG::JITCodeGenerator::emitBranch):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::getPrediction):

  • dfg/DFGNode.h:

(JSC::DFG::Node::valueOfJSConstantNode):
(JSC::DFG::Node::isInt32Constant):
(JSC::DFG::Node::isDoubleConstant):
(JSC::DFG::Node::isNumberConstant):
(JSC::DFG::Node::isBooleanConstant):
(JSC::DFG::Node::predict):

  • dfg/DFGPropagator.cpp:

(JSC::DFG::Propagator::Propagator):
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::fixupNode):
(JSC::DFG::Propagator::isPredictedNumerical):
(JSC::DFG::Propagator::logicalNotIsPure):

  • dfg/DFGSpeculativeJIT.cpp:

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

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::shouldSpeculateInteger):
(JSC::DFG::SpeculativeJIT::shouldSpeculateDouble):
(JSC::DFG::SpeculativeJIT::shouldSpeculateNumber):
(JSC::DFG::SpeculativeJIT::shouldNotSpeculateInteger):
(JSC::DFG::SpeculativeJIT::shouldSpeculateFinalObject):
(JSC::DFG::SpeculativeJIT::shouldSpeculateArray):
(JSC::DFG::SpeculativeJIT::shouldSpeculateObject):
(JSC::DFG::SpeculativeJIT::shouldSpeculateCell):

  • jit/JIT.cpp:

(JSC::JIT::privateCompile):

Location:
trunk/Source/JavaScriptCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r95927 r95930  
     12011-09-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG static prediction code is no longer needed and should be removed
     4        https://bugs.webkit.org/show_bug.cgi?id=68784
     5
     6        Reviewed by Oliver Hunt.
     7       
     8        This gets rid of static prediction code, and ensures that we do not
     9        try to compile code where dynamic predictions are not available.
     10        This is accomplished by immediately performing an OSR exit wherever
     11        a value is retrieved for which no predictions exist.
     12       
     13        This also adds value profiling for this on functions used for calls.
     14       
     15        The heuristics for deciding when to optimize code are also tweaked,
     16        since it is now profitable to optimize sooner. This may need to be
     17        tweaked further, but this patch only makes minimal changes.
     18       
     19        This results in a 16% speed-up on Kraken/ai-astar, leading to a 3%
     20        overall win on Kraken.  It's neutral elsewhere.
     21
     22        * bytecode/CodeBlock.cpp:
     23        (JSC::CodeBlock::shouldOptimizeNow):
     24        (JSC::CodeBlock::dumpValueProfiles):
     25        * bytecode/CodeBlock.h:
     26        * bytecode/PredictedType.cpp:
     27        (JSC::predictionToString):
     28        * bytecode/PredictedType.h:
     29        (JSC::isCellPrediction):
     30        (JSC::isObjectPrediction):
     31        (JSC::isFinalObjectPrediction):
     32        (JSC::isStringPrediction):
     33        (JSC::isArrayPrediction):
     34        (JSC::isInt32Prediction):
     35        (JSC::isDoublePrediction):
     36        (JSC::isNumberPrediction):
     37        (JSC::isBooleanPrediction):
     38        (JSC::mergePredictions):
     39        * bytecode/PredictionTracker.h:
     40        (JSC::PredictionTracker::predictArgument):
     41        (JSC::PredictionTracker::predict):
     42        (JSC::PredictionTracker::predictGlobalVar):
     43        * bytecode/ValueProfile.cpp:
     44        (JSC::ValueProfile::computeUpdatedPrediction):
     45        * dfg/DFGByteCodeParser.cpp:
     46        (JSC::DFG::ByteCodeParser::set):
     47        (JSC::DFG::ByteCodeParser::addCall):
     48        (JSC::DFG::ByteCodeParser::getPrediction):
     49        (JSC::DFG::ByteCodeParser::parseBlock):
     50        * dfg/DFGGraph.cpp:
     51        (JSC::DFG::Graph::predictArgumentTypes):
     52        * dfg/DFGGraph.h:
     53        (JSC::DFG::Graph::predict):
     54        (JSC::DFG::Graph::predictGlobalVar):
     55        (JSC::DFG::Graph::getMethodCheckPrediction):
     56        (JSC::DFG::Graph::getJSConstantPrediction):
     57        (JSC::DFG::Graph::getPrediction):
     58        * dfg/DFGJITCodeGenerator.cpp:
     59        (JSC::DFG::JITCodeGenerator::writeBarrier):
     60        (JSC::DFG::JITCodeGenerator::emitBranch):
     61        * dfg/DFGJITCompiler.h:
     62        (JSC::DFG::JITCompiler::getPrediction):
     63        * dfg/DFGNode.h:
     64        (JSC::DFG::Node::valueOfJSConstantNode):
     65        (JSC::DFG::Node::isInt32Constant):
     66        (JSC::DFG::Node::isDoubleConstant):
     67        (JSC::DFG::Node::isNumberConstant):
     68        (JSC::DFG::Node::isBooleanConstant):
     69        (JSC::DFG::Node::predict):
     70        * dfg/DFGPropagator.cpp:
     71        (JSC::DFG::Propagator::Propagator):
     72        (JSC::DFG::Propagator::propagateNodePredictions):
     73        (JSC::DFG::Propagator::fixupNode):
     74        (JSC::DFG::Propagator::isPredictedNumerical):
     75        (JSC::DFG::Propagator::logicalNotIsPure):
     76        * dfg/DFGSpeculativeJIT.cpp:
     77        (JSC::DFG::SpeculativeJIT::compile):
     78        * dfg/DFGSpeculativeJIT.h:
     79        (JSC::DFG::SpeculativeJIT::shouldSpeculateInteger):
     80        (JSC::DFG::SpeculativeJIT::shouldSpeculateDouble):
     81        (JSC::DFG::SpeculativeJIT::shouldSpeculateNumber):
     82        (JSC::DFG::SpeculativeJIT::shouldNotSpeculateInteger):
     83        (JSC::DFG::SpeculativeJIT::shouldSpeculateFinalObject):
     84        (JSC::DFG::SpeculativeJIT::shouldSpeculateArray):
     85        (JSC::DFG::SpeculativeJIT::shouldSpeculateObject):
     86        (JSC::DFG::SpeculativeJIT::shouldSpeculateCell):
     87        * jit/JIT.cpp:
     88        (JSC::JIT::privateCompile):
     89
    1902011-09-25  Filip Pizlo  <fpizlo@apple.com>
    291
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r95901 r95930  
    20002000
    20012001    if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= 0.75)
    2002         && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= 0.5))
     2002        && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= 0.25))
    20032003        return true;
    20042004   
     
    20272027        if (profile->m_bytecodeOffset < 0) {
    20282028            ASSERT(profile->m_bytecodeOffset == -1);
    2029             fprintf(stderr, "   arg = %u: ", i + 1);
     2029            fprintf(stderr, "   arg = %u: ", i);
    20302030        } else
    20312031            fprintf(stderr, "   bc = %d: ", profile->m_bytecodeOffset);
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r95901 r95930  
    499499        ValueProfile* valueProfileForArgument(int argumentIndex)
    500500        {
    501             int index = argumentIndex - 1;
     501            int index = argumentIndex;
    502502            if (static_cast<unsigned>(index) >= m_valueProfiles.size())
    503503                return 0;
    504             ValueProfile* result = valueProfile(argumentIndex - 1);
     504            ValueProfile* result = valueProfile(argumentIndex);
    505505            if (result->m_bytecodeOffset != -1)
    506506                return 0;
  • trunk/Source/JavaScriptCore/bytecode/PredictedType.cpp

    r95901 r95930  
    3838const char* predictionToString(PredictedType value)
    3939{
     40    if (value == PredictNone)
     41        return "None";
     42   
    4043    static const int size = 96;
    4144    static char description[size];
    4245    BoundsCheckedPointer<char> ptr(description, size);
    43    
    44     if (!(value & StrongPredictionTag))
    45         ptr.strcat("Weak");
    4646   
    4747    if (value & PredictObjectUnknown) {
  • trunk/Source/JavaScriptCore/bytecode/PredictedType.h

    r95901 r95930  
    5252static const PredictedType PredictOther         = 0x4000; // It's definitely none of the above.
    5353static const PredictedType PredictTop           = 0x7fff; // It can be any of the above.
    54 static const PredictedType StrongPredictionTag  = 0x8000; // It's a strong prediction (all strong predictions trump all weak ones).
    55 static const PredictedType PredictionTagMask    = 0x8000;
    56 
    57 enum PredictionSource { WeakPrediction, StrongPrediction };
    5854
    5955inline bool isCellPrediction(PredictedType value)
    6056{
    61     return !!(value & PredictCell) && !(value & ~(PredictCell | PredictionTagMask));
     57    return !!(value & PredictCell) && !(value & ~PredictCell);
    6258}
    6359
    6460inline bool isObjectPrediction(PredictedType value)
    6561{
    66     return !!(value & PredictObjectMask) && !(value & ~(PredictObjectMask | PredictionTagMask));
     62    return !!(value & PredictObjectMask) && !(value & ~PredictObjectMask);
    6763}
    6864
    6965inline bool isFinalObjectPrediction(PredictedType value)
    7066{
    71     return (value & ~PredictionTagMask) == PredictFinalObject;
     67    return value == PredictFinalObject;
    7268}
    7369
    7470inline bool isStringPrediction(PredictedType value)
    7571{
    76     return (value & ~PredictionTagMask) == PredictString;
     72    return value == PredictString;
    7773}
    7874
    7975inline bool isArrayPrediction(PredictedType value)
    8076{
    81     return (value & ~PredictionTagMask) == PredictArray;
     77    return value == PredictArray;
    8278}
    8379
    8480inline bool isInt32Prediction(PredictedType value)
    8581{
    86     return (value & ~PredictionTagMask) == PredictInt32;
     82    return value == PredictInt32;
    8783}
    8884
    8985inline bool isDoublePrediction(PredictedType value)
    9086{
    91     return (value & ~PredictionTagMask) == PredictDouble;
     87    return value == PredictDouble;
    9288}
    9389
    9490inline bool isNumberPrediction(PredictedType value)
    9591{
    96     return !!(value & PredictNumber) && !(value & ~(PredictNumber | PredictionTagMask));
     92    return !!(value & PredictNumber) && !(value & ~PredictNumber);
    9793}
    9894
    9995inline bool isBooleanPrediction(PredictedType value)
    10096{
    101     return (value & ~PredictionTagMask) == PredictBoolean;
    102 }
    103 
    104 inline bool isStrongPrediction(PredictedType value)
    105 {
    106     ASSERT(value != (PredictNone | StrongPredictionTag));
    107     return !!(value & StrongPredictionTag);
     97    return value == PredictBoolean;
    10898}
    10999
     
    114104inline PredictedType mergePredictions(PredictedType left, PredictedType right)
    115105{
    116     if (isStrongPrediction(left) == isStrongPrediction(right)) {
    117         if (left & PredictObjectUnknown) {
    118             ASSERT(!(left & (PredictObjectMask & ~PredictObjectUnknown)));
    119             if (right & PredictObjectMask)
    120                 return (left & ~PredictObjectUnknown) | right;
    121         } else if (right & PredictObjectUnknown) {
    122             ASSERT(!(right & (PredictObjectMask & ~PredictObjectUnknown)));
    123             if (left & PredictObjectMask)
    124                 return (right & ~PredictObjectUnknown) | left;
    125         }
    126         return left | right;
     106    if (left & PredictObjectUnknown) {
     107        ASSERT(!(left & (PredictObjectMask & ~PredictObjectUnknown)));
     108        if (right & PredictObjectMask)
     109            return (left & ~PredictObjectUnknown) | right;
     110    } else if (right & PredictObjectUnknown) {
     111        ASSERT(!(right & (PredictObjectMask & ~PredictObjectUnknown)));
     112        if (left & PredictObjectMask)
     113            return (right & ~PredictObjectUnknown) | left;
    127114    }
    128     if (isStrongPrediction(left)) {
    129         ASSERT(!isStrongPrediction(right));
    130         return left;
    131     }
    132     ASSERT(!isStrongPrediction(left));
    133     ASSERT(isStrongPrediction(right));
    134     return right;
     115    return left | right;
    135116}
    136117
     
    144125}
    145126
    146 inline PredictedType makePrediction(PredictedType type, PredictionSource source)
    147 {
    148     ASSERT(!(type & StrongPredictionTag));
    149     ASSERT(source == StrongPrediction || source == WeakPrediction);
    150     if (type == PredictNone)
    151         return PredictNone;
    152     return type | (source == StrongPrediction ? StrongPredictionTag : 0);
    153 }
    154 
    155127PredictedType predictionFromClassInfo(const ClassInfo*);
    156128PredictedType predictionFromStructure(Structure*);
  • trunk/Source/JavaScriptCore/bytecode/PredictionTracker.h

    r95901 r95930  
    7474    unsigned argumentIndexForOperand(int operand) const { return operand + m_arguments.size() + RegisterFile::CallFrameHeaderSize; }
    7575
    76     bool predictArgument(unsigned argument, PredictedType prediction, PredictionSource source)
     76    bool predictArgument(unsigned argument, PredictedType prediction)
    7777    {
    78         return mergePrediction(m_arguments[argument].m_value, makePrediction(prediction, source));
     78        return mergePrediction(m_arguments[argument].m_value, prediction);
    7979    }
    8080   
    81     bool predict(int operand, PredictedType prediction, PredictionSource source)
     81    bool predict(int operand, PredictedType prediction)
    8282    {
    8383        if (operandIsArgument(operand))
    84             return predictArgument(argumentIndexForOperand(operand), prediction, source);
     84            return predictArgument(argumentIndexForOperand(operand), prediction);
    8585        if ((unsigned)operand >= m_variables.size()) {
    8686            ASSERT(operand >= 0);
     
    8888        }
    8989       
    90         return mergePrediction(m_variables[operand].m_value, makePrediction(prediction, source));
     90        return mergePrediction(m_variables[operand].m_value, prediction);
    9191    }
    9292   
    93     bool predictGlobalVar(unsigned varNumber, PredictedType prediction, PredictionSource source)
     93    bool predictGlobalVar(unsigned varNumber, PredictedType prediction)
    9494    {
    9595        HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVars.find(varNumber + 1);
    9696        if (iter == m_globalVars.end()) {
    9797            PredictionSlot predictionSlot;
    98             bool result = mergePrediction(predictionSlot.m_value, makePrediction(prediction, source));
     98            bool result = mergePrediction(predictionSlot.m_value, prediction);
    9999            m_globalVars.add(varNumber + 1, predictionSlot);
    100100            return result;
    101101        }
    102         return mergePrediction(iter->second.m_value, makePrediction(prediction, source));
     102        return mergePrediction(iter->second.m_value, prediction);
    103103    }
    104104   
  • trunk/Source/JavaScriptCore/bytecode/ValueProfile.cpp

    r95901 r95930  
    9595        prediction = PredictNone;
    9696    else if (statistics.int32s == statistics.samples)
    97         prediction = StrongPredictionTag | PredictInt32;
     97        prediction = PredictInt32;
    9898    else if (statistics.doubles == statistics.samples)
    99         prediction = StrongPredictionTag | PredictDouble;
     99        prediction = PredictDouble;
    100100    else if (statistics.int32s + statistics.doubles == statistics.samples)
    101         prediction = StrongPredictionTag | PredictNumber;
     101        prediction = PredictNumber;
    102102    else if (statistics.arrays == statistics.samples)
    103         prediction = StrongPredictionTag | PredictArray;
     103        prediction = PredictArray;
    104104    else if (statistics.finalObjects == statistics.samples)
    105         prediction = StrongPredictionTag | PredictFinalObject;
     105        prediction = PredictFinalObject;
    106106    else if (statistics.strings == statistics.samples)
    107         prediction = StrongPredictionTag | PredictString;
     107        prediction = PredictString;
    108108    else if (statistics.objects == statistics.samples)
    109         prediction = StrongPredictionTag | PredictObjectOther;
     109        prediction = PredictObjectOther;
    110110    else if (statistics.cells == statistics.samples)
    111         prediction = StrongPredictionTag | PredictCellOther;
     111        prediction = PredictCellOther;
    112112    else if (statistics.booleans == statistics.samples)
    113         prediction = StrongPredictionTag | PredictBoolean;
     113        prediction = PredictBoolean;
    114114    else
    115         prediction = StrongPredictionTag | PredictOther;
     115        prediction = PredictOther;
    116116
    117117    m_numberOfSamplesInPrediction += statistics.samples;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r95927 r95930  
    102102        return getLocal((unsigned)operand);
    103103    }
    104     void set(int operand, NodeIndex value, PredictedType weakPrediction = PredictNone)
    105     {
    106         m_graph.predict(operand, weakPrediction, WeakPrediction);
    107 
     104    void set(int operand, NodeIndex value)
     105    {
    108106        // Is this an argument?
    109107        if (operandIsArgument(operand)) {
     
    437435        PredictedType prediction = PredictNone;
    438436        if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
    439             prediction = getStrongPrediction(m_graph.size(), m_currentIndex + OPCODE_LENGTH(op_call));
     437            prediction = getPrediction(m_graph.size(), m_currentIndex + OPCODE_LENGTH(op_call));
    440438       
    441439        addVarArgChild(get(currentInstruction[1].u.operand));
     
    453451    }
    454452
    455     void weaklyPredictArray(NodeIndex nodeIndex)
    456     {
    457         m_graph.predict(m_graph[nodeIndex], PredictArray, WeakPrediction);
    458     }
    459 
    460     void weaklyPredictInt32(NodeIndex nodeIndex)
    461     {
    462         ASSERT(m_reusableNodeStack.isEmpty());
    463         m_reusableNodeStack.append(&m_graph[nodeIndex]);
    464        
    465         do {
    466             Node* nodePtr = m_reusableNodeStack.last();
    467             m_reusableNodeStack.removeLast();
    468            
    469             if (nodePtr->op == ValueToNumber)
    470                 nodePtr = &m_graph[nodePtr->child1()];
    471            
    472             if (nodePtr->op == ValueToInt32)
    473                 nodePtr = &m_graph[nodePtr->child1()];
    474            
    475             switch (nodePtr->op) {
    476             case ArithAdd:
    477             case ArithSub:
    478             case ArithMul:
    479             case ValueAdd:
    480                 m_reusableNodeStack.append(&m_graph[nodePtr->child1()]);
    481                 m_reusableNodeStack.append(&m_graph[nodePtr->child2()]);
    482                 break;
    483             default:
    484                 m_graph.predict(*nodePtr, PredictInt32, WeakPrediction);
    485                 break;
    486             }
    487         } while (!m_reusableNodeStack.isEmpty());
    488     }
    489    
    490     PredictedType getStrongPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex)
     453    PredictedType getPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex)
    491454    {
    492455        UNUSED_PARAM(nodeIndex);
     
    508471    }
    509472   
    510     PredictedType getStrongPrediction()
    511     {
    512         return getStrongPrediction(m_graph.size(), m_currentIndex);
     473    PredictedType getPrediction()
     474    {
     475        return getPrediction(m_graph.size(), m_currentIndex);
    513476    }
    514477
     
    772735            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    773736            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    774             weaklyPredictInt32(op1);
    775             weaklyPredictInt32(op2);
    776             set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2), PredictInt32);
     737            set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2));
    777738            NEXT_OPCODE(op_bitand);
    778739        }
     
    781742            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    782743            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    783             weaklyPredictInt32(op1);
    784             weaklyPredictInt32(op2);
    785             set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2), PredictInt32);
     744            set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2));
    786745            NEXT_OPCODE(op_bitor);
    787746        }
     
    790749            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    791750            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    792             weaklyPredictInt32(op1);
    793             weaklyPredictInt32(op2);
    794             set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2), PredictInt32);
     751            set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2));
    795752            NEXT_OPCODE(op_bitxor);
    796753        }
     
    799756            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    800757            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    801             weaklyPredictInt32(op1);
    802             weaklyPredictInt32(op2);
    803758            NodeIndex result;
    804759            // Optimize out shifts by zero.
     
    807762            else
    808763                result = addToGraph(BitRShift, op1, op2);
    809             set(currentInstruction[1].u.operand, result, PredictInt32);
     764            set(currentInstruction[1].u.operand, result);
    810765            NEXT_OPCODE(op_rshift);
    811766        }
     
    814769            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    815770            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    816             weaklyPredictInt32(op1);
    817             weaklyPredictInt32(op2);
    818771            NodeIndex result;
    819772            // Optimize out shifts by zero.
     
    822775            else
    823776                result = addToGraph(BitLShift, op1, op2);
    824             set(currentInstruction[1].u.operand, result, PredictInt32);
     777            set(currentInstruction[1].u.operand, result);
    825778            NEXT_OPCODE(op_lshift);
    826779        }
     
    829782            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    830783            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    831             weaklyPredictInt32(op1);
    832             weaklyPredictInt32(op2);
    833784            NodeIndex result;
    834785            // The result of a zero-extending right shift is treated as an unsigned value.
     
    851802                result = makeSafe(addToGraph(UInt32ToNumber, OpInfo(NodeUseBottom), result));
    852803            }
    853             set(currentInstruction[1].u.operand, result, PredictInt32);
     804            set(currentInstruction[1].u.operand, result);
    854805            NEXT_OPCODE(op_urshift);
    855806        }
     
    860811            unsigned srcDst = currentInstruction[1].u.operand;
    861812            NodeIndex op = getToNumber(srcDst);
    862             weaklyPredictInt32(op);
    863813            set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
    864814            NEXT_OPCODE(op_pre_inc);
     
    869819            unsigned srcDst = currentInstruction[2].u.operand;
    870820            NodeIndex op = getToNumber(srcDst);
    871             weaklyPredictInt32(op);
    872821            set(result, op);
    873822            set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
     
    878827            unsigned srcDst = currentInstruction[1].u.operand;
    879828            NodeIndex op = getToNumber(srcDst);
    880             weaklyPredictInt32(op);
    881829            set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
    882830            NEXT_OPCODE(op_pre_dec);
     
    887835            unsigned srcDst = currentInstruction[2].u.operand;
    888836            NodeIndex op = getToNumber(srcDst);
    889             weaklyPredictInt32(op);
    890837            set(result, op);
    891838            set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
     
    898845            NodeIndex op1 = get(currentInstruction[2].u.operand);
    899846            NodeIndex op2 = get(currentInstruction[3].u.operand);
    900             // If both operands can statically be determined to the numbers, then this is an arithmetic add.
    901             // Otherwise, we must assume this may be performing a concatenation to a string.
    902             if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) {
    903                 weaklyPredictInt32(op1);
    904                 weaklyPredictInt32(op2);
    905             }
    906            
    907847            if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult())
    908848                set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), toNumber(op1), toNumber(op2))));
     
    915855            NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
    916856            NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
    917             if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) {
    918                 weaklyPredictInt32(op1);
    919                 weaklyPredictInt32(op2);
    920             }
    921            
    922857            set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2)));
    923858            NEXT_OPCODE(op_sub);
     
    1063998
    1064999        case op_get_by_val: {
    1065             PredictedType prediction = getStrongPrediction();
     1000            PredictedType prediction = getPrediction();
    10661001           
    10671002            NodeIndex base = get(currentInstruction[2].u.operand);
    10681003            NodeIndex property = get(currentInstruction[3].u.operand);
    1069             weaklyPredictArray(base);
    1070             weaklyPredictInt32(property);
    10711004
    10721005            NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo(prediction), base, property);
     
    10801013            NodeIndex property = get(currentInstruction[2].u.operand);
    10811014            NodeIndex value = get(currentInstruction[3].u.operand);
    1082             weaklyPredictArray(base);
    1083             weaklyPredictInt32(property);
    10841015
    10851016            addToGraph(PutByVal, base, property, value);
     
    10911022            Instruction* getInstruction = currentInstruction + OPCODE_LENGTH(op_method_check);
    10921023           
    1093             PredictedType prediction = getStrongPrediction();
     1024            PredictedType prediction = getPrediction();
    10941025           
    10951026            ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id);
     
    11251056        }
    11261057        case op_get_scoped_var: {
    1127             PredictedType prediction = getStrongPrediction();
     1058            PredictedType prediction = getPrediction();
    11281059            int dst = currentInstruction[1].u.operand;
    11291060            int slot = currentInstruction[2].u.operand;
     
    11431074        }
    11441075        case op_get_by_id: {
    1145             PredictedType prediction = getStrongPrediction();
     1076            PredictedType prediction = getPrediction();
    11461077           
    11471078            NodeIndex base = get(currentInstruction[2].u.operand);
     
    11891120
    11901121        case op_get_global_var: {
    1191             PredictedType prediction = getStrongPrediction();
     1122            PredictedType prediction = getPrediction();
    11921123           
    11931124            NodeIndex getGlobalVar = addToGraph(GetGlobalVar, OpInfo(currentInstruction[2].u.operand));
    11941125            set(currentInstruction[1].u.operand, getGlobalVar);
    1195             m_graph.predictGlobalVar(currentInstruction[2].u.operand, prediction & ~PredictionTagMask, StrongPrediction);
     1126            m_graph.predictGlobalVar(currentInstruction[2].u.operand, prediction);
    11961127            NEXT_OPCODE(op_get_global_var);
    11971128        }
     
    14251356
    14261357        case op_resolve: {
    1427             PredictedType prediction = getStrongPrediction();
     1358            PredictedType prediction = getPrediction();
    14281359           
    14291360            unsigned identifier = currentInstruction[2].u.operand;
     
    14361367
    14371368        case op_resolve_base: {
    1438             PredictedType prediction = getStrongPrediction();
     1369            PredictedType prediction = getPrediction();
    14391370           
    14401371            unsigned identifier = currentInstruction[2].u.operand;
     
    14471378           
    14481379        case op_resolve_global: {
    1449             PredictedType prediction = getStrongPrediction();
     1380            PredictedType prediction = getPrediction();
    14501381           
    14511382            NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r95901 r95930  
    207207        size_t numberOfArguments = std::min(exec->argumentCountIncludingThis(), m_predictions.numberOfArguments());
    208208       
    209         for (size_t arg = 1; arg < numberOfArguments; ++arg) {
    210             JSValue argumentValue = exec->argument(arg - 1);
    211             if (argumentValue.isInt32())
    212                 m_predictions.predictArgument(arg, PredictInt32, WeakPrediction);
    213             else if (argumentValue.isDouble())
    214                 m_predictions.predictArgument(arg, PredictDouble, WeakPrediction);
    215         }
     209        for (size_t arg = 1; arg < numberOfArguments; ++arg)
     210            m_predictions.predictArgument(arg, predictionFromValue(exec->argument(arg - 1)));
    216211    }
    217212   
     
    221216    CodeBlock* profiledCodeBlock = codeBlock->alternative();
    222217    ASSERT(codeBlock->m_numParameters >= 1);
    223     for (size_t arg = 1; arg < static_cast<size_t>(codeBlock->m_numParameters); ++arg) {
     218    for (size_t arg = 0; arg < static_cast<size_t>(codeBlock->m_numParameters); ++arg) {
    224219        ValueProfile* profile = profiledCodeBlock->valueProfileForArgument(arg);
    225220        if (!profile)
    226221            continue;
    227222       
    228         m_predictions.predictArgument(arg, profile->computeUpdatedPrediction() & ~PredictionTagMask, StrongPrediction);
     223        m_predictions.predictArgument(arg, profile->computeUpdatedPrediction());
    229224       
    230225#if ENABLE(DFG_DEBUG_VERBOSE)
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r95901 r95930  
    177177    }
    178178   
    179     bool predict(int operand, PredictedType prediction, PredictionSource source)
    180     {
    181         return m_predictions.predict(operand, prediction, source);
    182     }
    183    
    184     bool predictGlobalVar(unsigned varNumber, PredictedType prediction, PredictionSource source)
    185     {
    186         return m_predictions.predictGlobalVar(varNumber, prediction, source);
    187     }
    188    
    189     bool predict(Node& node, PredictedType prediction, PredictionSource source)
     179    bool predict(int operand, PredictedType prediction)
     180    {
     181        return m_predictions.predict(operand, prediction);
     182    }
     183   
     184    bool predictGlobalVar(unsigned varNumber, PredictedType prediction)
     185    {
     186        return m_predictions.predictGlobalVar(varNumber, prediction);
     187    }
     188   
     189    bool predict(Node& node, PredictedType prediction)
    190190    {
    191191        switch (node.op) {
    192192        case GetLocal:
    193             return predict(node.local(), prediction, source);
     193            return predict(node.local(), prediction);
    194194            break;
    195195        case GetGlobalVar:
    196             return predictGlobalVar(node.varNumber(), prediction, source);
     196            return predictGlobalVar(node.varNumber(), prediction);
    197197            break;
    198198        case GetById:
     
    207207        case ResolveBaseStrictPut:
    208208        case ResolveGlobal:
    209             return node.predict(prediction, source);
     209            return node.predict(prediction);
    210210        default:
    211211            return false;
     
    225225    PredictedType getMethodCheckPrediction(Node& node)
    226226    {
    227         return makePrediction(predictionFromCell(m_methodCheckData[node.methodCheckDataIndex()].function), StrongPrediction);
    228     }
    229    
    230     PredictedType getPrediction(Node& node)
     227        return predictionFromCell(m_methodCheckData[node.methodCheckDataIndex()].function);
     228    }
     229   
     230    PredictedType getJSConstantPrediction(Node& node, CodeBlock* codeBlock)
     231    {
     232        return predictionFromValue(node.valueOfJSConstantNode(codeBlock));
     233    }
     234   
     235    PredictedType getPrediction(Node& node, CodeBlock* codeBlock)
    231236    {
    232237        Node* nodePtr = &node;
     
    252257        case CheckMethod:
    253258            return getMethodCheckPrediction(*nodePtr);
     259        case JSConstant:
     260            return getJSConstantPrediction(*nodePtr, codeBlock);
    254261        default:
    255262            return PredictNone;
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r95927 r95930  
    12301230    JITCompiler::Jump rhsNotCell;
    12311231    bool hadCellCheck = false;
    1232     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.graph().getPrediction(m_jit.graph()[valueIndex]))) {
     1232    if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    12331233        hadCellCheck = true;
    12341234        rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     
    12711271    JITCompiler::Jump rhsNotCell;
    12721272    bool hadCellCheck = false;
    1273     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.graph().getPrediction(m_jit.graph()[valueIndex]))) {
     1273    if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    12741274        hadCellCheck = true;
    12751275        rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     
    17971797        GPRReg resultGPR = result.gpr();
    17981798       
    1799         bool predictBoolean = isBooleanPrediction(m_jit.graph().getPrediction(m_jit.graph()[node.child1()]));
     1799        bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
    18001800   
    18011801        if (predictBoolean) {
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r95902 r95930  
    273273    bool valueOfBooleanConstant(NodeIndex nodeIndex) { return graph().valueOfBooleanConstant(codeBlock(), nodeIndex); }
    274274    JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return graph().valueOfFunctionConstant(codeBlock(), nodeIndex); }
     275   
     276    // Helper methods to get predictions
     277    PredictedType getPrediction(Node& node) { return graph().getPrediction(node, codeBlock()); }
     278    PredictedType getPrediction(NodeIndex nodeIndex) { return getPrediction(graph()[nodeIndex]); }
    275279
    276280#if USE(JSVALUE32_64)
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r95916 r95930  
    427427    }
    428428   
     429    // NOTE: this only works for JSConstant nodes.
     430    JSValue valueOfJSConstantNode(CodeBlock* codeBlock)
     431    {
     432        return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
     433    }
     434
    429435    bool isInt32Constant(CodeBlock* codeBlock)
    430436    {
    431         return isConstant() && valueOfJSConstant(codeBlock).isInt32();
     437        return isConstant() && valueOfJSConstantNode(codeBlock).isInt32();
    432438    }
    433439   
    434440    bool isDoubleConstant(CodeBlock* codeBlock)
    435441    {
    436         bool result = isConstant() && valueOfJSConstant(codeBlock).isDouble();
     442        bool result = isConstant() && valueOfJSConstantNode(codeBlock).isDouble();
    437443        if (result)
    438444            ASSERT(!isInt32Constant(codeBlock));
     
    442448    bool isNumberConstant(CodeBlock* codeBlock)
    443449    {
    444         bool result = isConstant() && valueOfJSConstant(codeBlock).isNumber();
     450        bool result = isConstant() && valueOfJSConstantNode(codeBlock).isNumber();
    445451        ASSERT(result == (isInt32Constant(codeBlock) || isDoubleConstant(codeBlock)));
    446452        return result;
     
    449455    bool isBooleanConstant(CodeBlock* codeBlock)
    450456    {
    451         return isConstant() && valueOfJSConstant(codeBlock).isBoolean();
     457        return isConstant() && valueOfJSConstantNode(codeBlock).isBoolean();
    452458    }
    453459   
     
    656662    }
    657663   
    658     bool predict(PredictedType prediction, PredictionSource source)
     664    bool predict(PredictedType prediction)
    659665    {
    660666        ASSERT(hasPrediction());
    661667       
    662         // We have previously found empirically that ascribing static predictions
    663         // to heap loads as well as calls is not profitable, as these predictions
    664         // are wrong too often. Hence, this completely ignores static predictions.
    665         if (source == WeakPrediction)
    666             return false;
    667        
    668         if (prediction == PredictNone)
    669             return false;
    670        
    671         ASSERT(source == StrongPrediction);
    672        
    673         return mergePrediction(m_opInfo2, makePrediction(prediction, source));
     668        return mergePrediction(m_opInfo2, prediction);
    674669    }
    675670   
     
    804799
    805800private:
    806     // This is private because it only works for the JSConstant op. The DFG is written under the
    807     // assumption that "valueOfJSConstant" can correctly return a constant for any DFG node for
    808     // which hasConstant() is true.
    809     JSValue valueOfJSConstant(CodeBlock* codeBlock)
    810     {
    811         return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
    812     }
    813 
    814801    // The virtual register number (spill location) associated with this .
    815802    VirtualRegister m_virtualRegister;
  • trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp

    r95916 r95930  
    4848        m_predictions.resize(m_graph.size());
    4949       
    50         // Uses is a backward flow property that propagates the hard expectations at
    51         // certain uses to their value sources, ensuring that predictions about
    52         // values do not contravene the code itself. This comes up only in the
    53         // cases of obvious cell uses, like GetById and friends as well as Call.
    54         // We're essentially statically speculating that if the value profile indicates
    55         // that only booleans (for example) flow into a GetById, then the value
    56         // profile is simply wrong due to insufficient coverage and needs to be
    57         // adjusted accordingly. The alternatives would be to assume either
    58         // that the GetById never executes, or always executes on a boolean leading
    59         // to whatever bizarre behavior that's supposed to cause.
    60         m_uses.resize(m_graph.size());
    61         m_variableUses.initializeSimilarTo(m_graph.predictions());
    62        
    6350        // Replacements are used to implement local common subexpression elimination.
    6451        m_replacements.resize(m_graph.size());
     
    6653        for (unsigned i = 0; i < m_graph.size(); ++i) {
    6754            m_predictions[i] = PredictNone;
    68             m_uses[i] = PredictNone;
    6955            m_replacements[i] = NoNode;
    7056        }
     
    307293    }
    308294   
    309     bool mergeUse(NodeIndex nodeIndex, PredictedType prediction)
    310     {
    311         ASSERT(m_graph[nodeIndex].hasResult());
    312        
    313         return JSC::mergePrediction(m_uses[nodeIndex], prediction);
    314     }
    315    
    316295    bool mergePrediction(PredictedType prediction)
    317296    {
     
    336315        switch (op) {
    337316        case JSConstant: {
    338             changed |= setPrediction(makePrediction(predictionFromValue(m_graph.valueOfJSConstant(m_codeBlock, m_compileIndex)), StrongPrediction));
     317            changed |= setPrediction(predictionFromValue(m_graph.valueOfJSConstant(m_codeBlock, m_compileIndex)));
    339318            break;
    340319        }
    341320           
    342321        case GetLocal: {
    343             changed |= m_graph.predict(node.local(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    344             changed |= m_variableUses.predict(node.local(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    345 
    346322            PredictedType prediction = m_graph.getPrediction(node.local());
    347             if (isStrongPrediction(prediction))
     323            if (prediction)
    348324                changed |= mergePrediction(prediction);
    349325            break;
     
    351327           
    352328        case SetLocal: {
    353             changed |= m_graph.predict(node.local(), m_predictions[node.child1()] & ~PredictionTagMask, StrongPrediction);
    354             changed |= mergeUse(node.child1(), m_variableUses.getPrediction(node.local()));
     329            changed |= m_graph.predict(node.local(), m_predictions[node.child1()]);
    355330            break;
    356331        }
     
    363338        case BitURShift:
    364339        case ValueToInt32: {
    365             changed |= setPrediction(makePrediction(PredictInt32, StrongPrediction));
     340            changed |= setPrediction(PredictInt32);
    366341            break;
    367342        }
     
    371346            PredictedType right = m_predictions[node.child2()];
    372347           
    373             if (isStrongPrediction(left) && isStrongPrediction(right)) {
     348            if (left && right) {
    374349                if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
    375                     changed |= mergePrediction(makePrediction(PredictInt32, StrongPrediction));
     350                    changed |= mergePrediction(PredictInt32);
    376351                else
    377                     changed |= mergePrediction(makePrediction(PredictDouble, StrongPrediction));
     352                    changed |= mergePrediction(PredictDouble);
    378353            }
    379354            break;
     
    382357        case UInt32ToNumber: {
    383358            if (nodeCanSpeculateInteger(node.arithNodeFlags()))
    384                 changed |= setPrediction(makePrediction(PredictInt32, StrongPrediction));
     359                changed |= setPrediction(PredictInt32);
    385360            else
    386                 changed |= setPrediction(makePrediction(PredictNumber, StrongPrediction));
     361                changed |= setPrediction(PredictNumber);
    387362            break;
    388363        }
     
    391366            PredictedType prediction = m_predictions[node.child1()];
    392367           
    393             if (isStrongPrediction(prediction)) {
     368            if (prediction) {
    394369                if (!(prediction & PredictDouble) && nodeCanSpeculateInteger(node.arithNodeFlags()))
    395                     changed |= mergePrediction(makePrediction(PredictInt32, StrongPrediction));
     370                    changed |= mergePrediction(PredictInt32);
    396371                else
    397                     changed |= mergePrediction(makePrediction(PredictNumber, StrongPrediction));
     372                    changed |= mergePrediction(PredictNumber);
    398373            }
    399374           
     
    412387            PredictedType right = m_predictions[node.child2()];
    413388           
    414             if (isStrongPrediction(left) && isStrongPrediction(right)) {
     389            if (left && right) {
    415390                if (isNumberPrediction(left) && isNumberPrediction(right)) {
    416391                    if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
    417                         changed |= mergePrediction(makePrediction(PredictInt32, StrongPrediction));
     392                        changed |= mergePrediction(PredictInt32);
    418393                    else
    419                         changed |= mergePrediction(makePrediction(PredictDouble, StrongPrediction));
     394                        changed |= mergePrediction(PredictDouble);
    420395                } else if (!(left & PredictNumber) || !(right & PredictNumber)) {
    421396                    // left or right is definitely something other than a number.
    422                     changed |= mergePrediction(makePrediction(PredictString, StrongPrediction));
     397                    changed |= mergePrediction(PredictString);
    423398                } else
    424                     changed |= mergePrediction(makePrediction(PredictString | PredictInt32 | PredictDouble, StrongPrediction));
     399                    changed |= mergePrediction(PredictString | PredictInt32 | PredictDouble);
    425400            }
    426401            break;
     
    436411            PredictedType right = m_predictions[node.child2()];
    437412           
    438             if (isStrongPrediction(left) && isStrongPrediction(right)) {
     413            if (left && right) {
    439414                if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags()))
    440                     changed |= mergePrediction(makePrediction(PredictInt32, StrongPrediction));
     415                    changed |= mergePrediction(PredictInt32);
    441416                else
    442                     changed |= mergePrediction(makePrediction(PredictDouble, StrongPrediction));
     417                    changed |= mergePrediction(PredictDouble);
    443418            }
    444419            break;
     
    446421           
    447422        case ArithSqrt: {
    448             changed |= setPrediction(makePrediction(PredictDouble, StrongPrediction));
     423            changed |= setPrediction(PredictDouble);
    449424            break;
    450425        }
     
    452427        case ArithAbs: {
    453428            PredictedType child = m_predictions[node.child1()];
    454             if (isStrongPrediction(child)) {
     429            if (child) {
    455430                if (nodeCanSpeculateInteger(node.arithNodeFlags()))
    456431                    changed |= mergePrediction(child);
    457432                else
    458                     changed |= setPrediction(makePrediction(PredictDouble, StrongPrediction));
     433                    changed |= setPrediction(PredictDouble);
    459434            }
    460435            break;
     
    469444        case CompareStrictEq:
    470445        case InstanceOf: {
    471             changed |= setPrediction(makePrediction(PredictBoolean, StrongPrediction));
     446            changed |= setPrediction(PredictBoolean);
    472447            break;
    473448        }
     
    476451        case GetMethod:
    477452        case GetByVal: {
    478             changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);
    479             changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    480             if (isStrongPrediction(node.getPrediction()))
     453            if (node.getPrediction())
    481454                changed |= mergePrediction(node.getPrediction());
    482455            break;
     
    484457           
    485458        case CheckStructure: {
    486             // We backward propagate what this CheckStructure tells us. Maybe that's the right way
    487             // to go; maybe it isn't. I'm not sure. What we'd really want is flow-sensitive
    488             // forward propagation of what we learn from having executed CheckStructure. But for
    489             // now we preserve the flow-insensitive nature of this analysis, because it's cheap to
    490             // run and seems to work well enough.
    491             changed |= mergeUse(node.child1(), predictionFromStructure(node.structure()) | StrongPredictionTag);
    492             changed |= setPrediction(PredictOther | StrongPredictionTag);
     459            changed |= setPrediction(PredictOther);
    493460            break;
    494461        }
    495462           
    496463        case GetByOffset: {
    497             changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    498             if (isStrongPrediction(node.getPrediction()))
     464            if (node.getPrediction())
    499465                changed |= mergePrediction(node.getPrediction());
    500466            break;
     
    502468           
    503469        case CheckMethod: {
    504             changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);
    505470            changed |= setPrediction(m_graph.getMethodCheckPrediction(node));
    506471            break;
     
    509474        case Call:
    510475        case Construct: {
    511             changed |= mergeUse(m_graph.m_varArgChildren[node.firstChild()], PredictObjectUnknown | StrongPredictionTag);
    512             changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    513             if (isStrongPrediction(node.getPrediction()))
     476            if (node.getPrediction())
    514477                changed |= mergePrediction(node.getPrediction());
    515478            break;
     
    517480           
    518481        case ConvertThis: {
    519             changed |= setPrediction(makePrediction(PredictObjectUnknown, StrongPrediction));
     482            changed |= setPrediction(PredictObjectUnknown);
    520483            break;
    521484        }
    522485           
    523486        case GetGlobalVar: {
    524             changed |= m_variableUses.predictGlobalVar(node.varNumber(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    525487            PredictedType prediction = m_graph.getGlobalVarPrediction(node.varNumber());
    526             if (isStrongPrediction(prediction))
     488            if (prediction)
    527489                changed |= mergePrediction(prediction);
    528490            break;
     
    530492           
    531493        case PutGlobalVar: {
    532             changed |= m_graph.predictGlobalVar(node.varNumber(), m_predictions[node.child1()] & ~PredictionTagMask, StrongPrediction);
    533             changed |= mergeUse(node.child1(), m_variableUses.getGlobalVarPrediction(node.varNumber()));
     494            changed |= m_graph.predictGlobalVar(node.varNumber(), m_predictions[node.child1()]);
    534495            break;
    535496        }
     
    540501        case ResolveBaseStrictPut:
    541502        case ResolveGlobal: {
    542             changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
    543503            PredictedType prediction = node.getPrediction();
    544             if (isStrongPrediction(prediction))
     504            if (prediction)
    545505                changed |= mergePrediction(prediction);
    546506            break;
     
    548508           
    549509        case GetScopeChain: {
    550             changed |= setPrediction(makePrediction(PredictCellOther, StrongPrediction));
    551             break;
    552         }
    553            
    554         case PutByVal:
    555         case PutByValAlias:
    556         case PutById:
    557         case PutByIdDirect: {
    558             changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);
    559             break;
    560         }
    561 
     510            changed |= setPrediction(PredictCellOther);
     511            break;
     512        }
     513           
    562514        case GetCallee: {
    563             changed |= setPrediction(makePrediction(PredictObjectOther, StrongPrediction));
     515            changed |= setPrediction(PredictObjectOther);
    564516            break;
    565517        }
    566518           
    567519        case CreateThis: {
    568             changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);
    569             changed |= setPrediction(makePrediction(PredictFinalObject, StrongPrediction));
     520            changed |= setPrediction(PredictFinalObject);
    570521            break;
    571522        }
    572523           
    573524        case StrCat: {
    574             changed |= setPrediction(makePrediction(PredictString, StrongPrediction));
     525            changed |= setPrediction(PredictString);
    575526            break;
    576527        }
     
    578529        case ToPrimitive: {
    579530            PredictedType child = m_predictions[node.child1()];
    580             if (isStrongPrediction(child)) {
     531            if (child) {
    581532                if (isObjectPrediction(child)) {
    582533                    // I'd love to fold this case into the case below, but I can't, because
     
    585536                    // (strong predict-none). This should be killed once we remove all traces
    586537                    // of static (aka weak) predictions.
    587                     changed |= mergePrediction(makePrediction(PredictString, StrongPrediction));
     538                    changed |= mergePrediction(PredictString);
    588539                } else if (child & PredictObjectMask) {
    589540                    // Objects get turned into strings. So if the input has hints of objectness,
    590541                    // the output will have hinsts of stringiness.
    591                     changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, makePrediction(PredictString, StrongPrediction)));
     542                    changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, PredictString));
    592543                } else
    593544                    changed |= mergePrediction(child);
     
    612563        // This gets ignored because it doesn't do anything.
    613564        case Phantom:
     565        case PutByVal:
     566        case PutByValAlias:
     567        case PutById:
     568        case PutByIdDirect:
    614569            break;
    615570#else
     
    620575
    621576#if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE)
    622         printf("expect(%s) ", predictionToString(m_predictions[m_compileIndex]));
    623         printf("use(%s) %s\n", predictionToString(m_uses[m_compileIndex]), changed ? "CHANGED" : "");
     577        printf("%s ", predictionToString(m_predictions[m_compileIndex]));
    624578#endif
    625579       
     
    677631            PredictedType right = m_predictions[node.child2()];
    678632           
    679             if (isStrongPrediction(left) && isStrongPrediction(right) && isNumberPrediction(left) && isNumberPrediction(right)) {
     633            if (left && right && isNumberPrediction(left) && isNumberPrediction(right)) {
    680634                if (left & PredictDouble)
    681635                    toDouble(node.child2());
     
    702656            PredictedType right = m_predictions[node.child2()];
    703657           
    704             if (isStrongPrediction(left) && isStrongPrediction(right)) {
     658            if (left && right) {
    705659                if (left & PredictDouble)
    706660                    toDouble(node.child2());
     
    718672           
    719673            PredictedType prediction = m_predictions[node.child1()];
    720             if (isStrongPrediction(prediction) && (prediction & PredictDouble))
     674            if (prediction & PredictDouble)
    721675                toDouble(node.child1());
    722676            break;
     
    867821        PredictedType left = m_predictions[node.child1()];
    868822        PredictedType right = m_predictions[node.child2()];
    869         return isStrongPrediction(left) && isStrongPrediction(right)
    870             && isNumberPrediction(left) && isNumberPrediction(right);
     823        return isNumberPrediction(left) && isNumberPrediction(right);
    871824    }
    872825   
     
    874827    {
    875828        PredictedType prediction = m_predictions[node.child1()];
    876         return isBooleanPrediction(prediction) || !isStrongPrediction(prediction);
     829        return isBooleanPrediction(prediction) || !prediction;
    877830    }
    878831   
     
    12331186   
    12341187    Vector<PredictedType, 16> m_predictions;
    1235     Vector<PredictedType, 16> m_uses;
    1236    
    1237     PredictionTracker m_variableUses;
    12381188
    12391189#if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r95916 r95930  
    696696
    697697    case GetLocal: {
     698        PredictedType prediction = m_jit.graph().getPrediction(node.local());
     699
     700        // If we have no prediction for this local, then don't attempt to compile.
     701        if (prediction == PredictNone) {
     702            terminateSpeculativeExecution();
     703            break;
     704        }
     705       
    698706        GPRTemporary result(this);
    699         PredictedType prediction = m_jit.graph().getPrediction(node.local());
    700707        if (isInt32Prediction(prediction)) {
    701708            m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
     
    13011308        }
    13021309       
    1303         PredictedType prediction = m_jit.graph().getPrediction(m_jit.graph()[node.child1()]);
    1304         if (isBooleanPrediction(prediction) || !isStrongPrediction(prediction)) {
     1310        PredictedType prediction = m_jit.getPrediction(node.child1());
     1311        if (isBooleanPrediction(prediction) || !prediction) {
    13051312            JSValueOperand value(this, node.child1());
    13061313            GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r95910 r95930  
    371371            return true;
    372372       
    373         if (isInt32Prediction(m_jit.graph().getPrediction(m_jit.graph()[nodeIndex])))
     373        if (isInt32Prediction(m_jit.getPrediction(nodeIndex)))
    374374            return true;
    375375       
     
    390390            return true;
    391391       
    392         if (isDoublePrediction(m_jit.graph().getPrediction(node)))
     392        if (isDoublePrediction(m_jit.getPrediction(nodeIndex)))
    393393            return true;
    394394       
     
    412412            return true;
    413413       
    414         PredictedType prediction = m_jit.graph().getPrediction(node);
     414        PredictedType prediction = m_jit.getPrediction(nodeIndex);
    415415       
    416416        if (isNumberPrediction(prediction) || prediction == PredictNone)
     
    433433            return true;
    434434       
    435         if (m_jit.graph().getPrediction(node) & PredictDouble)
     435        if (m_jit.getPrediction(nodeIndex) & PredictDouble)
    436436            return true;
    437437       
     
    445445            prediction = predictionFromValue(valueOfJSConstant(nodeIndex));
    446446        else
    447             prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]);
     447            prediction = m_jit.getPrediction(nodeIndex);
    448448        return isFinalObjectPrediction(prediction);
    449449    }
     
    455455            prediction = predictionFromValue(valueOfJSConstant(nodeIndex));
    456456        else
    457             prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]);
     457            prediction = m_jit.getPrediction(nodeIndex);
    458458        return isArrayPrediction(prediction);
    459459    }
     
    468468            prediction = predictionFromValue(valueOfJSConstant(nodeIndex));
    469469        else
    470             prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]);
     470            prediction = m_jit.getPrediction(nodeIndex);
    471471        return isObjectPrediction(prediction);
    472472    }
     
    479479        Node& node = m_jit.graph()[nodeIndex];
    480480
    481         if (isCellPrediction(m_jit.graph().getPrediction(node)))
     481        if (isCellPrediction(m_jit.getPrediction(nodeIndex)))
    482482            return true;
    483483
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r95916 r95930  
    555555#if ENABLE(VALUE_PROFILER)
    556556        ASSERT(m_bytecodeOffset == (unsigned)-1);
    557         for (int argumentRegister = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters + 1; argumentRegister < -RegisterFile::CallFrameHeaderSize; ++argumentRegister) {
    558             loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0);
    559             emitValueProfilingSite(FirstProfilingSite);
     557        if (shouldEmitProfiling()) {
     558            for (int argumentRegister = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters; argumentRegister < -RegisterFile::CallFrameHeaderSize; ++argumentRegister) {
     559                // If this is a constructor, then we want to put in a dummy profiling site (to
     560                // keep things consistent) but we don't actually want to record the dummy value.
     561                if (m_codeBlock->m_isConstructor
     562                    && argumentRegister == -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters)
     563                    m_codeBlock->addValueProfile(-1);
     564                else {
     565                    loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0);
     566                    emitValueProfilingSite(FirstProfilingSite);
     567                }
     568            }
    560569        }
    561570#endif
Note: See TracChangeset for help on using the changeset viewer.