Changeset 96415 in webkit


Ignore:
Timestamp:
Sep 30, 2011 1:01:38 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Merge some more of DFGSpeculativeJIT 32_64/64
https://bugs.webkit.org/show_bug.cgi?id=69164

Reviewed by Oliver Hunt.

  • dfg/DFGJITCodeGenerator.h:
  • dfg/DFGJITCodeGenerator32_64.cpp:
  • dfg/DFGJITCodeGenerator64.cpp:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):

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

(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::compile):

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r96406 r96415  
     12011-09-30  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Merge some more of DFGSpeculativeJIT 32_64/64
     4        https://bugs.webkit.org/show_bug.cgi?id=69164
     5
     6        Reviewed by Oliver Hunt.
     7
     8        * dfg/DFGJITCodeGenerator.h:
     9        * dfg/DFGJITCodeGenerator32_64.cpp:
     10        * dfg/DFGJITCodeGenerator64.cpp:
     11        * dfg/DFGSpeculativeJIT.cpp:
     12        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
     13        * dfg/DFGSpeculativeJIT.h:
     14        * dfg/DFGSpeculativeJIT32_64.cpp:
     15        (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
     16        (JSC::DFG::SpeculativeJIT::compare):
     17        (JSC::DFG::SpeculativeJIT::compileValueAdd):
     18        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     19        (JSC::DFG::SpeculativeJIT::compile):
     20        * dfg/DFGSpeculativeJIT64.cpp:
     21        (JSC::DFG::SpeculativeJIT::compare):
     22        (JSC::DFG::SpeculativeJIT::compileValueAdd):
     23        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     24        (JSC::DFG::SpeculativeJIT::compile):
     25
    1262011-09-30  Mark Hahnenberg  <mhahnenberg@apple.com>
    227
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h

    r96391 r96415  
    780780    void emitBranch(Node&);
    781781   
    782     void nonSpeculativeLogicalNot(Node&);
    783    
    784782    MacroAssembler::Address addressOfCallData(int idx)
    785783    {
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp

    r96391 r96415  
    15551555}
    15561556
    1557 void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)
    1558 {
    1559     JSValueOperand arg1(this, node.child1());
    1560     GPRTemporary resultTag(this, arg1);
    1561     GPRTemporary resultPayload(this, arg1, false);
    1562     GPRReg arg1TagGPR = arg1.tagGPR();
    1563     GPRReg arg1PayloadGPR = arg1.payloadGPR();
    1564     GPRReg resultTagGPR = resultTag.gpr();
    1565     GPRReg resultPayloadGPR = resultPayload.gpr();
    1566        
    1567     arg1.use();
    1568 
    1569     JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
    1570        
    1571     silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
    1572     m_jit.push(arg1TagGPR);
    1573     m_jit.push(arg1PayloadGPR);
    1574     m_jit.push(GPRInfo::callFrameRegister);
    1575     appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1576     m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);
    1577     silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
    1578     JITCompiler::Jump doNot = m_jit.jump();
    1579        
    1580     fastCase.link(&m_jit);
    1581     m_jit.move(arg1PayloadGPR, resultPayloadGPR);
    1582 
    1583     doNot.link(&m_jit);
    1584     m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
    1585     m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);
    1586     jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1587 }
    1588 
    15891557void JITCodeGenerator::emitCall(Node& node)
    15901558{
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp

    r96377 r96415  
    15261526}
    15271527
    1528 void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)
    1529 {
    1530     JSValueOperand arg1(this, node.child1());
    1531     GPRTemporary result(this);
    1532    
    1533     GPRReg arg1GPR = arg1.gpr();
    1534     GPRReg resultGPR = result.gpr();
    1535    
    1536     arg1.use();
    1537    
    1538     m_jit.move(arg1GPR, resultGPR);
    1539     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
    1540     JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
    1541    
    1542     silentSpillAllRegisters(resultGPR);
    1543     m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
    1544     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1545     appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1546     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1547     silentFillAllRegisters(resultGPR);
    1548    
    1549     fastCase.link(&m_jit);
    1550    
    1551     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
    1552     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1553 }
    1554 
    15551528void JITCodeGenerator::emitCall(Node& node)
    15561529{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r96379 r96415  
    193193    if (notTaken != (m_block + 1))
    194194        addBranch(m_jit.jump(), notTaken);
     195}
     196
     197// Returns true if the compare is fused with a subsequent branch.
     198bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
     199{
     200    // Fused compare & branch.
     201    NodeIndex branchNodeIndex = detectPeepHoleBranch();
     202    if (branchNodeIndex != NoNode) {
     203        // detectPeepHoleBranch currently only permits the branch to be the very next node,
     204        // so can be no intervening nodes to also reference the compare.
     205        ASSERT(node.adjustedRefCount() == 1);
     206
     207        if (shouldSpeculateInteger(node.child1(), node.child2())) {
     208            compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
     209            use(node.child1());
     210            use(node.child2());
     211        } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
     212            compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
     213            use(node.child1());
     214            use(node.child2());
     215        } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
     216            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
     217            use(node.child1());
     218            use(node.child2());
     219        } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
     220            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
     221            use(node.child1());
     222            use(node.child2());
     223        } else
     224            nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
     225
     226        m_compileIndex = branchNodeIndex;
     227        return true;
     228    }
     229    return false;
    195230}
    196231
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r96379 r96415  
    571571   
    572572    bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
     573    bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
    573574    void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
    574575    void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
    575576    void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, void* vptr);
    576577    void compileObjectEquality(Node&, void* vptr);
     578    void compileValueAdd(Node&);
     579    void compileLogicalNot(Node&);
    577580   
    578581    // It is acceptable to have structure be equal to scratch, so long as you're fine
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r96389 r96415  
    102102    case DataFormatBoolean:
    103103    case DataFormatJSDouble:
    104     case DataFormatJSCell: 
     104    case DataFormatJSCell:
    105105    case DataFormatJSBoolean: {
    106106        terminateSpeculativeExecution();
     
    374374bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
    375375{
    376     // Fused compare & branch.
    377     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    378     if (branchNodeIndex != NoNode) {
    379         // detectPeepHoleBranch currently only permits the branch to be the very next node,
    380         // so can be no intervening nodes to also reference the compare.
    381         ASSERT(node.adjustedRefCount() == 1);
    382 
    383         if (shouldSpeculateInteger(node.child1(), node.child2())) {
    384             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
    385             use(node.child1());
    386             use(node.child2());
    387         } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
    388             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
    389             use(node.child1());
    390             use(node.child2());
    391         } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
    392             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
    393             use(node.child1());
    394             use(node.child2());
    395         } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
    396             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
    397             use(node.child1());
    398             use(node.child2());
    399         } else
    400             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
    401 
    402         m_compileIndex = branchNodeIndex;
     376    if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
    403377        return true;
    404     }
    405378
    406379    if (shouldSpeculateFinalObject(node.child1(), node.child2()))
     
    441414}
    442415
     416void SpeculativeJIT::compileValueAdd(Node& node)
     417{
     418    JSValueOperand op1(this, node.child1());
     419    JSValueOperand op2(this, node.child2());
     420
     421    GPRReg op1TagGPR = op1.tagGPR();
     422    GPRReg op1PayloadGPR = op1.payloadGPR();
     423    GPRReg op2TagGPR = op2.tagGPR();
     424    GPRReg op2PayloadGPR = op2.payloadGPR();
     425
     426    flushRegisters();
     427   
     428    GPRResult2 resultTag(this);
     429    GPRResult resultPayload(this);
     430    if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
     431        callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
     432    else
     433        callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
     434   
     435    jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
     436}
     437
     438void SpeculativeJIT::compileLogicalNot(Node& node)
     439{
     440    // FIXME: Need to add fast paths for known booleans.
     441    JSValueOperand value(this, node.child1());
     442    GPRTemporary resultTag(this, value);
     443    GPRTemporary resultPayload(this, value, false);
     444    speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));
     445    m_jit.move(value.payloadGPR(), resultPayload.gpr());
     446    m_jit.xor32(TrustedImm32(1), resultPayload.gpr());
     447    m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
     448
     449    // If we add a DataFormatBool, we should use it here.
     450    jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
     451
     452    // This code is moved from nonSpeculativeLogicalNot, currently unused!
     453#if 0
     454    JSValueOperand arg1(this, node.child1());
     455    GPRTemporary resultTag(this, arg1);
     456    GPRTemporary resultPayload(this, arg1, false);
     457    GPRReg arg1TagGPR = arg1.tagGPR();
     458    GPRReg arg1PayloadGPR = arg1.payloadGPR();
     459    GPRReg resultTagGPR = resultTag.gpr();
     460    GPRReg resultPayloadGPR = resultPayload.gpr();
     461       
     462    arg1.use();
     463
     464    JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
     465       
     466    silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
     467    m_jit.push(arg1TagGPR);
     468    m_jit.push(arg1PayloadGPR);
     469    m_jit.push(GPRInfo::callFrameRegister);
     470    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
     471    m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);
     472    silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
     473    JITCompiler::Jump doNot = m_jit.jump();
     474       
     475    fastCase.link(&m_jit);
     476    m_jit.move(arg1PayloadGPR, resultPayloadGPR);
     477
     478    doNot.link(&m_jit);
     479    m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
     480    m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);
     481    jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
     482#endif
     483}
     484
    443485void SpeculativeJIT::compile(Node& node)
    444486{
     
    460502       
    461503        GPRTemporary result(this);
    462         VirtualRegister virtualRegister = node.virtualRegister();
    463         m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
    464504        if (isInt32Prediction(prediction)) {
     505            m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
     506
    465507            // Like integerResult, but don't useChildren - our children are phi nodes,
    466508            // and don't represent values within this dataflow with virtual registers.
     509            VirtualRegister virtualRegister = node.virtualRegister();
    467510            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
    468511            m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
    469         } else {
    470             // Like jsValueResult, but don't useChildren - our children are phi nodes,
    471             // and don't represent values within this dataflow with virtual registers.
    472             GPRTemporary tag(this);
    473             m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
    474             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
    475             m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
    476 
    477             DataFormat format;
    478             if (isArrayPrediction(prediction))
    479                 format = DataFormatJSCell;
    480             else if (isBooleanPrediction(prediction))
    481                 format = DataFormatJSBoolean;
    482             else
    483                 format = DataFormatJS;
    484 
    485             m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
    486         }
     512            break;
     513        }
     514
     515        GPRTemporary tag(this);
     516        m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
     517        m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
     518
     519        // Like jsValueResult, but don't useChildren - our children are phi nodes,
     520        // and don't represent values within this dataflow with virtual registers.
     521        VirtualRegister virtualRegister = node.virtualRegister();
     522        m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
     523        m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
     524
     525        DataFormat format;
     526        if (isArrayPrediction(prediction))
     527            format = DataFormatJSCell;
     528        else if (isBooleanPrediction(prediction))
     529            format = DataFormatJSBoolean;
     530        else
     531            format = DataFormatJS;
     532
     533        m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
    487534        break;
    488535    }
     
    617664            IntegerOperand op1(this, node.child1());
    618665            FPRTemporary result(this);
    619             GPRTemporary address(this, op1);
    620666           
    621667            GPRReg inputGPR = op1.gpr();
    622668            FPRReg outputFPR = result.fpr();
    623             GPRReg addressGPR = address.gpr();
    624669           
    625670            m_jit.convertInt32ToDouble(inputGPR, outputFPR);
    626671           
    627672            JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
    628             m_jit.move(JITCompiler::TrustedImmPtr(&twoToThe32), addressGPR);
    629             m_jit.addDouble(JITCompiler::Address(addressGPR, 0), outputFPR);
     673            m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR);
    630674            positive.link(&m_jit);
    631675           
     
    765809
    766810        ASSERT(op == ValueAdd);
    767 
    768         JSValueOperand op1(this, node.child1());
    769         JSValueOperand op2(this, node.child2());
    770 
    771         GPRReg op1TagGPR = op1.tagGPR();
    772         GPRReg op1PayloadGPR = op1.payloadGPR();
    773         GPRReg op2TagGPR = op2.tagGPR();
    774         GPRReg op2PayloadGPR = op2.payloadGPR();
    775 
    776         flushRegisters();
    777        
    778         GPRResult2 resultTag(this);
    779         GPRResult resultPayload(this);
    780         if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
    781             callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
    782         else
    783             callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
    784        
    785         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
     811        compileValueAdd(node);
    786812        break;
    787813    }
     
    10631089    }
    10641090
    1065     case LogicalNot: {
    1066         // FIXME: Need to add fast paths for known booleans.
    1067         JSValueOperand value(this, node.child1());
    1068         GPRTemporary resultTag(this, value);
    1069         GPRTemporary resultPayload(this, value, false);
    1070         speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));
    1071         m_jit.move(value.payloadGPR(), resultPayload.gpr());
    1072         m_jit.xor32(TrustedImm32(1), resultPayload.gpr());
    1073         m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
    1074 
    1075         // If we add a DataFormatBool, we should use it here.
    1076         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
    1077         break;
    1078     }
     1091    case LogicalNot:
     1092        compileLogicalNot(node);
     1093        break;
    10791094
    10801095    case CompareLess:
     
    11571172        SpeculateStrictInt32Operand property(this, node.child2());
    11581173        JSValueOperand value(this, node.child3());
    1159         GPRTemporary scratch(this, base);
     1174        GPRTemporary scratch(this);
    11601175
    11611176        // Map base, property & value into registers, allocate a scratch register.
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r96389 r96415  
    477477bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
    478478{
    479     // Fused compare & branch.
    480     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    481     if (branchNodeIndex != NoNode) {
    482         // detectPeepHoleBranch currently only permits the branch to be the very next node,
    483         // so can be no intervening nodes to also reference the compare.
    484         ASSERT(node.adjustedRefCount() == 1);
    485 
    486         if (shouldSpeculateInteger(node.child1(), node.child2())) {
    487             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
    488             use(node.child1());
    489             use(node.child2());
    490         } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
    491             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
    492             use(node.child1());
    493             use(node.child2());
    494         } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
    495             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
    496             use(node.child1());
    497             use(node.child2());
    498         } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
    499             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
    500             use(node.child1());
    501             use(node.child2());
    502         } else
    503             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
    504 
    505         m_compileIndex = branchNodeIndex;
     479    if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
    506480        return true;
    507     }
    508481
    509482    if (shouldSpeculateInteger(node.child1(), node.child2())) {
     
    538511}
    539512
     513void SpeculativeJIT::compileValueAdd(Node& node)
     514{
     515    JSValueOperand op1(this, node.child1());
     516    JSValueOperand op2(this, node.child2());
     517   
     518    GPRReg op1GPR = op1.gpr();
     519    GPRReg op2GPR = op2.gpr();
     520   
     521    flushRegisters();
     522   
     523    GPRResult result(this);
     524    if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
     525        callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
     526    else
     527        callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
     528   
     529    jsValueResult(result.gpr(), m_compileIndex);
     530}
     531
     532void SpeculativeJIT::compileLogicalNot(Node& node)
     533{
     534    if (isKnownBoolean(node.child1())) {
     535        SpeculateBooleanOperand value(this, node.child1());
     536        GPRTemporary result(this, value);
     537       
     538        m_jit.move(value.gpr(), result.gpr());
     539        m_jit.xorPtr(TrustedImm32(true), result.gpr());
     540       
     541        jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
     542        return;
     543    }
     544   
     545    PredictedType prediction = m_jit.getPrediction(node.child1());
     546    if (isBooleanPrediction(prediction) || !prediction) {
     547        JSValueOperand value(this, node.child1());
     548        GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
     549       
     550        m_jit.move(value.gpr(), result.gpr());
     551        m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
     552        speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
     553        m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
     554       
     555        // If we add a DataFormatBool, we should use it here.
     556        jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
     557        return;
     558    }
     559   
     560    JSValueOperand arg1(this, node.child1());
     561    GPRTemporary result(this);
     562   
     563    GPRReg arg1GPR = arg1.gpr();
     564    GPRReg resultGPR = result.gpr();
     565   
     566    arg1.use();
     567   
     568    m_jit.move(arg1GPR, resultGPR);
     569    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
     570    JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
     571   
     572    silentSpillAllRegisters(resultGPR);
     573    m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
     574    m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     575    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
     576    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
     577    silentFillAllRegisters(resultGPR);
     578   
     579    fastCase.link(&m_jit);
     580   
     581    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
     582    jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
     583}
     584
    540585void SpeculativeJIT::compile(Node& node)
    541586{
     
    565610            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
    566611            m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
    567         } else {
    568             m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
    569 
    570             // Like jsValueResult, but don't useChildren - our children are phi nodes,
    571             // and don't represent values within this dataflow with virtual registers.
    572             VirtualRegister virtualRegister = node.virtualRegister();
    573             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
    574            
    575             DataFormat format;
    576             if (isArrayPrediction(prediction))
    577                 format = DataFormatJSCell;
    578             else if (isBooleanPrediction(prediction))
    579                 format = DataFormatJSBoolean;
    580             else
    581                 format = DataFormatJS;
    582 
    583             m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
    584         }
     612            break;
     613        }
     614
     615        m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
     616
     617        // Like jsValueResult, but don't useChildren - our children are phi nodes,
     618        // and don't represent values within this dataflow with virtual registers.
     619        VirtualRegister virtualRegister = node.virtualRegister();
     620        m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
     621
     622        DataFormat format;
     623        if (isArrayPrediction(prediction))
     624            format = DataFormatJSCell;
     625        else if (isBooleanPrediction(prediction))
     626            format = DataFormatJSBoolean;
     627        else
     628            format = DataFormatJS;
     629
     630        m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
    585631        break;
    586632    }
     
    863909
    864910        ASSERT(op == ValueAdd);
    865 
    866         JSValueOperand op1(this, node.child1());
    867         JSValueOperand op2(this, node.child2());
    868        
    869         GPRReg op1GPR = op1.gpr();
    870         GPRReg op2GPR = op2.gpr();
    871        
    872         flushRegisters();
    873        
    874         GPRResult result(this);
    875         if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
    876             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
    877         else
    878             callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
    879        
    880         jsValueResult(result.gpr(), m_compileIndex);
     911        compileValueAdd(node);
    881912        break;
    882913    }
     
    11581189    }
    11591190
    1160     case LogicalNot: {
    1161         if (isKnownBoolean(node.child1())) {
    1162             SpeculateBooleanOperand value(this, node.child1());
    1163             GPRTemporary result(this, value);
    1164            
    1165             m_jit.move(value.gpr(), result.gpr());
    1166             m_jit.xorPtr(TrustedImm32(true), result.gpr());
    1167            
    1168             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
    1169             break;
    1170         }
    1171        
    1172         PredictedType prediction = m_jit.getPrediction(node.child1());
    1173         if (isBooleanPrediction(prediction) || !prediction) {
    1174             JSValueOperand value(this, node.child1());
    1175             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
    1176            
    1177             m_jit.move(value.gpr(), result.gpr());
    1178             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
    1179             speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
    1180             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
    1181            
    1182             // If we add a DataFormatBool, we should use it here.
    1183             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
    1184             break;
    1185         }
    1186        
    1187         nonSpeculativeLogicalNot(node);
    1188        
    1189         break;
    1190     }
     1191    case LogicalNot:
     1192        compileLogicalNot(node);
     1193        break;
    11911194
    11921195    case CompareLess:
Note: See TracChangeset for help on using the changeset viewer.