Changeset 121717 in webkit for trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
- Timestamp:
- Jul 2, 2012, 6:27:16 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r121391 r121717 46 46 , m_lastSetOperand(std::numeric_limits<int>::max()) 47 47 , m_state(m_jit.graph()) 48 , m_stream(&jit.codeBlock()->variableEventStream()) 49 , m_minifiedGraph(&jit.codeBlock()->minifiedDFG()) 48 50 , m_isCheckingArgumentTypes(false) 49 51 { … … 100 102 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); 101 103 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr); 102 info.fillStorage( gpr);104 info.fillStorage(*m_stream, gpr); 103 105 return gpr; 104 106 } … … 780 782 } 781 783 #endif 782 783 void ValueSource::dump(FILE* out) const784 {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 }815 784 816 785 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition) … … 954 923 } 955 924 925 void 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 956 936 void SpeculativeJIT::compileMovHint(Node& node) 957 937 { 958 938 ASSERT(node.op() == SetLocal); 959 939 960 setNodeIndexForOperand(node.child1().index(), node.local());961 940 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())); 962 949 } 963 950 … … 984 971 #endif 985 972 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 986 979 m_jit.jitAssertHasValidCallFrame(); 987 980 988 981 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 } 991 987 992 988 m_state.reset(); … … 996 992 for (size_t i = 0; i < m_variables.size(); ++i) { 997 993 NodeIndex nodeIndex = block.variablesAtHead.local(i); 994 ValueSource valueSource; 998 995 if (nodeIndex == NoNode) 999 m_variables[i]= ValueSource(SourceIsDead);996 valueSource = ValueSource(SourceIsDead); 1000 997 else if (at(nodeIndex).variableAccessData()->isArgumentsAlias()) 1001 m_variables[i]= ValueSource(ArgumentsSource);998 valueSource = ValueSource(ArgumentsSource); 1002 999 else if (at(nodeIndex).variableAccessData()->isCaptured()) 1003 m_variables[i]= ValueSource(ValueInRegisterFile);1000 valueSource = ValueSource(ValueInRegisterFile); 1004 1001 else if (!at(nodeIndex).refCount()) 1005 m_variables[i]= ValueSource(SourceIsDead);1002 valueSource = ValueSource(SourceIsDead); 1006 1003 else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat()) 1007 m_variables[i]= ValueSource(DoubleInRegisterFile);1004 valueSource = ValueSource(DoubleInRegisterFile); 1008 1005 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())); 1010 1009 } 1011 1010 … … 1019 1018 verificationSucceeded.link(&m_jit); 1020 1019 } 1020 1021 #if DFG_ENABLE(DEBUG_VERBOSE) 1022 dataLog("\n"); 1023 #endif 1021 1024 1022 1025 for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) { … … 1030 1033 #endif 1031 1034 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 1032 1044 case SetLocal: 1033 1045 compileMovHint(node); … … 1074 1086 } 1075 1087 1076 case WeakJSConstant:1077 m_jit.addWeakReference(node.weakConstant());1078 break;1079 1080 1088 default: 1089 if (belongsInMinifiedGraph(node.op())) 1090 m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node)); 1081 1091 break; 1082 1092 } … … 1099 1109 clearGenerationInfo(); 1100 1110 return; 1111 } 1112 1113 if (belongsInMinifiedGraph(node.op())) { 1114 m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node)); 1115 noticeOSRBirth(m_compileIndex, node); 1101 1116 } 1102 1117 … … 1121 1136 } 1122 1137 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 #endif1132 1133 1138 #if DFG_ENABLE(DEBUG_VERBOSE) 1134 1139 dataLog("\n"); … … 1367 1372 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource) 1368 1373 { 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(); 1519 1382 } 1520 1383 … … 1655 1518 case DataFormatDouble: 1656 1519 return GeneratedOperandDouble; 1657 } 1658 1659 ASSERT_NOT_REACHED(); 1660 return GeneratedOperandTypeUnknown; 1520 1521 default: 1522 ASSERT_NOT_REACHED(); 1523 return GeneratedOperandTypeUnknown; 1524 } 1661 1525 } 1662 1526
Note:
See TracChangeset
for help on using the changeset viewer.