Changeset 91894 in webkit


Ignore:
Timestamp:
Jul 27, 2011, 8:25:19 PM (14 years ago)
Author:
commit-queue@webkit.org
Message:

DFG graph has no notion of double prediction.
https://bugs.webkit.org/show_bug.cgi?id=65234

Patch by Filip Pizlo <fpizlo@apple.com> on 2011-07-27
Reviewed by Gavin Barraclough.

Added the notion of PredictDouble, and PredictNumber, which is the least
upper bound of PredictInt32 and PredictDouble. Least upper bound is
defined as the bitwise-or of two predictions. Bottom is defined as 0,
and Top is defined as all bits being set. Added the ability to explicitly
distinguish between a node having had a prediction associated with it,
and that prediction still being valid (i.e. no conflicting predictions
have also been added). Used this to guard the speculative JIT from
speculating Int32 in cases where the graph knows that the value is
double, which currently only happens for GetLocal nodes on arguments
which were double at compile-time.

  • dfg/DFGGraph.cpp:

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

  • dfg/DFGGraph.h:

(JSC::DFG::isCellPrediction):
(JSC::DFG::isArrayPrediction):
(JSC::DFG::isInt32Prediction):
(JSC::DFG::isDoublePrediction):
(JSC::DFG::isNumberPrediction):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::initializeVariableTypes):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::isRegisterDataFormatDouble):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r91883 r91894  
     12011-07-27  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG graph has no notion of double prediction.
     4        https://bugs.webkit.org/show_bug.cgi?id=65234
     5
     6        Reviewed by Gavin Barraclough.
     7       
     8        Added the notion of PredictDouble, and PredictNumber, which is the least
     9        upper bound of PredictInt32 and PredictDouble.  Least upper bound is
     10        defined as the bitwise-or of two predictions.  Bottom is defined as 0,
     11        and Top is defined as all bits being set.  Added the ability to explicitly
     12        distinguish between a node having had a prediction associated with it,
     13        and that prediction still being valid (i.e. no conflicting predictions
     14        have also been added).  Used this to guard the speculative JIT from
     15        speculating Int32 in cases where the graph knows that the value is
     16        double, which currently only happens for GetLocal nodes on arguments
     17        which were double at compile-time.
     18
     19        * dfg/DFGGraph.cpp:
     20        (JSC::DFG::Graph::predictArgumentTypes):
     21        * dfg/DFGGraph.h:
     22        (JSC::DFG::isCellPrediction):
     23        (JSC::DFG::isArrayPrediction):
     24        (JSC::DFG::isInt32Prediction):
     25        (JSC::DFG::isDoublePrediction):
     26        (JSC::DFG::isNumberPrediction):
     27        * dfg/DFGSpeculativeJIT.cpp:
     28        (JSC::DFG::SpeculativeJIT::compile):
     29        (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
     30        (JSC::DFG::SpeculativeJIT::initializeVariableTypes):
     31        * dfg/DFGSpeculativeJIT.h:
     32        (JSC::DFG::SpeculativeJIT::isRegisterDataFormatDouble):
     33
    1342011-07-27  Gavin Barraclough  <barraclough@apple.com>
    235
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r91115 r91894  
    182182
    183183    for (size_t arg = 1; arg < numberOfArguments; ++arg) {
    184         if (exec->argument(arg - 1).isInt32())
     184        JSValue argumentValue = exec->argument(arg - 1);
     185        if (argumentValue.isInt32())
    185186            m_argumentPredictions[arg].m_value |= PredictInt32;
     187        else if (argumentValue.isDouble())
     188            m_argumentPredictions[arg].m_value |= PredictDouble;
    186189    }
    187190}
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r91131 r91894  
    4545
    4646typedef uint8_t PredictedType;
    47 static const PredictedType PredictNone  = 0;
    48 static const PredictedType PredictCell  = 0x01;
    49 static const PredictedType PredictArray = 0x03;
    50 static const PredictedType PredictInt32 = 0x04;
     47static const PredictedType PredictNone   = 0;
     48static const PredictedType PredictCell   = 0x01;
     49static const PredictedType PredictArray  = 0x03;
     50static const PredictedType PredictInt32  = 0x04;
     51static const PredictedType PredictDouble = 0x08;
     52static const PredictedType PredictNumber = 0x0c;
     53
     54inline bool isCellPrediction(PredictedType value)
     55{
     56    return (value & PredictCell) == PredictCell && !(value & ~PredictArray);
     57}
     58
     59inline bool isArrayPrediction(PredictedType value)
     60{
     61    return value == PredictArray;
     62}
     63
     64inline bool isInt32Prediction(PredictedType value)
     65{
     66    return value == PredictInt32;
     67}
     68
     69inline bool isDoublePrediction(PredictedType value)
     70{
     71    return value == PredictDouble;
     72}
     73
     74inline bool isNumberPrediction(PredictedType value)
     75{
     76    return !!(value & PredictNumber) && !(value & ~PredictNumber);
     77}
    5178
    5279struct PredictionSlot {
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r91807 r91894  
    538538        GPRTemporary result(this);
    539539        PredictedType prediction = m_jit.graph().getPrediction(node.local());
    540         if (prediction == PredictInt32) {
     540        if (isInt32Prediction(prediction)) {
    541541            m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
    542542
     
    553553            VirtualRegister virtualRegister = node.virtualRegister();
    554554            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
    555             m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), (prediction == PredictArray) ? DataFormatJSCell : DataFormatJS);
     555            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), isArrayPrediction(prediction) ? DataFormatJSCell : DataFormatJS);
    556556        }
    557557        break;
     
    559559
    560560    case SetLocal: {
    561         switch (m_jit.graph().getPrediction(node.local())) {
    562         case PredictInt32: {
     561        PredictedType predictedType = m_jit.graph().getPrediction(node.local());
     562        if (isInt32Prediction(predictedType)) {
    563563            SpeculateIntegerOperand value(this, node.child1());
    564564            m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
    565565            noResult(m_compileIndex);
    566             break;
    567         }
    568         case PredictArray: {
     566        } else if (isArrayPrediction(predictedType)) {
    569567            SpeculateCellOperand cell(this, node.child1());
    570568            GPRReg cellGPR = cell.gpr();
     
    572570            m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
    573571            noResult(m_compileIndex);
    574             break;
    575         }
    576 
    577         default: {
     572        } else {
    578573            JSValueOperand value(this, node.child1());
    579574            m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
    580575            noResult(m_compileIndex);
    581             break;
    582         }
    583576        }
    584577        break;
     
    919912        // If we have predicted the base to be type array, we can skip the check.
    920913        Node& baseNode = m_jit.graph()[node.child1()];
    921         if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
     914        if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
    922915            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
    923916        speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
     
    954947        // If we have predicted the base to be type array, we can skip the check.
    955948        Node& baseNode = m_jit.graph()[node.child1()];
    956         if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
     949        if (baseNode.op != GetLocal || isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
    957950            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
    958951
     
    13061299    for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
    13071300        VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i);
    1308         switch (m_jit.graph().getPrediction(virtualRegister)) {
    1309         case PredictInt32:
     1301        PredictedType predictedType = m_jit.graph().getPrediction(virtualRegister);
     1302        if (isInt32Prediction(predictedType))
    13101303            speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
    1311             break;
    1312 
    1313         case PredictArray: {
     1304        else if (isArrayPrediction(predictedType)) {
    13141305            GPRTemporary temp(this);
    13151306            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
    13161307            speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
    13171308            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
    1318             break;
    1319         }
    1320 
    1321         default:
    1322             break;
    13231309        }
    13241310    }
     
    13331319    ASSERT(!m_compileIndex);
    13341320    for (int var = 0; var < m_jit.codeBlock()->m_numVars; ++var) {
    1335         if (m_jit.graph().getPrediction(var) == PredictInt32)
     1321        if (isInt32Prediction(m_jit.graph().getPrediction(var)))
    13361322            m_jit.storePtr(GPRInfo::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var));
    13371323    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r91807 r91894  
    163163        GenerationInfo& info = m_generationInfo[virtualRegister];
    164164
    165         return (info.registerFormat() | DataFormatJS) == DataFormatJSDouble;
     165        if ((info.registerFormat() | DataFormatJS) == DataFormatJSDouble
     166            || (info.spillFormat() | DataFormatJS) == DataFormatJSDouble)
     167            return true;
     168       
     169        if (node.op == GetLocal && isDoublePrediction(m_jit.graph().getPrediction(node.local())))
     170            return true;
     171       
     172        return false;
    166173    }
    167174   
Note: See TracChangeset for help on using the changeset viewer.