Ignore:
Timestamp:
Jul 2, 2012, 6:27:16 PM (13 years ago)
Author:
[email protected]
Message:

DFG OSR exit value recoveries should be computed lazily
https://bugs.webkit.org/show_bug.cgi?id=82155

Reviewed by Gavin Barraclough.

This change aims to reduce one aspect of DFG compile times: the fact
that we currently compute the value recoveries for each local and
argument on every speculation check. We compile many speculation checks,
so this can add up quick. The strategy that this change takes is to
have the DFG save just enough information about how the compiler is
choosing to represent state, that the DFG::OSRExitCompiler can reify
the value recoveries lazily.

This appears to be an 0.3% SunSpider speed-up and is neutral elsewhere.

I also took the opportunity to fix the sampling regions profiler (it
was missing an export macro) and to put in more sampling regions in
the DFG (which are disabled so long as ENABLE(SAMPLING_REGIONS) is
false).

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • bytecode/CodeBlock.cpp:

(JSC):
(JSC::CodeBlock::shrinkDFGDataToFit):

  • bytecode/CodeBlock.h:

(CodeBlock):
(JSC::CodeBlock::minifiedDFG):
(JSC::CodeBlock::variableEventStream):
(DFGData):

  • bytecode/Operands.h:

(JSC::Operands::hasOperand):
(Operands):
(JSC::Operands::size):
(JSC::Operands::at):
(JSC::Operands::operator[]):
(JSC::Operands::isArgument):
(JSC::Operands::isVariable):
(JSC::Operands::argumentForIndex):
(JSC::Operands::variableForIndex):
(JSC::Operands::operandForIndex):
(JSC):
(JSC::dumpOperands):

  • bytecode/SamplingTool.h:

(SamplingRegion):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::parse):

  • dfg/DFGCFAPhase.cpp:

(JSC::DFG::performCFA):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::performCSE):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::performFixup):

  • dfg/DFGGenerationInfo.h:

(JSC::DFG::GenerationInfo::GenerationInfo):
(JSC::DFG::GenerationInfo::initConstant):
(JSC::DFG::GenerationInfo::initInteger):
(JSC::DFG::GenerationInfo::initJSValue):
(JSC::DFG::GenerationInfo::initCell):
(JSC::DFG::GenerationInfo::initBoolean):
(JSC::DFG::GenerationInfo::initDouble):
(JSC::DFG::GenerationInfo::initStorage):
(GenerationInfo):
(JSC::DFG::GenerationInfo::noticeOSRBirth):
(JSC::DFG::GenerationInfo::use):
(JSC::DFG::GenerationInfo::spill):
(JSC::DFG::GenerationInfo::setSpilled):
(JSC::DFG::GenerationInfo::fillJSValue):
(JSC::DFG::GenerationInfo::fillCell):
(JSC::DFG::GenerationInfo::fillInteger):
(JSC::DFG::GenerationInfo::fillBoolean):
(JSC::DFG::GenerationInfo::fillDouble):
(JSC::DFG::GenerationInfo::fillStorage):
(JSC::DFG::GenerationInfo::appendFill):
(JSC::DFG::GenerationInfo::appendSpill):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):

  • dfg/DFGMinifiedGraph.h: Added.

(DFG):
(MinifiedGraph):
(JSC::DFG::MinifiedGraph::MinifiedGraph):
(JSC::DFG::MinifiedGraph::at):
(JSC::DFG::MinifiedGraph::append):
(JSC::DFG::MinifiedGraph::prepareAndShrink):
(JSC::DFG::MinifiedGraph::setOriginalGraphSize):
(JSC::DFG::MinifiedGraph::originalGraphSize):

  • dfg/DFGMinifiedNode.cpp: Added.

(DFG):
(JSC::DFG::MinifiedNode::fromNode):

  • dfg/DFGMinifiedNode.h: Added.

(DFG):
(JSC::DFG::belongsInMinifiedGraph):
(MinifiedNode):
(JSC::DFG::MinifiedNode::MinifiedNode):
(JSC::DFG::MinifiedNode::index):
(JSC::DFG::MinifiedNode::op):
(JSC::DFG::MinifiedNode::hasChild1):
(JSC::DFG::MinifiedNode::child1):
(JSC::DFG::MinifiedNode::hasConstant):
(JSC::DFG::MinifiedNode::hasConstantNumber):
(JSC::DFG::MinifiedNode::constantNumber):
(JSC::DFG::MinifiedNode::hasWeakConstant):
(JSC::DFG::MinifiedNode::weakConstant):
(JSC::DFG::MinifiedNode::getIndex):
(JSC::DFG::MinifiedNode::compareByNodeIndex):
(JSC::DFG::MinifiedNode::hasChild):

  • dfg/DFGNode.h:

(Node):

  • dfg/DFGOSRExit.cpp:

(JSC::DFG::OSRExit::OSRExit):

  • dfg/DFGOSRExit.h:

(OSRExit):

  • dfg/DFGOSRExitCompiler.cpp:
  • dfg/DFGOSRExitCompiler.h:

(OSRExitCompiler):

  • dfg/DFGOSRExitCompiler32_64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOSRExitCompiler64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::performPredictionPropagation):

  • dfg/DFGRedundantPhiEliminationPhase.cpp:

(JSC::DFG::performRedundantPhiElimination):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::SpeculativeJIT):
(DFG):
(JSC::DFG::SpeculativeJIT::fillStorage):
(JSC::DFG::SpeculativeJIT::noticeOSRBirth):
(JSC::DFG::SpeculativeJIT::compileMovHint):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):

  • dfg/DFGSpeculativeJIT.h:

(DFG):
(JSC::DFG::SpeculativeJIT::use):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::spill):
(JSC::DFG::SpeculativeJIT::speculationCheck):
(JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
(JSC::DFG::SpeculativeJIT::recordSetLocal):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillInteger):
(JSC::DFG::SpeculativeJIT::fillDouble):
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillInteger):
(JSC::DFG::SpeculativeJIT::fillDouble):
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGValueRecoveryOverride.h: Added.

(DFG):
(ValueRecoveryOverride):
(JSC::DFG::ValueRecoveryOverride::ValueRecoveryOverride):

  • dfg/DFGValueSource.cpp: Added.

(DFG):
(JSC::DFG::ValueSource::dump):

  • dfg/DFGValueSource.h: Added.

(DFG):
(JSC::DFG::dataFormatToValueSourceKind):
(JSC::DFG::valueSourceKindToDataFormat):
(JSC::DFG::isInRegisterFile):
(ValueSource):
(JSC::DFG::ValueSource::ValueSource):
(JSC::DFG::ValueSource::forPrediction):
(JSC::DFG::ValueSource::forDataFormat):
(JSC::DFG::ValueSource::isSet):
(JSC::DFG::ValueSource::kind):
(JSC::DFG::ValueSource::isInRegisterFile):
(JSC::DFG::ValueSource::dataFormat):
(JSC::DFG::ValueSource::valueRecovery):
(JSC::DFG::ValueSource::nodeIndex):
(JSC::DFG::ValueSource::nodeIndexFromKind):
(JSC::DFG::ValueSource::kindFromNodeIndex):

  • dfg/DFGVariableEvent.cpp: Added.

(DFG):
(JSC::DFG::VariableEvent::dump):
(JSC::DFG::VariableEvent::dumpFillInfo):
(JSC::DFG::VariableEvent::dumpSpillInfo):

  • dfg/DFGVariableEvent.h: Added.

(DFG):
(VariableEvent):
(JSC::DFG::VariableEvent::VariableEvent):
(JSC::DFG::VariableEvent::reset):
(JSC::DFG::VariableEvent::fillGPR):
(JSC::DFG::VariableEvent::fillPair):
(JSC::DFG::VariableEvent::fillFPR):
(JSC::DFG::VariableEvent::spill):
(JSC::DFG::VariableEvent::death):
(JSC::DFG::VariableEvent::setLocal):
(JSC::DFG::VariableEvent::movHint):
(JSC::DFG::VariableEvent::kind):
(JSC::DFG::VariableEvent::nodeIndex):
(JSC::DFG::VariableEvent::dataFormat):
(JSC::DFG::VariableEvent::gpr):
(JSC::DFG::VariableEvent::tagGPR):
(JSC::DFG::VariableEvent::payloadGPR):
(JSC::DFG::VariableEvent::fpr):
(JSC::DFG::VariableEvent::virtualRegister):
(JSC::DFG::VariableEvent::operand):
(JSC::DFG::VariableEvent::variableRepresentation):

  • dfg/DFGVariableEventStream.cpp: Added.

(DFG):
(JSC::DFG::VariableEventStream::logEvent):
(MinifiedGenerationInfo):
(JSC::DFG::MinifiedGenerationInfo::MinifiedGenerationInfo):
(JSC::DFG::MinifiedGenerationInfo::update):
(JSC::DFG::VariableEventStream::reconstruct):

  • dfg/DFGVariableEventStream.h: Added.

(DFG):
(VariableEventStream):
(JSC::DFG::VariableEventStream::appendAndLog):

  • dfg/DFGVirtualRegisterAllocationPhase.cpp:

(JSC::DFG::performVirtualRegisterAllocation):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r121391 r121717  
    4646    , m_lastSetOperand(std::numeric_limits<int>::max())
    4747    , m_state(m_jit.graph())
     48    , m_stream(&jit.codeBlock()->variableEventStream())
     49    , m_minifiedGraph(&jit.codeBlock()->minifiedDFG())
    4850    , m_isCheckingArgumentTypes(false)
    4951{
     
    100102            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    101103            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    102             info.fillStorage(gpr);
     104            info.fillStorage(*m_stream, gpr);
    103105            return gpr;
    104106        }
     
    780782}
    781783#endif
    782 
    783 void ValueSource::dump(FILE* out) const
    784 {
    785     switch (kind()) {
    786     case SourceNotSet:
    787         fprintf(out, "NotSet");
    788         break;
    789     case SourceIsDead:
    790         fprintf(out, "IsDead");
    791         break;
    792     case ValueInRegisterFile:
    793         fprintf(out, "InRegFile");
    794         break;
    795     case Int32InRegisterFile:
    796         fprintf(out, "Int32");
    797         break;
    798     case CellInRegisterFile:
    799         fprintf(out, "Cell");
    800         break;
    801     case BooleanInRegisterFile:
    802         fprintf(out, "Bool");
    803         break;
    804     case DoubleInRegisterFile:
    805         fprintf(out, "Double");
    806         break;
    807     case ArgumentsSource:
    808         fprintf(out, "Arguments");
    809         break;
    810     case HaveNode:
    811         fprintf(out, "Node(%d)", m_nodeIndex);
    812         break;
    813     }
    814 }
    815784
    816785void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
     
    954923}
    955924
     925void SpeculativeJIT::noticeOSRBirth(NodeIndex nodeIndex, Node& node)
     926{
     927    if (!node.hasVirtualRegister())
     928        return;
     929   
     930    VirtualRegister virtualRegister = node.virtualRegister();
     931    GenerationInfo& info = m_generationInfo[virtualRegister];
     932   
     933    info.noticeOSRBirth(*m_stream, nodeIndex, virtualRegister);
     934}
     935
    956936void SpeculativeJIT::compileMovHint(Node& node)
    957937{
    958938    ASSERT(node.op() == SetLocal);
    959939   
    960     setNodeIndexForOperand(node.child1().index(), node.local());
    961940    m_lastSetOperand = node.local();
     941   
     942    Node& child = at(node.child1());
     943    noticeOSRBirth(node.child1().index(), child);
     944   
     945    if (child.op() == UInt32ToNumber)
     946        noticeOSRBirth(child.child1().index(), at(child.child1()));
     947   
     948    m_stream->appendAndLog(VariableEvent::movHint(node.child1().index(), node.local()));
    962949}
    963950
     
    984971#endif
    985972   
     973#if DFG_ENABLE(DEBUG_VERBOSE)
     974    dataLog("Setting up state for block #%u: ", m_block);
     975#endif
     976   
     977    m_stream->appendAndLog(VariableEvent::reset());
     978   
    986979    m_jit.jitAssertHasValidCallFrame();
    987980
    988981    ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
    989     for (size_t i = 0; i < m_arguments.size(); ++i)
    990         m_arguments[i] = ValueSource(ValueInRegisterFile);
     982    for (size_t i = 0; i < m_arguments.size(); ++i) {
     983        ValueSource valueSource = ValueSource(ValueInRegisterFile);
     984        m_arguments[i] = valueSource;
     985        m_stream->appendAndLog(VariableEvent::setLocal(argumentToOperand(i), valueSource.dataFormat()));
     986    }
    991987   
    992988    m_state.reset();
     
    996992    for (size_t i = 0; i < m_variables.size(); ++i) {
    997993        NodeIndex nodeIndex = block.variablesAtHead.local(i);
     994        ValueSource valueSource;
    998995        if (nodeIndex == NoNode)
    999             m_variables[i] = ValueSource(SourceIsDead);
     996            valueSource = ValueSource(SourceIsDead);
    1000997        else if (at(nodeIndex).variableAccessData()->isArgumentsAlias())
    1001             m_variables[i] = ValueSource(ArgumentsSource);
     998            valueSource = ValueSource(ArgumentsSource);
    1002999        else if (at(nodeIndex).variableAccessData()->isCaptured())
    1003             m_variables[i] = ValueSource(ValueInRegisterFile);
     1000            valueSource = ValueSource(ValueInRegisterFile);
    10041001        else if (!at(nodeIndex).refCount())
    1005             m_variables[i] = ValueSource(SourceIsDead);
     1002            valueSource = ValueSource(SourceIsDead);
    10061003        else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat())
    1007             m_variables[i] = ValueSource(DoubleInRegisterFile);
     1004            valueSource = ValueSource(DoubleInRegisterFile);
    10081005        else
    1009             m_variables[i] = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->argumentAwarePrediction());
     1006            valueSource = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->argumentAwarePrediction());
     1007        m_variables[i] = valueSource;
     1008        m_stream->appendAndLog(VariableEvent::setLocal(i, valueSource.dataFormat()));
    10101009    }
    10111010   
     
    10191018        verificationSucceeded.link(&m_jit);
    10201019    }
     1020
     1021#if DFG_ENABLE(DEBUG_VERBOSE)
     1022    dataLog("\n");
     1023#endif
    10211024
    10221025    for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
     
    10301033#endif
    10311034            switch (node.op()) {
     1035            case JSConstant:
     1036                m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
     1037                break;
     1038               
     1039            case WeakJSConstant:
     1040                m_jit.addWeakReference(node.weakConstant());
     1041                m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
     1042                break;
     1043               
    10321044            case SetLocal:
    10331045                compileMovHint(node);
     
    10741086            }
    10751087               
    1076             case WeakJSConstant:
    1077                 m_jit.addWeakReference(node.weakConstant());
    1078                 break;
    1079                
    10801088            default:
     1089                if (belongsInMinifiedGraph(node.op()))
     1090                    m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
    10811091                break;
    10821092            }
     
    10991109                clearGenerationInfo();
    11001110                return;
     1111            }
     1112           
     1113            if (belongsInMinifiedGraph(node.op())) {
     1114                m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
     1115                noticeOSRBirth(m_compileIndex, node);
    11011116            }
    11021117           
     
    11211136        }
    11221137       
    1123 #if DFG_ENABLE(VERBOSE_VALUE_RECOVERIES)
    1124         for (size_t i = 0; i < m_arguments.size(); ++i)
    1125             computeValueRecoveryFor(argumentToOperand(i)).dump(stderr);
    1126        
    1127         dataLog(" : ");
    1128        
    1129         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
    1130             computeValueRecoveryFor(operand).dump(stderr);
    1131 #endif
    1132 
    11331138#if DFG_ENABLE(DEBUG_VERBOSE)
    11341139        dataLog("\n");
     
    13671372ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
    13681373{
    1369     switch (valueSource.kind()) {
    1370     case SourceIsDead:
    1371         return ValueRecovery::constant(jsUndefined());
    1372        
    1373     case ValueInRegisterFile:
    1374         return ValueRecovery::alreadyInRegisterFile();
    1375        
    1376     case Int32InRegisterFile:
    1377         return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
    1378 
    1379     case CellInRegisterFile:
    1380         return ValueRecovery::alreadyInRegisterFileAsUnboxedCell();
    1381 
    1382     case BooleanInRegisterFile:
    1383         return ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean();
    1384        
    1385     case DoubleInRegisterFile:
    1386         return ValueRecovery::alreadyInRegisterFileAsUnboxedDouble();
    1387        
    1388     case ArgumentsSource:
    1389         return ValueRecovery::argumentsThatWereNotCreated();
    1390 
    1391     case HaveNode: {
    1392         Node* nodePtr = &at(valueSource.nodeIndex());
    1393 
    1394         if (nodePtr->isPhantomArguments())
    1395             return ValueRecovery::argumentsThatWereNotCreated();
    1396        
    1397         if (nodePtr->hasConstant())
    1398             return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
    1399        
    1400         GenerationInfo* infoPtr;
    1401         if (nodePtr->shouldGenerate())
    1402             infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
    1403         else
    1404             infoPtr = 0;
    1405         if (!infoPtr || !infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
    1406             // Try to see if there is an alternate node that would contain the value we want.
    1407             // There are four possibilities:
    1408             //
    1409             // Int32ToDouble: We can use this in place of the original node, but
    1410             //    we'd rather not; so we use it only if it is the only remaining
    1411             //    live version.
    1412             //
    1413             // ValueToInt32: If the only remaining live version of the value is
    1414             //    ValueToInt32, then we can use it.
    1415             //
    1416             // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
    1417             //    then the only remaining uses are ones that want a properly formed number
    1418             //    rather than a UInt32 intermediate.
    1419             //
    1420             // The reverse of the above: This node could be a UInt32ToNumber, but its
    1421             //    alternative is still alive. This means that the only remaining uses of
    1422             //    the number would be fine with a UInt32 intermediate.
    1423             //
    1424             // DoubleAsInt32: Same as UInt32ToNumber.
    1425             //
    1426        
    1427             bool found = false;
    1428        
    1429             if (nodePtr->op() == UInt32ToNumber || nodePtr->op() == DoubleAsInt32) {
    1430                 NodeIndex nodeIndex = nodePtr->child1().index();
    1431                 nodePtr = &at(nodeIndex);
    1432                 if (nodePtr->shouldGenerate()) {
    1433                     infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
    1434                     if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
    1435                         found = true;
    1436                 }
    1437             }
    1438        
    1439             if (!found) {
    1440                 NodeIndex int32ToDoubleIndex = NoNode;
    1441                 NodeIndex valueToInt32Index = NoNode;
    1442                 NodeIndex uint32ToNumberIndex = NoNode;
    1443                 NodeIndex doubleAsInt32Index = NoNode;
    1444            
    1445                 for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
    1446                     GenerationInfo& info = m_generationInfo[virtualRegister];
    1447                     if (!info.alive())
    1448                         continue;
    1449                     if (info.nodeIndex() == NoNode)
    1450                         continue;
    1451                     Node& node = at(info.nodeIndex());
    1452                     if (node.child1Unchecked() != valueSource.nodeIndex())
    1453                         continue;
    1454                     switch (node.op()) {
    1455                     case Int32ToDouble:
    1456                         int32ToDoubleIndex = info.nodeIndex();
    1457                         break;
    1458                     case ValueToInt32:
    1459                         valueToInt32Index = info.nodeIndex();
    1460                         break;
    1461                     case UInt32ToNumber:
    1462                         uint32ToNumberIndex = info.nodeIndex();
    1463                         break;
    1464                     case DoubleAsInt32:
    1465                         doubleAsInt32Index = info.nodeIndex();
    1466                     default:
    1467                         break;
    1468                     }
    1469                 }
    1470            
    1471                 NodeIndex nodeIndexToUse;
    1472                 if (doubleAsInt32Index != NoNode)
    1473                     nodeIndexToUse = doubleAsInt32Index;
    1474                 else if (int32ToDoubleIndex != NoNode)
    1475                     nodeIndexToUse = int32ToDoubleIndex;
    1476                 else if (valueToInt32Index != NoNode)
    1477                     nodeIndexToUse = valueToInt32Index;
    1478                 else if (uint32ToNumberIndex != NoNode)
    1479                     nodeIndexToUse = uint32ToNumberIndex;
    1480                 else
    1481                     nodeIndexToUse = NoNode;
    1482            
    1483                 if (nodeIndexToUse != NoNode) {
    1484                     nodePtr = &at(nodeIndexToUse);
    1485                     if (nodePtr->shouldGenerate()) {
    1486                         infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
    1487                         ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
    1488                         found = true;
    1489                     }
    1490                 }
    1491             }
    1492        
    1493             if (!found)
    1494                 return ValueRecovery::constant(jsUndefined());
    1495         }
    1496    
    1497         ASSERT(infoPtr->alive());
    1498 
    1499         if (infoPtr->registerFormat() != DataFormatNone) {
    1500             if (infoPtr->registerFormat() == DataFormatDouble)
    1501                 return ValueRecovery::inFPR(infoPtr->fpr());
    1502 #if USE(JSVALUE32_64)
    1503             if (infoPtr->registerFormat() & DataFormatJS)
    1504                 return ValueRecovery::inPair(infoPtr->tagGPR(), infoPtr->payloadGPR());
    1505 #endif
    1506             return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
    1507         }
    1508         if (infoPtr->spillFormat() != DataFormatNone)
    1509             return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()), infoPtr->spillFormat());
    1510    
    1511         ASSERT_NOT_REACHED();
    1512         return ValueRecovery();
    1513     }
    1514        
    1515     default:
    1516         ASSERT_NOT_REACHED();
    1517         return ValueRecovery();
    1518     }
     1374    if (valueSource.isInRegisterFile())
     1375        return valueSource.valueRecovery();
     1376       
     1377    ASSERT(valueSource.kind() == HaveNode);
     1378    if (isConstant(valueSource.nodeIndex()))
     1379        return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
     1380   
     1381    return ValueRecovery();
    15191382}
    15201383
     
    16551518    case DataFormatDouble:
    16561519        return GeneratedOperandDouble;
    1657     }
    1658 
    1659     ASSERT_NOT_REACHED();
    1660     return GeneratedOperandTypeUnknown;
     1520       
     1521    default:
     1522        ASSERT_NOT_REACHED();
     1523        return GeneratedOperandTypeUnknown;
     1524    }
    16611525}
    16621526
Note: See TracChangeset for help on using the changeset viewer.