Changeset 96661 in webkit


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

JITCodeGenerator should no longer have code that tries too hard
to be both speculative and non-speculative
https://bugs.webkit.org/show_bug.cgi?id=69321

Reviewed by Gavin Barraclough.

Removed m_isSpeculative and speculationCheck() from JITCodeGenerator.
This required moving emitBranch() to SpeculativeJIT, since it was
the main user of that field and method. Other than trvial clean-ups
in emitBranch(), the code is unchanged (and still has some disparity
between 64 and 32_64, and still lacks some obvious optimizations).

  • dfg/DFGJITCodeGenerator.cpp:
  • dfg/DFGJITCodeGenerator.h:

(JSC::DFG::JITCodeGenerator::JITCodeGenerator):

  • dfg/DFGJITCodeGenerator32_64.cpp:

(JSC::DFG::JITCodeGenerator::fillDouble):
(JSC::DFG::JITCodeGenerator::fillJSValue):

  • dfg/DFGJITCodeGenerator64.cpp:

(JSC::DFG::JITCodeGenerator::fillDouble):
(JSC::DFG::JITCodeGenerator::fillJSValue):

  • dfg/DFGSpeculativeJIT.h:

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

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::emitBranch):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::emitBranch):

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r96643 r96661  
     12011-10-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JITCodeGenerator should no longer have code that tries too hard
     4        to be both speculative and non-speculative
     5        https://bugs.webkit.org/show_bug.cgi?id=69321
     6
     7        Reviewed by Gavin Barraclough.
     8       
     9        Removed m_isSpeculative and speculationCheck() from JITCodeGenerator.
     10        This required moving emitBranch() to SpeculativeJIT, since it was
     11        the main user of that field and method. Other than trvial clean-ups
     12        in emitBranch(), the code is unchanged (and still has some disparity
     13        between 64 and 32_64, and still lacks some obvious optimizations).
     14
     15        * dfg/DFGJITCodeGenerator.cpp:
     16        * dfg/DFGJITCodeGenerator.h:
     17        (JSC::DFG::JITCodeGenerator::JITCodeGenerator):
     18        * dfg/DFGJITCodeGenerator32_64.cpp:
     19        (JSC::DFG::JITCodeGenerator::fillDouble):
     20        (JSC::DFG::JITCodeGenerator::fillJSValue):
     21        * dfg/DFGJITCodeGenerator64.cpp:
     22        (JSC::DFG::JITCodeGenerator::fillDouble):
     23        (JSC::DFG::JITCodeGenerator::fillJSValue):
     24        * dfg/DFGSpeculativeJIT.h:
     25        (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
     26        * dfg/DFGSpeculativeJIT32_64.cpp:
     27        (JSC::DFG::SpeculativeJIT::emitBranch):
     28        * dfg/DFGSpeculativeJIT64.cpp:
     29        (JSC::DFG::SpeculativeJIT::emitBranch):
     30
    1312011-10-04  David Hyatt  <hyatt@apple.com>
    232
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r96443 r96661  
    378378}
    379379
    380 void JITCodeGenerator::speculationCheck(MacroAssembler::Jump jumpToFail)
    381 {
    382     ASSERT(m_isSpeculative);
    383     static_cast<SpeculativeJIT*>(this)->speculationCheck(jumpToFail);
    384 }
    385 
    386380#ifndef NDEBUG
    387381static const char* dataFormatString(DataFormat format)
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h

    r96451 r96661  
    233233
    234234protected:
    235     JITCodeGenerator(JITCompiler& jit, bool isSpeculative)
     235    JITCodeGenerator(JITCompiler& jit)
    236236        : m_jit(jit)
    237         , m_isSpeculative(isSpeculative)
    238237        , m_compileIndex(0)
    239238        , m_generationInfo(m_jit.codeBlock()->m_numCalleeRegisters)
     
    779778    bool nonSpeculativeStrictEq(Node&, bool invert = false);
    780779   
    781     void emitBranch(Node&);
    782    
    783780    MacroAssembler::Address addressOfCallData(int idx)
    784781    {
     
    800797    void emitCall(Node&);
    801798   
    802     void speculationCheck(MacroAssembler::Jump jumpToFail);
    803 
    804799    // Called once a node has completed code generation but prior to setting
    805800    // its result, to free up its children. (This must happen prior to setting
     
    13841379    // The JIT, while also provides MacroAssembler functionality.
    13851380    JITCompiler& m_jit;
    1386     // This flag is used to distinguish speculative and non-speculative
    1387     // code generation. This is significant when filling spilled values
    1388     // from the RegisterFile. When spilling we attempt to store information
    1389     // as to the type of boxed value being stored (int32, double, cell), and
    1390     // when filling on the speculative path we will retrieve this type info
    1391     // where available. On the non-speculative path, however, we cannot rely
    1392     // on the spill format info, since the a value being loaded might have
    1393     // been spilled by either the speculative or non-speculative paths (where
    1394     // we entered the non-speculative path on an intervening bail-out), and
    1395     // the value may have been boxed differently on the two paths.
    1396     bool m_isSpeculative;
    13971381    // The current node being generated.
    13981382    BlockIndex m_block;
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp

    r96451 r96661  
    137137            m_gprs.retain(tag, virtualRegister, SpillOrderSpilled);
    138138            m_gprs.retain(payload, virtualRegister, SpillOrderSpilled);
    139             info.fillJSValue(tag, payload, m_isSpeculative ? spillFormat : DataFormatJS);
     139            info.fillJSValue(tag, payload, spillFormat);
    140140            unlock(tag);
    141141            unlock(payload);
     
    243243            m_gprs.retain(tagGPR, virtualRegister, SpillOrderSpilled);
    244244            m_gprs.retain(payloadGPR, virtualRegister, SpillOrderSpilled);
    245             info.fillJSValue(tagGPR, payloadGPR, m_isSpeculative ? spillFormat : DataFormatJS);
     245            info.fillJSValue(tagGPR, payloadGPR, spillFormat);
    246246        }
    247247
     
    15181518}
    15191519
    1520 void JITCodeGenerator::emitBranch(Node& node)
    1521 {
    1522     // FIXME: Add fast cases for known Boolean!
    1523     JSValueOperand value(this, node.child1());
    1524     value.fill();
    1525     GPRReg valueTagGPR = value.tagGPR();
    1526     GPRReg valuePayloadGPR = value.payloadGPR();
    1527 
    1528     GPRTemporary result(this);
    1529     GPRReg resultGPR = result.gpr();
    1530    
    1531     use(node.child1());
    1532    
    1533     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
    1534     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
    1535 
    1536     JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
    1537     JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
    1538 
    1539     fastPath.link(&m_jit);
    1540     addBranch(m_jit.branchTest32(JITCompiler::Zero, valuePayloadGPR), notTaken);
    1541     addBranch(m_jit.jump(), taken);
    1542 
    1543     slowPath.link(&m_jit);
    1544     silentSpillAllRegisters(resultGPR);
    1545     m_jit.push(valueTagGPR);
    1546     m_jit.push(valuePayloadGPR);
    1547     m_jit.push(GPRInfo::callFrameRegister);
    1548     appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1549     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1550     silentFillAllRegisters(resultGPR);
    1551    
    1552     addBranch(m_jit.branchTest8(JITCompiler::NonZero, resultGPR), taken);
    1553     if (notTaken != (m_block + 1))
    1554         addBranch(m_jit.jump(), notTaken);
    1555    
    1556     noResult(m_compileIndex, UseChildrenCalledExplicitly);
    1557 }
    1558 
    15591520void JITCodeGenerator::emitCall(Node& node)
    15601521{
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp

    r96415 r96661  
    149149            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    150150            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    151             info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
     151            info.fillJSValue(gpr, spillFormat);
    152152            unlock(gpr);
    153153        }
     
    267267            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    268268            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    269             info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
     269            info.fillJSValue(gpr, spillFormat);
    270270        }
    271271        return gpr;
     
    14621462}
    14631463
    1464 void JITCodeGenerator::emitBranch(Node& node)
    1465 {
    1466     JSValueOperand value(this, node.child1());
    1467     GPRReg valueGPR = value.gpr();
    1468    
    1469     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
    1470     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
    1471    
    1472     if (isKnownBoolean(node.child1())) {
    1473         MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
    1474        
    1475         if (taken == (m_block + 1)) {
    1476             condition = MacroAssembler::Zero;
    1477             BlockIndex tmp = taken;
    1478             taken = notTaken;
    1479             notTaken = tmp;
    1480         }
    1481        
    1482         addBranch(m_jit.branchTest32(condition, valueGPR, TrustedImm32(true)), taken);
    1483         if (notTaken != (m_block + 1))
    1484             addBranch(m_jit.jump(), notTaken);
    1485        
    1486         noResult(m_compileIndex);
    1487     } else {
    1488         GPRTemporary result(this);
    1489         GPRReg resultGPR = result.gpr();
    1490        
    1491         bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
    1492    
    1493         if (predictBoolean) {
    1494             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
    1495             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
    1496         }
    1497        
    1498         if (m_isSpeculative && predictBoolean) {
    1499             speculationCheck(m_jit.jump());
    1500             value.use();
    1501         } else {
    1502             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
    1503             addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken);
    1504    
    1505             if (!predictBoolean) {
    1506                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
    1507                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
    1508             }
    1509    
    1510             value.use();
    1511    
    1512             silentSpillAllRegisters(resultGPR);
    1513             m_jit.move(valueGPR, GPRInfo::argumentGPR1);
    1514             m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1515             appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1516             m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1517             silentFillAllRegisters(resultGPR);
    1518    
    1519             addBranch(m_jit.branchTest8(MacroAssembler::NonZero, resultGPR), taken);
    1520             if (notTaken != (m_block + 1))
    1521                 addBranch(m_jit.jump(), notTaken);
    1522         }
    1523        
    1524         noResult(m_compileIndex, UseChildrenCalledExplicitly);
    1525     }
    1526 }
    1527 
    15281464void JITCodeGenerator::emitCall(Node& node)
    15291465{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r96461 r96661  
    601601    void compileValueAdd(Node&);
    602602    void compileLogicalNot(Node&);
     603    void emitBranch(Node&);
    603604   
    604605    // It is acceptable to have structure be equal to scratch, so long as you're fine
     
    944945
    945946inline SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
    946     : JITCodeGenerator(jit, true)
     947    : JITCodeGenerator(jit)
    947948    , m_compileOkay(true)
    948949    , m_arguments(jit.codeBlock()->m_numParameters)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r96569 r96661  
    483483}
    484484
     485void SpeculativeJIT::emitBranch(Node& node)
     486{
     487    // FIXME: Add fast cases for known Boolean!
     488    JSValueOperand value(this, node.child1());
     489    value.fill();
     490    GPRReg valueTagGPR = value.tagGPR();
     491    GPRReg valuePayloadGPR = value.payloadGPR();
     492
     493    GPRTemporary result(this);
     494    GPRReg resultGPR = result.gpr();
     495   
     496    use(node.child1());
     497   
     498    BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
     499    BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
     500
     501    JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
     502    JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
     503
     504    fastPath.link(&m_jit);
     505    addBranch(m_jit.branchTest32(JITCompiler::Zero, valuePayloadGPR), notTaken);
     506    addBranch(m_jit.jump(), taken);
     507
     508    slowPath.link(&m_jit);
     509    silentSpillAllRegisters(resultGPR);
     510    m_jit.push(valueTagGPR);
     511    m_jit.push(valuePayloadGPR);
     512    m_jit.push(GPRInfo::callFrameRegister);
     513    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
     514    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
     515    silentFillAllRegisters(resultGPR);
     516   
     517    addBranch(m_jit.branchTest8(JITCompiler::NonZero, resultGPR), taken);
     518    if (notTaken != (m_block + 1))
     519        addBranch(m_jit.jump(), notTaken);
     520   
     521    noResult(m_compileIndex, UseChildrenCalledExplicitly);
     522}
     523
    485524void SpeculativeJIT::compile(Node& node)
    486525{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r96567 r96661  
    583583}
    584584
     585void SpeculativeJIT::emitBranch(Node& node)
     586{
     587    JSValueOperand value(this, node.child1());
     588    GPRReg valueGPR = value.gpr();
     589   
     590    BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
     591    BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
     592   
     593    if (isKnownBoolean(node.child1())) {
     594        MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
     595       
     596        if (taken == (m_block + 1)) {
     597            condition = MacroAssembler::Zero;
     598            BlockIndex tmp = taken;
     599            taken = notTaken;
     600            notTaken = tmp;
     601        }
     602       
     603        addBranch(m_jit.branchTest32(condition, valueGPR, TrustedImm32(true)), taken);
     604        if (notTaken != (m_block + 1))
     605            addBranch(m_jit.jump(), notTaken);
     606       
     607        noResult(m_compileIndex);
     608    } else {
     609        GPRTemporary result(this);
     610        GPRReg resultGPR = result.gpr();
     611       
     612        bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
     613   
     614        if (predictBoolean) {
     615            addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
     616            addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
     617
     618            speculationCheck(m_jit.jump());
     619            value.use();
     620        } else {
     621            addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
     622            addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken);
     623   
     624            addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
     625            addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
     626   
     627            value.use();
     628   
     629            silentSpillAllRegisters(resultGPR);
     630            m_jit.move(valueGPR, GPRInfo::argumentGPR1);
     631            m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     632            appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
     633            m_jit.move(GPRInfo::returnValueGPR, resultGPR);
     634            silentFillAllRegisters(resultGPR);
     635   
     636            addBranch(m_jit.branchTest8(MacroAssembler::NonZero, resultGPR), taken);
     637            if (notTaken != (m_block + 1))
     638                addBranch(m_jit.jump(), notTaken);
     639        }
     640       
     641        noResult(m_compileIndex, UseChildrenCalledExplicitly);
     642    }
     643}
     644
    585645void SpeculativeJIT::compile(Node& node)
    586646{
Note: See TracChangeset for help on using the changeset viewer.