Changeset 95930 in webkit
- Timestamp:
- Sep 25, 2011 7:25:02 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r95927 r95930 1 2011-09-25 Filip Pizlo <fpizlo@apple.com> 2 3 DFG static prediction code is no longer needed and should be removed 4 https://bugs.webkit.org/show_bug.cgi?id=68784 5 6 Reviewed by Oliver Hunt. 7 8 This gets rid of static prediction code, and ensures that we do not 9 try to compile code where dynamic predictions are not available. 10 This is accomplished by immediately performing an OSR exit wherever 11 a value is retrieved for which no predictions exist. 12 13 This also adds value profiling for this on functions used for calls. 14 15 The heuristics for deciding when to optimize code are also tweaked, 16 since it is now profitable to optimize sooner. This may need to be 17 tweaked further, but this patch only makes minimal changes. 18 19 This results in a 16% speed-up on Kraken/ai-astar, leading to a 3% 20 overall win on Kraken. It's neutral elsewhere. 21 22 * bytecode/CodeBlock.cpp: 23 (JSC::CodeBlock::shouldOptimizeNow): 24 (JSC::CodeBlock::dumpValueProfiles): 25 * bytecode/CodeBlock.h: 26 * bytecode/PredictedType.cpp: 27 (JSC::predictionToString): 28 * bytecode/PredictedType.h: 29 (JSC::isCellPrediction): 30 (JSC::isObjectPrediction): 31 (JSC::isFinalObjectPrediction): 32 (JSC::isStringPrediction): 33 (JSC::isArrayPrediction): 34 (JSC::isInt32Prediction): 35 (JSC::isDoublePrediction): 36 (JSC::isNumberPrediction): 37 (JSC::isBooleanPrediction): 38 (JSC::mergePredictions): 39 * bytecode/PredictionTracker.h: 40 (JSC::PredictionTracker::predictArgument): 41 (JSC::PredictionTracker::predict): 42 (JSC::PredictionTracker::predictGlobalVar): 43 * bytecode/ValueProfile.cpp: 44 (JSC::ValueProfile::computeUpdatedPrediction): 45 * dfg/DFGByteCodeParser.cpp: 46 (JSC::DFG::ByteCodeParser::set): 47 (JSC::DFG::ByteCodeParser::addCall): 48 (JSC::DFG::ByteCodeParser::getPrediction): 49 (JSC::DFG::ByteCodeParser::parseBlock): 50 * dfg/DFGGraph.cpp: 51 (JSC::DFG::Graph::predictArgumentTypes): 52 * dfg/DFGGraph.h: 53 (JSC::DFG::Graph::predict): 54 (JSC::DFG::Graph::predictGlobalVar): 55 (JSC::DFG::Graph::getMethodCheckPrediction): 56 (JSC::DFG::Graph::getJSConstantPrediction): 57 (JSC::DFG::Graph::getPrediction): 58 * dfg/DFGJITCodeGenerator.cpp: 59 (JSC::DFG::JITCodeGenerator::writeBarrier): 60 (JSC::DFG::JITCodeGenerator::emitBranch): 61 * dfg/DFGJITCompiler.h: 62 (JSC::DFG::JITCompiler::getPrediction): 63 * dfg/DFGNode.h: 64 (JSC::DFG::Node::valueOfJSConstantNode): 65 (JSC::DFG::Node::isInt32Constant): 66 (JSC::DFG::Node::isDoubleConstant): 67 (JSC::DFG::Node::isNumberConstant): 68 (JSC::DFG::Node::isBooleanConstant): 69 (JSC::DFG::Node::predict): 70 * dfg/DFGPropagator.cpp: 71 (JSC::DFG::Propagator::Propagator): 72 (JSC::DFG::Propagator::propagateNodePredictions): 73 (JSC::DFG::Propagator::fixupNode): 74 (JSC::DFG::Propagator::isPredictedNumerical): 75 (JSC::DFG::Propagator::logicalNotIsPure): 76 * dfg/DFGSpeculativeJIT.cpp: 77 (JSC::DFG::SpeculativeJIT::compile): 78 * dfg/DFGSpeculativeJIT.h: 79 (JSC::DFG::SpeculativeJIT::shouldSpeculateInteger): 80 (JSC::DFG::SpeculativeJIT::shouldSpeculateDouble): 81 (JSC::DFG::SpeculativeJIT::shouldSpeculateNumber): 82 (JSC::DFG::SpeculativeJIT::shouldNotSpeculateInteger): 83 (JSC::DFG::SpeculativeJIT::shouldSpeculateFinalObject): 84 (JSC::DFG::SpeculativeJIT::shouldSpeculateArray): 85 (JSC::DFG::SpeculativeJIT::shouldSpeculateObject): 86 (JSC::DFG::SpeculativeJIT::shouldSpeculateCell): 87 * jit/JIT.cpp: 88 (JSC::JIT::privateCompile): 89 1 90 2011-09-25 Filip Pizlo <fpizlo@apple.com> 2 91 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r95901 r95930 2000 2000 2001 2001 if ((!numberOfNonArgumentValueProfiles || (double)numberOfLiveNonArgumentValueProfiles / numberOfNonArgumentValueProfiles >= 0.75) 2002 && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= 0. 5))2002 && (!numberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles() >= 0.25)) 2003 2003 return true; 2004 2004 … … 2027 2027 if (profile->m_bytecodeOffset < 0) { 2028 2028 ASSERT(profile->m_bytecodeOffset == -1); 2029 fprintf(stderr, " arg = %u: ", i + 1);2029 fprintf(stderr, " arg = %u: ", i); 2030 2030 } else 2031 2031 fprintf(stderr, " bc = %d: ", profile->m_bytecodeOffset); -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r95901 r95930 499 499 ValueProfile* valueProfileForArgument(int argumentIndex) 500 500 { 501 int index = argumentIndex - 1;501 int index = argumentIndex; 502 502 if (static_cast<unsigned>(index) >= m_valueProfiles.size()) 503 503 return 0; 504 ValueProfile* result = valueProfile(argumentIndex - 1);504 ValueProfile* result = valueProfile(argumentIndex); 505 505 if (result->m_bytecodeOffset != -1) 506 506 return 0; -
trunk/Source/JavaScriptCore/bytecode/PredictedType.cpp
r95901 r95930 38 38 const char* predictionToString(PredictedType value) 39 39 { 40 if (value == PredictNone) 41 return "None"; 42 40 43 static const int size = 96; 41 44 static char description[size]; 42 45 BoundsCheckedPointer<char> ptr(description, size); 43 44 if (!(value & StrongPredictionTag))45 ptr.strcat("Weak");46 46 47 47 if (value & PredictObjectUnknown) { -
trunk/Source/JavaScriptCore/bytecode/PredictedType.h
r95901 r95930 52 52 static const PredictedType PredictOther = 0x4000; // It's definitely none of the above. 53 53 static const PredictedType PredictTop = 0x7fff; // It can be any of the above. 54 static const PredictedType StrongPredictionTag = 0x8000; // It's a strong prediction (all strong predictions trump all weak ones).55 static const PredictedType PredictionTagMask = 0x8000;56 57 enum PredictionSource { WeakPrediction, StrongPrediction };58 54 59 55 inline bool isCellPrediction(PredictedType value) 60 56 { 61 return !!(value & PredictCell) && !(value & ~ (PredictCell | PredictionTagMask));57 return !!(value & PredictCell) && !(value & ~PredictCell); 62 58 } 63 59 64 60 inline bool isObjectPrediction(PredictedType value) 65 61 { 66 return !!(value & PredictObjectMask) && !(value & ~ (PredictObjectMask | PredictionTagMask));62 return !!(value & PredictObjectMask) && !(value & ~PredictObjectMask); 67 63 } 68 64 69 65 inline bool isFinalObjectPrediction(PredictedType value) 70 66 { 71 return (value & ~PredictionTagMask)== PredictFinalObject;67 return value == PredictFinalObject; 72 68 } 73 69 74 70 inline bool isStringPrediction(PredictedType value) 75 71 { 76 return (value & ~PredictionTagMask)== PredictString;72 return value == PredictString; 77 73 } 78 74 79 75 inline bool isArrayPrediction(PredictedType value) 80 76 { 81 return (value & ~PredictionTagMask)== PredictArray;77 return value == PredictArray; 82 78 } 83 79 84 80 inline bool isInt32Prediction(PredictedType value) 85 81 { 86 return (value & ~PredictionTagMask)== PredictInt32;82 return value == PredictInt32; 87 83 } 88 84 89 85 inline bool isDoublePrediction(PredictedType value) 90 86 { 91 return (value & ~PredictionTagMask)== PredictDouble;87 return value == PredictDouble; 92 88 } 93 89 94 90 inline bool isNumberPrediction(PredictedType value) 95 91 { 96 return !!(value & PredictNumber) && !(value & ~ (PredictNumber | PredictionTagMask));92 return !!(value & PredictNumber) && !(value & ~PredictNumber); 97 93 } 98 94 99 95 inline bool isBooleanPrediction(PredictedType value) 100 96 { 101 return (value & ~PredictionTagMask) == PredictBoolean; 102 } 103 104 inline bool isStrongPrediction(PredictedType value) 105 { 106 ASSERT(value != (PredictNone | StrongPredictionTag)); 107 return !!(value & StrongPredictionTag); 97 return value == PredictBoolean; 108 98 } 109 99 … … 114 104 inline PredictedType mergePredictions(PredictedType left, PredictedType right) 115 105 { 116 if (isStrongPrediction(left) == isStrongPrediction(right)) { 117 if (left & PredictObjectUnknown) { 118 ASSERT(!(left & (PredictObjectMask & ~PredictObjectUnknown))); 119 if (right & PredictObjectMask) 120 return (left & ~PredictObjectUnknown) | right; 121 } else if (right & PredictObjectUnknown) { 122 ASSERT(!(right & (PredictObjectMask & ~PredictObjectUnknown))); 123 if (left & PredictObjectMask) 124 return (right & ~PredictObjectUnknown) | left; 125 } 126 return left | right; 106 if (left & PredictObjectUnknown) { 107 ASSERT(!(left & (PredictObjectMask & ~PredictObjectUnknown))); 108 if (right & PredictObjectMask) 109 return (left & ~PredictObjectUnknown) | right; 110 } else if (right & PredictObjectUnknown) { 111 ASSERT(!(right & (PredictObjectMask & ~PredictObjectUnknown))); 112 if (left & PredictObjectMask) 113 return (right & ~PredictObjectUnknown) | left; 127 114 } 128 if (isStrongPrediction(left)) { 129 ASSERT(!isStrongPrediction(right)); 130 return left; 131 } 132 ASSERT(!isStrongPrediction(left)); 133 ASSERT(isStrongPrediction(right)); 134 return right; 115 return left | right; 135 116 } 136 117 … … 144 125 } 145 126 146 inline PredictedType makePrediction(PredictedType type, PredictionSource source)147 {148 ASSERT(!(type & StrongPredictionTag));149 ASSERT(source == StrongPrediction || source == WeakPrediction);150 if (type == PredictNone)151 return PredictNone;152 return type | (source == StrongPrediction ? StrongPredictionTag : 0);153 }154 155 127 PredictedType predictionFromClassInfo(const ClassInfo*); 156 128 PredictedType predictionFromStructure(Structure*); -
trunk/Source/JavaScriptCore/bytecode/PredictionTracker.h
r95901 r95930 74 74 unsigned argumentIndexForOperand(int operand) const { return operand + m_arguments.size() + RegisterFile::CallFrameHeaderSize; } 75 75 76 bool predictArgument(unsigned argument, PredictedType prediction , PredictionSource source)76 bool predictArgument(unsigned argument, PredictedType prediction) 77 77 { 78 return mergePrediction(m_arguments[argument].m_value, makePrediction(prediction, source));78 return mergePrediction(m_arguments[argument].m_value, prediction); 79 79 } 80 80 81 bool predict(int operand, PredictedType prediction , PredictionSource source)81 bool predict(int operand, PredictedType prediction) 82 82 { 83 83 if (operandIsArgument(operand)) 84 return predictArgument(argumentIndexForOperand(operand), prediction , source);84 return predictArgument(argumentIndexForOperand(operand), prediction); 85 85 if ((unsigned)operand >= m_variables.size()) { 86 86 ASSERT(operand >= 0); … … 88 88 } 89 89 90 return mergePrediction(m_variables[operand].m_value, makePrediction(prediction, source));90 return mergePrediction(m_variables[operand].m_value, prediction); 91 91 } 92 92 93 bool predictGlobalVar(unsigned varNumber, PredictedType prediction , PredictionSource source)93 bool predictGlobalVar(unsigned varNumber, PredictedType prediction) 94 94 { 95 95 HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVars.find(varNumber + 1); 96 96 if (iter == m_globalVars.end()) { 97 97 PredictionSlot predictionSlot; 98 bool result = mergePrediction(predictionSlot.m_value, makePrediction(prediction, source));98 bool result = mergePrediction(predictionSlot.m_value, prediction); 99 99 m_globalVars.add(varNumber + 1, predictionSlot); 100 100 return result; 101 101 } 102 return mergePrediction(iter->second.m_value, makePrediction(prediction, source));102 return mergePrediction(iter->second.m_value, prediction); 103 103 } 104 104 -
trunk/Source/JavaScriptCore/bytecode/ValueProfile.cpp
r95901 r95930 95 95 prediction = PredictNone; 96 96 else if (statistics.int32s == statistics.samples) 97 prediction = StrongPredictionTag |PredictInt32;97 prediction = PredictInt32; 98 98 else if (statistics.doubles == statistics.samples) 99 prediction = StrongPredictionTag |PredictDouble;99 prediction = PredictDouble; 100 100 else if (statistics.int32s + statistics.doubles == statistics.samples) 101 prediction = StrongPredictionTag |PredictNumber;101 prediction = PredictNumber; 102 102 else if (statistics.arrays == statistics.samples) 103 prediction = StrongPredictionTag |PredictArray;103 prediction = PredictArray; 104 104 else if (statistics.finalObjects == statistics.samples) 105 prediction = StrongPredictionTag |PredictFinalObject;105 prediction = PredictFinalObject; 106 106 else if (statistics.strings == statistics.samples) 107 prediction = StrongPredictionTag |PredictString;107 prediction = PredictString; 108 108 else if (statistics.objects == statistics.samples) 109 prediction = StrongPredictionTag |PredictObjectOther;109 prediction = PredictObjectOther; 110 110 else if (statistics.cells == statistics.samples) 111 prediction = StrongPredictionTag |PredictCellOther;111 prediction = PredictCellOther; 112 112 else if (statistics.booleans == statistics.samples) 113 prediction = StrongPredictionTag |PredictBoolean;113 prediction = PredictBoolean; 114 114 else 115 prediction = StrongPredictionTag |PredictOther;115 prediction = PredictOther; 116 116 117 117 m_numberOfSamplesInPrediction += statistics.samples; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r95927 r95930 102 102 return getLocal((unsigned)operand); 103 103 } 104 void set(int operand, NodeIndex value, PredictedType weakPrediction = PredictNone) 105 { 106 m_graph.predict(operand, weakPrediction, WeakPrediction); 107 104 void set(int operand, NodeIndex value) 105 { 108 106 // Is this an argument? 109 107 if (operandIsArgument(operand)) { … … 437 435 PredictedType prediction = PredictNone; 438 436 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 439 prediction = get StrongPrediction(m_graph.size(), m_currentIndex + OPCODE_LENGTH(op_call));437 prediction = getPrediction(m_graph.size(), m_currentIndex + OPCODE_LENGTH(op_call)); 440 438 441 439 addVarArgChild(get(currentInstruction[1].u.operand)); … … 453 451 } 454 452 455 void weaklyPredictArray(NodeIndex nodeIndex) 456 { 457 m_graph.predict(m_graph[nodeIndex], PredictArray, WeakPrediction); 458 } 459 460 void weaklyPredictInt32(NodeIndex nodeIndex) 461 { 462 ASSERT(m_reusableNodeStack.isEmpty()); 463 m_reusableNodeStack.append(&m_graph[nodeIndex]); 464 465 do { 466 Node* nodePtr = m_reusableNodeStack.last(); 467 m_reusableNodeStack.removeLast(); 468 469 if (nodePtr->op == ValueToNumber) 470 nodePtr = &m_graph[nodePtr->child1()]; 471 472 if (nodePtr->op == ValueToInt32) 473 nodePtr = &m_graph[nodePtr->child1()]; 474 475 switch (nodePtr->op) { 476 case ArithAdd: 477 case ArithSub: 478 case ArithMul: 479 case ValueAdd: 480 m_reusableNodeStack.append(&m_graph[nodePtr->child1()]); 481 m_reusableNodeStack.append(&m_graph[nodePtr->child2()]); 482 break; 483 default: 484 m_graph.predict(*nodePtr, PredictInt32, WeakPrediction); 485 break; 486 } 487 } while (!m_reusableNodeStack.isEmpty()); 488 } 489 490 PredictedType getStrongPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex) 453 PredictedType getPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex) 491 454 { 492 455 UNUSED_PARAM(nodeIndex); … … 508 471 } 509 472 510 PredictedType get StrongPrediction()511 { 512 return get StrongPrediction(m_graph.size(), m_currentIndex);473 PredictedType getPrediction() 474 { 475 return getPrediction(m_graph.size(), m_currentIndex); 513 476 } 514 477 … … 772 735 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 773 736 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 774 weaklyPredictInt32(op1); 775 weaklyPredictInt32(op2); 776 set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2), PredictInt32); 737 set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2)); 777 738 NEXT_OPCODE(op_bitand); 778 739 } … … 781 742 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 782 743 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 783 weaklyPredictInt32(op1); 784 weaklyPredictInt32(op2); 785 set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2), PredictInt32); 744 set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2)); 786 745 NEXT_OPCODE(op_bitor); 787 746 } … … 790 749 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 791 750 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 792 weaklyPredictInt32(op1); 793 weaklyPredictInt32(op2); 794 set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2), PredictInt32); 751 set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2)); 795 752 NEXT_OPCODE(op_bitxor); 796 753 } … … 799 756 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 800 757 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 801 weaklyPredictInt32(op1);802 weaklyPredictInt32(op2);803 758 NodeIndex result; 804 759 // Optimize out shifts by zero. … … 807 762 else 808 763 result = addToGraph(BitRShift, op1, op2); 809 set(currentInstruction[1].u.operand, result , PredictInt32);764 set(currentInstruction[1].u.operand, result); 810 765 NEXT_OPCODE(op_rshift); 811 766 } … … 814 769 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 815 770 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 816 weaklyPredictInt32(op1);817 weaklyPredictInt32(op2);818 771 NodeIndex result; 819 772 // Optimize out shifts by zero. … … 822 775 else 823 776 result = addToGraph(BitLShift, op1, op2); 824 set(currentInstruction[1].u.operand, result , PredictInt32);777 set(currentInstruction[1].u.operand, result); 825 778 NEXT_OPCODE(op_lshift); 826 779 } … … 829 782 NodeIndex op1 = getToInt32(currentInstruction[2].u.operand); 830 783 NodeIndex op2 = getToInt32(currentInstruction[3].u.operand); 831 weaklyPredictInt32(op1);832 weaklyPredictInt32(op2);833 784 NodeIndex result; 834 785 // The result of a zero-extending right shift is treated as an unsigned value. … … 851 802 result = makeSafe(addToGraph(UInt32ToNumber, OpInfo(NodeUseBottom), result)); 852 803 } 853 set(currentInstruction[1].u.operand, result , PredictInt32);804 set(currentInstruction[1].u.operand, result); 854 805 NEXT_OPCODE(op_urshift); 855 806 } … … 860 811 unsigned srcDst = currentInstruction[1].u.operand; 861 812 NodeIndex op = getToNumber(srcDst); 862 weaklyPredictInt32(op);863 813 set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one()))); 864 814 NEXT_OPCODE(op_pre_inc); … … 869 819 unsigned srcDst = currentInstruction[2].u.operand; 870 820 NodeIndex op = getToNumber(srcDst); 871 weaklyPredictInt32(op);872 821 set(result, op); 873 822 set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one()))); … … 878 827 unsigned srcDst = currentInstruction[1].u.operand; 879 828 NodeIndex op = getToNumber(srcDst); 880 weaklyPredictInt32(op);881 829 set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one()))); 882 830 NEXT_OPCODE(op_pre_dec); … … 887 835 unsigned srcDst = currentInstruction[2].u.operand; 888 836 NodeIndex op = getToNumber(srcDst); 889 weaklyPredictInt32(op);890 837 set(result, op); 891 838 set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one()))); … … 898 845 NodeIndex op1 = get(currentInstruction[2].u.operand); 899 846 NodeIndex op2 = get(currentInstruction[3].u.operand); 900 // If both operands can statically be determined to the numbers, then this is an arithmetic add.901 // Otherwise, we must assume this may be performing a concatenation to a string.902 if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) {903 weaklyPredictInt32(op1);904 weaklyPredictInt32(op2);905 }906 907 847 if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult()) 908 848 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), toNumber(op1), toNumber(op2)))); … … 915 855 NodeIndex op1 = getToNumber(currentInstruction[2].u.operand); 916 856 NodeIndex op2 = getToNumber(currentInstruction[3].u.operand); 917 if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) {918 weaklyPredictInt32(op1);919 weaklyPredictInt32(op2);920 }921 922 857 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2))); 923 858 NEXT_OPCODE(op_sub); … … 1063 998 1064 999 case op_get_by_val: { 1065 PredictedType prediction = get StrongPrediction();1000 PredictedType prediction = getPrediction(); 1066 1001 1067 1002 NodeIndex base = get(currentInstruction[2].u.operand); 1068 1003 NodeIndex property = get(currentInstruction[3].u.operand); 1069 weaklyPredictArray(base);1070 weaklyPredictInt32(property);1071 1004 1072 1005 NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo(prediction), base, property); … … 1080 1013 NodeIndex property = get(currentInstruction[2].u.operand); 1081 1014 NodeIndex value = get(currentInstruction[3].u.operand); 1082 weaklyPredictArray(base);1083 weaklyPredictInt32(property);1084 1015 1085 1016 addToGraph(PutByVal, base, property, value); … … 1091 1022 Instruction* getInstruction = currentInstruction + OPCODE_LENGTH(op_method_check); 1092 1023 1093 PredictedType prediction = get StrongPrediction();1024 PredictedType prediction = getPrediction(); 1094 1025 1095 1026 ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id); … … 1125 1056 } 1126 1057 case op_get_scoped_var: { 1127 PredictedType prediction = get StrongPrediction();1058 PredictedType prediction = getPrediction(); 1128 1059 int dst = currentInstruction[1].u.operand; 1129 1060 int slot = currentInstruction[2].u.operand; … … 1143 1074 } 1144 1075 case op_get_by_id: { 1145 PredictedType prediction = get StrongPrediction();1076 PredictedType prediction = getPrediction(); 1146 1077 1147 1078 NodeIndex base = get(currentInstruction[2].u.operand); … … 1189 1120 1190 1121 case op_get_global_var: { 1191 PredictedType prediction = get StrongPrediction();1122 PredictedType prediction = getPrediction(); 1192 1123 1193 1124 NodeIndex getGlobalVar = addToGraph(GetGlobalVar, OpInfo(currentInstruction[2].u.operand)); 1194 1125 set(currentInstruction[1].u.operand, getGlobalVar); 1195 m_graph.predictGlobalVar(currentInstruction[2].u.operand, prediction & ~PredictionTagMask, StrongPrediction);1126 m_graph.predictGlobalVar(currentInstruction[2].u.operand, prediction); 1196 1127 NEXT_OPCODE(op_get_global_var); 1197 1128 } … … 1425 1356 1426 1357 case op_resolve: { 1427 PredictedType prediction = get StrongPrediction();1358 PredictedType prediction = getPrediction(); 1428 1359 1429 1360 unsigned identifier = currentInstruction[2].u.operand; … … 1436 1367 1437 1368 case op_resolve_base: { 1438 PredictedType prediction = get StrongPrediction();1369 PredictedType prediction = getPrediction(); 1439 1370 1440 1371 unsigned identifier = currentInstruction[2].u.operand; … … 1447 1378 1448 1379 case op_resolve_global: { 1449 PredictedType prediction = get StrongPrediction();1380 PredictedType prediction = getPrediction(); 1450 1381 1451 1382 NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction)); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r95901 r95930 207 207 size_t numberOfArguments = std::min(exec->argumentCountIncludingThis(), m_predictions.numberOfArguments()); 208 208 209 for (size_t arg = 1; arg < numberOfArguments; ++arg) { 210 JSValue argumentValue = exec->argument(arg - 1); 211 if (argumentValue.isInt32()) 212 m_predictions.predictArgument(arg, PredictInt32, WeakPrediction); 213 else if (argumentValue.isDouble()) 214 m_predictions.predictArgument(arg, PredictDouble, WeakPrediction); 215 } 209 for (size_t arg = 1; arg < numberOfArguments; ++arg) 210 m_predictions.predictArgument(arg, predictionFromValue(exec->argument(arg - 1))); 216 211 } 217 212 … … 221 216 CodeBlock* profiledCodeBlock = codeBlock->alternative(); 222 217 ASSERT(codeBlock->m_numParameters >= 1); 223 for (size_t arg = 1; arg < static_cast<size_t>(codeBlock->m_numParameters); ++arg) {218 for (size_t arg = 0; arg < static_cast<size_t>(codeBlock->m_numParameters); ++arg) { 224 219 ValueProfile* profile = profiledCodeBlock->valueProfileForArgument(arg); 225 220 if (!profile) 226 221 continue; 227 222 228 m_predictions.predictArgument(arg, profile->computeUpdatedPrediction() & ~PredictionTagMask, StrongPrediction);223 m_predictions.predictArgument(arg, profile->computeUpdatedPrediction()); 229 224 230 225 #if ENABLE(DFG_DEBUG_VERBOSE) -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r95901 r95930 177 177 } 178 178 179 bool predict(int operand, PredictedType prediction , PredictionSource source)180 { 181 return m_predictions.predict(operand, prediction , source);182 } 183 184 bool predictGlobalVar(unsigned varNumber, PredictedType prediction , PredictionSource source)185 { 186 return m_predictions.predictGlobalVar(varNumber, prediction , source);187 } 188 189 bool predict(Node& node, PredictedType prediction , PredictionSource source)179 bool predict(int operand, PredictedType prediction) 180 { 181 return m_predictions.predict(operand, prediction); 182 } 183 184 bool predictGlobalVar(unsigned varNumber, PredictedType prediction) 185 { 186 return m_predictions.predictGlobalVar(varNumber, prediction); 187 } 188 189 bool predict(Node& node, PredictedType prediction) 190 190 { 191 191 switch (node.op) { 192 192 case GetLocal: 193 return predict(node.local(), prediction , source);193 return predict(node.local(), prediction); 194 194 break; 195 195 case GetGlobalVar: 196 return predictGlobalVar(node.varNumber(), prediction , source);196 return predictGlobalVar(node.varNumber(), prediction); 197 197 break; 198 198 case GetById: … … 207 207 case ResolveBaseStrictPut: 208 208 case ResolveGlobal: 209 return node.predict(prediction , source);209 return node.predict(prediction); 210 210 default: 211 211 return false; … … 225 225 PredictedType getMethodCheckPrediction(Node& node) 226 226 { 227 return makePrediction(predictionFromCell(m_methodCheckData[node.methodCheckDataIndex()].function), StrongPrediction); 228 } 229 230 PredictedType getPrediction(Node& node) 227 return predictionFromCell(m_methodCheckData[node.methodCheckDataIndex()].function); 228 } 229 230 PredictedType getJSConstantPrediction(Node& node, CodeBlock* codeBlock) 231 { 232 return predictionFromValue(node.valueOfJSConstantNode(codeBlock)); 233 } 234 235 PredictedType getPrediction(Node& node, CodeBlock* codeBlock) 231 236 { 232 237 Node* nodePtr = &node; … … 252 257 case CheckMethod: 253 258 return getMethodCheckPrediction(*nodePtr); 259 case JSConstant: 260 return getJSConstantPrediction(*nodePtr, codeBlock); 254 261 default: 255 262 return PredictNone; -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
r95927 r95930 1230 1230 JITCompiler::Jump rhsNotCell; 1231 1231 bool hadCellCheck = false; 1232 if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.g raph().getPrediction(m_jit.graph()[valueIndex]))) {1232 if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) { 1233 1233 hadCellCheck = true; 1234 1234 rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); … … 1271 1271 JITCompiler::Jump rhsNotCell; 1272 1272 bool hadCellCheck = false; 1273 if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.g raph().getPrediction(m_jit.graph()[valueIndex]))) {1273 if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) { 1274 1274 hadCellCheck = true; 1275 1275 rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); … … 1797 1797 GPRReg resultGPR = result.gpr(); 1798 1798 1799 bool predictBoolean = isBooleanPrediction(m_jit.g raph().getPrediction(m_jit.graph()[node.child1()]));1799 bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1())); 1800 1800 1801 1801 if (predictBoolean) { -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r95902 r95930 273 273 bool valueOfBooleanConstant(NodeIndex nodeIndex) { return graph().valueOfBooleanConstant(codeBlock(), nodeIndex); } 274 274 JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return graph().valueOfFunctionConstant(codeBlock(), nodeIndex); } 275 276 // Helper methods to get predictions 277 PredictedType getPrediction(Node& node) { return graph().getPrediction(node, codeBlock()); } 278 PredictedType getPrediction(NodeIndex nodeIndex) { return getPrediction(graph()[nodeIndex]); } 275 279 276 280 #if USE(JSVALUE32_64) -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r95916 r95930 427 427 } 428 428 429 // NOTE: this only works for JSConstant nodes. 430 JSValue valueOfJSConstantNode(CodeBlock* codeBlock) 431 { 432 return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get(); 433 } 434 429 435 bool isInt32Constant(CodeBlock* codeBlock) 430 436 { 431 return isConstant() && valueOfJSConstant (codeBlock).isInt32();437 return isConstant() && valueOfJSConstantNode(codeBlock).isInt32(); 432 438 } 433 439 434 440 bool isDoubleConstant(CodeBlock* codeBlock) 435 441 { 436 bool result = isConstant() && valueOfJSConstant (codeBlock).isDouble();442 bool result = isConstant() && valueOfJSConstantNode(codeBlock).isDouble(); 437 443 if (result) 438 444 ASSERT(!isInt32Constant(codeBlock)); … … 442 448 bool isNumberConstant(CodeBlock* codeBlock) 443 449 { 444 bool result = isConstant() && valueOfJSConstant (codeBlock).isNumber();450 bool result = isConstant() && valueOfJSConstantNode(codeBlock).isNumber(); 445 451 ASSERT(result == (isInt32Constant(codeBlock) || isDoubleConstant(codeBlock))); 446 452 return result; … … 449 455 bool isBooleanConstant(CodeBlock* codeBlock) 450 456 { 451 return isConstant() && valueOfJSConstant (codeBlock).isBoolean();457 return isConstant() && valueOfJSConstantNode(codeBlock).isBoolean(); 452 458 } 453 459 … … 656 662 } 657 663 658 bool predict(PredictedType prediction , PredictionSource source)664 bool predict(PredictedType prediction) 659 665 { 660 666 ASSERT(hasPrediction()); 661 667 662 // We have previously found empirically that ascribing static predictions 663 // to heap loads as well as calls is not profitable, as these predictions 664 // are wrong too often. Hence, this completely ignores static predictions. 665 if (source == WeakPrediction) 666 return false; 667 668 if (prediction == PredictNone) 669 return false; 670 671 ASSERT(source == StrongPrediction); 672 673 return mergePrediction(m_opInfo2, makePrediction(prediction, source)); 668 return mergePrediction(m_opInfo2, prediction); 674 669 } 675 670 … … 804 799 805 800 private: 806 // This is private because it only works for the JSConstant op. The DFG is written under the807 // assumption that "valueOfJSConstant" can correctly return a constant for any DFG node for808 // which hasConstant() is true.809 JSValue valueOfJSConstant(CodeBlock* codeBlock)810 {811 return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();812 }813 814 801 // The virtual register number (spill location) associated with this . 815 802 VirtualRegister m_virtualRegister; -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r95916 r95930 48 48 m_predictions.resize(m_graph.size()); 49 49 50 // Uses is a backward flow property that propagates the hard expectations at51 // certain uses to their value sources, ensuring that predictions about52 // values do not contravene the code itself. This comes up only in the53 // cases of obvious cell uses, like GetById and friends as well as Call.54 // We're essentially statically speculating that if the value profile indicates55 // that only booleans (for example) flow into a GetById, then the value56 // profile is simply wrong due to insufficient coverage and needs to be57 // adjusted accordingly. The alternatives would be to assume either58 // that the GetById never executes, or always executes on a boolean leading59 // to whatever bizarre behavior that's supposed to cause.60 m_uses.resize(m_graph.size());61 m_variableUses.initializeSimilarTo(m_graph.predictions());62 63 50 // Replacements are used to implement local common subexpression elimination. 64 51 m_replacements.resize(m_graph.size()); … … 66 53 for (unsigned i = 0; i < m_graph.size(); ++i) { 67 54 m_predictions[i] = PredictNone; 68 m_uses[i] = PredictNone;69 55 m_replacements[i] = NoNode; 70 56 } … … 307 293 } 308 294 309 bool mergeUse(NodeIndex nodeIndex, PredictedType prediction)310 {311 ASSERT(m_graph[nodeIndex].hasResult());312 313 return JSC::mergePrediction(m_uses[nodeIndex], prediction);314 }315 316 295 bool mergePrediction(PredictedType prediction) 317 296 { … … 336 315 switch (op) { 337 316 case JSConstant: { 338 changed |= setPrediction( makePrediction(predictionFromValue(m_graph.valueOfJSConstant(m_codeBlock, m_compileIndex)), StrongPrediction));317 changed |= setPrediction(predictionFromValue(m_graph.valueOfJSConstant(m_codeBlock, m_compileIndex))); 339 318 break; 340 319 } 341 320 342 321 case GetLocal: { 343 changed |= m_graph.predict(node.local(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);344 changed |= m_variableUses.predict(node.local(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);345 346 322 PredictedType prediction = m_graph.getPrediction(node.local()); 347 if ( isStrongPrediction(prediction))323 if (prediction) 348 324 changed |= mergePrediction(prediction); 349 325 break; … … 351 327 352 328 case SetLocal: { 353 changed |= m_graph.predict(node.local(), m_predictions[node.child1()] & ~PredictionTagMask, StrongPrediction); 354 changed |= mergeUse(node.child1(), m_variableUses.getPrediction(node.local())); 329 changed |= m_graph.predict(node.local(), m_predictions[node.child1()]); 355 330 break; 356 331 } … … 363 338 case BitURShift: 364 339 case ValueToInt32: { 365 changed |= setPrediction( makePrediction(PredictInt32, StrongPrediction));340 changed |= setPrediction(PredictInt32); 366 341 break; 367 342 } … … 371 346 PredictedType right = m_predictions[node.child2()]; 372 347 373 if ( isStrongPrediction(left) && isStrongPrediction(right)) {348 if (left && right) { 374 349 if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) 375 changed |= mergePrediction( makePrediction(PredictInt32, StrongPrediction));350 changed |= mergePrediction(PredictInt32); 376 351 else 377 changed |= mergePrediction( makePrediction(PredictDouble, StrongPrediction));352 changed |= mergePrediction(PredictDouble); 378 353 } 379 354 break; … … 382 357 case UInt32ToNumber: { 383 358 if (nodeCanSpeculateInteger(node.arithNodeFlags())) 384 changed |= setPrediction( makePrediction(PredictInt32, StrongPrediction));359 changed |= setPrediction(PredictInt32); 385 360 else 386 changed |= setPrediction( makePrediction(PredictNumber, StrongPrediction));361 changed |= setPrediction(PredictNumber); 387 362 break; 388 363 } … … 391 366 PredictedType prediction = m_predictions[node.child1()]; 392 367 393 if ( isStrongPrediction(prediction)) {368 if (prediction) { 394 369 if (!(prediction & PredictDouble) && nodeCanSpeculateInteger(node.arithNodeFlags())) 395 changed |= mergePrediction( makePrediction(PredictInt32, StrongPrediction));370 changed |= mergePrediction(PredictInt32); 396 371 else 397 changed |= mergePrediction( makePrediction(PredictNumber, StrongPrediction));372 changed |= mergePrediction(PredictNumber); 398 373 } 399 374 … … 412 387 PredictedType right = m_predictions[node.child2()]; 413 388 414 if ( isStrongPrediction(left) && isStrongPrediction(right)) {389 if (left && right) { 415 390 if (isNumberPrediction(left) && isNumberPrediction(right)) { 416 391 if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) 417 changed |= mergePrediction( makePrediction(PredictInt32, StrongPrediction));392 changed |= mergePrediction(PredictInt32); 418 393 else 419 changed |= mergePrediction( makePrediction(PredictDouble, StrongPrediction));394 changed |= mergePrediction(PredictDouble); 420 395 } else if (!(left & PredictNumber) || !(right & PredictNumber)) { 421 396 // left or right is definitely something other than a number. 422 changed |= mergePrediction( makePrediction(PredictString, StrongPrediction));397 changed |= mergePrediction(PredictString); 423 398 } else 424 changed |= mergePrediction( makePrediction(PredictString | PredictInt32 | PredictDouble, StrongPrediction));399 changed |= mergePrediction(PredictString | PredictInt32 | PredictDouble); 425 400 } 426 401 break; … … 436 411 PredictedType right = m_predictions[node.child2()]; 437 412 438 if ( isStrongPrediction(left) && isStrongPrediction(right)) {413 if (left && right) { 439 414 if (isInt32Prediction(mergePredictions(left, right)) && nodeCanSpeculateInteger(node.arithNodeFlags())) 440 changed |= mergePrediction( makePrediction(PredictInt32, StrongPrediction));415 changed |= mergePrediction(PredictInt32); 441 416 else 442 changed |= mergePrediction( makePrediction(PredictDouble, StrongPrediction));417 changed |= mergePrediction(PredictDouble); 443 418 } 444 419 break; … … 446 421 447 422 case ArithSqrt: { 448 changed |= setPrediction( makePrediction(PredictDouble, StrongPrediction));423 changed |= setPrediction(PredictDouble); 449 424 break; 450 425 } … … 452 427 case ArithAbs: { 453 428 PredictedType child = m_predictions[node.child1()]; 454 if ( isStrongPrediction(child)) {429 if (child) { 455 430 if (nodeCanSpeculateInteger(node.arithNodeFlags())) 456 431 changed |= mergePrediction(child); 457 432 else 458 changed |= setPrediction( makePrediction(PredictDouble, StrongPrediction));433 changed |= setPrediction(PredictDouble); 459 434 } 460 435 break; … … 469 444 case CompareStrictEq: 470 445 case InstanceOf: { 471 changed |= setPrediction( makePrediction(PredictBoolean, StrongPrediction));446 changed |= setPrediction(PredictBoolean); 472 447 break; 473 448 } … … 476 451 case GetMethod: 477 452 case GetByVal: { 478 changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag); 479 changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction); 480 if (isStrongPrediction(node.getPrediction())) 453 if (node.getPrediction()) 481 454 changed |= mergePrediction(node.getPrediction()); 482 455 break; … … 484 457 485 458 case CheckStructure: { 486 // We backward propagate what this CheckStructure tells us. Maybe that's the right way 487 // to go; maybe it isn't. I'm not sure. What we'd really want is flow-sensitive 488 // forward propagation of what we learn from having executed CheckStructure. But for 489 // now we preserve the flow-insensitive nature of this analysis, because it's cheap to 490 // run and seems to work well enough. 491 changed |= mergeUse(node.child1(), predictionFromStructure(node.structure()) | StrongPredictionTag); 492 changed |= setPrediction(PredictOther | StrongPredictionTag); 459 changed |= setPrediction(PredictOther); 493 460 break; 494 461 } 495 462 496 463 case GetByOffset: { 497 changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction); 498 if (isStrongPrediction(node.getPrediction())) 464 if (node.getPrediction()) 499 465 changed |= mergePrediction(node.getPrediction()); 500 466 break; … … 502 468 503 469 case CheckMethod: { 504 changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);505 470 changed |= setPrediction(m_graph.getMethodCheckPrediction(node)); 506 471 break; … … 509 474 case Call: 510 475 case Construct: { 511 changed |= mergeUse(m_graph.m_varArgChildren[node.firstChild()], PredictObjectUnknown | StrongPredictionTag); 512 changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction); 513 if (isStrongPrediction(node.getPrediction())) 476 if (node.getPrediction()) 514 477 changed |= mergePrediction(node.getPrediction()); 515 478 break; … … 517 480 518 481 case ConvertThis: { 519 changed |= setPrediction( makePrediction(PredictObjectUnknown, StrongPrediction));482 changed |= setPrediction(PredictObjectUnknown); 520 483 break; 521 484 } 522 485 523 486 case GetGlobalVar: { 524 changed |= m_variableUses.predictGlobalVar(node.varNumber(), m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);525 487 PredictedType prediction = m_graph.getGlobalVarPrediction(node.varNumber()); 526 if ( isStrongPrediction(prediction))488 if (prediction) 527 489 changed |= mergePrediction(prediction); 528 490 break; … … 530 492 531 493 case PutGlobalVar: { 532 changed |= m_graph.predictGlobalVar(node.varNumber(), m_predictions[node.child1()] & ~PredictionTagMask, StrongPrediction); 533 changed |= mergeUse(node.child1(), m_variableUses.getGlobalVarPrediction(node.varNumber())); 494 changed |= m_graph.predictGlobalVar(node.varNumber(), m_predictions[node.child1()]); 534 495 break; 535 496 } … … 540 501 case ResolveBaseStrictPut: 541 502 case ResolveGlobal: { 542 changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);543 503 PredictedType prediction = node.getPrediction(); 544 if ( isStrongPrediction(prediction))504 if (prediction) 545 505 changed |= mergePrediction(prediction); 546 506 break; … … 548 508 549 509 case GetScopeChain: { 550 changed |= setPrediction(makePrediction(PredictCellOther, StrongPrediction)); 551 break; 552 } 553 554 case PutByVal: 555 case PutByValAlias: 556 case PutById: 557 case PutByIdDirect: { 558 changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag); 559 break; 560 } 561 510 changed |= setPrediction(PredictCellOther); 511 break; 512 } 513 562 514 case GetCallee: { 563 changed |= setPrediction( makePrediction(PredictObjectOther, StrongPrediction));515 changed |= setPrediction(PredictObjectOther); 564 516 break; 565 517 } 566 518 567 519 case CreateThis: { 568 changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag); 569 changed |= setPrediction(makePrediction(PredictFinalObject, StrongPrediction)); 520 changed |= setPrediction(PredictFinalObject); 570 521 break; 571 522 } 572 523 573 524 case StrCat: { 574 changed |= setPrediction( makePrediction(PredictString, StrongPrediction));525 changed |= setPrediction(PredictString); 575 526 break; 576 527 } … … 578 529 case ToPrimitive: { 579 530 PredictedType child = m_predictions[node.child1()]; 580 if ( isStrongPrediction(child)) {531 if (child) { 581 532 if (isObjectPrediction(child)) { 582 533 // I'd love to fold this case into the case below, but I can't, because … … 585 536 // (strong predict-none). This should be killed once we remove all traces 586 537 // of static (aka weak) predictions. 587 changed |= mergePrediction( makePrediction(PredictString, StrongPrediction));538 changed |= mergePrediction(PredictString); 588 539 } else if (child & PredictObjectMask) { 589 540 // Objects get turned into strings. So if the input has hints of objectness, 590 541 // the output will have hinsts of stringiness. 591 changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, makePrediction(PredictString, StrongPrediction)));542 changed |= mergePrediction(mergePredictions(child & ~PredictObjectMask, PredictString)); 592 543 } else 593 544 changed |= mergePrediction(child); … … 612 563 // This gets ignored because it doesn't do anything. 613 564 case Phantom: 565 case PutByVal: 566 case PutByValAlias: 567 case PutById: 568 case PutByIdDirect: 614 569 break; 615 570 #else … … 620 575 621 576 #if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE) 622 printf("expect(%s) ", predictionToString(m_predictions[m_compileIndex])); 623 printf("use(%s) %s\n", predictionToString(m_uses[m_compileIndex]), changed ? "CHANGED" : ""); 577 printf("%s ", predictionToString(m_predictions[m_compileIndex])); 624 578 #endif 625 579 … … 677 631 PredictedType right = m_predictions[node.child2()]; 678 632 679 if ( isStrongPrediction(left) && isStrongPrediction(right)&& isNumberPrediction(left) && isNumberPrediction(right)) {633 if (left && right && isNumberPrediction(left) && isNumberPrediction(right)) { 680 634 if (left & PredictDouble) 681 635 toDouble(node.child2()); … … 702 656 PredictedType right = m_predictions[node.child2()]; 703 657 704 if ( isStrongPrediction(left) && isStrongPrediction(right)) {658 if (left && right) { 705 659 if (left & PredictDouble) 706 660 toDouble(node.child2()); … … 718 672 719 673 PredictedType prediction = m_predictions[node.child1()]; 720 if ( isStrongPrediction(prediction) && (prediction & PredictDouble))674 if (prediction & PredictDouble) 721 675 toDouble(node.child1()); 722 676 break; … … 867 821 PredictedType left = m_predictions[node.child1()]; 868 822 PredictedType right = m_predictions[node.child2()]; 869 return isStrongPrediction(left) && isStrongPrediction(right) 870 && isNumberPrediction(left) && isNumberPrediction(right); 823 return isNumberPrediction(left) && isNumberPrediction(right); 871 824 } 872 825 … … 874 827 { 875 828 PredictedType prediction = m_predictions[node.child1()]; 876 return isBooleanPrediction(prediction) || ! isStrongPrediction(prediction);829 return isBooleanPrediction(prediction) || !prediction; 877 830 } 878 831 … … 1233 1186 1234 1187 Vector<PredictedType, 16> m_predictions; 1235 Vector<PredictedType, 16> m_uses;1236 1237 PredictionTracker m_variableUses;1238 1188 1239 1189 #if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r95916 r95930 696 696 697 697 case GetLocal: { 698 PredictedType prediction = m_jit.graph().getPrediction(node.local()); 699 700 // If we have no prediction for this local, then don't attempt to compile. 701 if (prediction == PredictNone) { 702 terminateSpeculativeExecution(); 703 break; 704 } 705 698 706 GPRTemporary result(this); 699 PredictedType prediction = m_jit.graph().getPrediction(node.local());700 707 if (isInt32Prediction(prediction)) { 701 708 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr()); … … 1301 1308 } 1302 1309 1303 PredictedType prediction = m_jit.g raph().getPrediction(m_jit.graph()[node.child1()]);1304 if (isBooleanPrediction(prediction) || ! isStrongPrediction(prediction)) {1310 PredictedType prediction = m_jit.getPrediction(node.child1()); 1311 if (isBooleanPrediction(prediction) || !prediction) { 1305 1312 JSValueOperand value(this, node.child1()); 1306 1313 GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add). -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r95910 r95930 371 371 return true; 372 372 373 if (isInt32Prediction(m_jit.g raph().getPrediction(m_jit.graph()[nodeIndex])))373 if (isInt32Prediction(m_jit.getPrediction(nodeIndex))) 374 374 return true; 375 375 … … 390 390 return true; 391 391 392 if (isDoublePrediction(m_jit.g raph().getPrediction(node)))392 if (isDoublePrediction(m_jit.getPrediction(nodeIndex))) 393 393 return true; 394 394 … … 412 412 return true; 413 413 414 PredictedType prediction = m_jit.g raph().getPrediction(node);414 PredictedType prediction = m_jit.getPrediction(nodeIndex); 415 415 416 416 if (isNumberPrediction(prediction) || prediction == PredictNone) … … 433 433 return true; 434 434 435 if (m_jit.g raph().getPrediction(node) & PredictDouble)435 if (m_jit.getPrediction(nodeIndex) & PredictDouble) 436 436 return true; 437 437 … … 445 445 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 446 446 else 447 prediction = m_jit.g raph().getPrediction(m_jit.graph()[nodeIndex]);447 prediction = m_jit.getPrediction(nodeIndex); 448 448 return isFinalObjectPrediction(prediction); 449 449 } … … 455 455 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 456 456 else 457 prediction = m_jit.g raph().getPrediction(m_jit.graph()[nodeIndex]);457 prediction = m_jit.getPrediction(nodeIndex); 458 458 return isArrayPrediction(prediction); 459 459 } … … 468 468 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 469 469 else 470 prediction = m_jit.g raph().getPrediction(m_jit.graph()[nodeIndex]);470 prediction = m_jit.getPrediction(nodeIndex); 471 471 return isObjectPrediction(prediction); 472 472 } … … 479 479 Node& node = m_jit.graph()[nodeIndex]; 480 480 481 if (isCellPrediction(m_jit.g raph().getPrediction(node)))481 if (isCellPrediction(m_jit.getPrediction(nodeIndex))) 482 482 return true; 483 483 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r95916 r95930 555 555 #if ENABLE(VALUE_PROFILER) 556 556 ASSERT(m_bytecodeOffset == (unsigned)-1); 557 for (int argumentRegister = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters + 1; argumentRegister < -RegisterFile::CallFrameHeaderSize; ++argumentRegister) { 558 loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0); 559 emitValueProfilingSite(FirstProfilingSite); 557 if (shouldEmitProfiling()) { 558 for (int argumentRegister = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters; argumentRegister < -RegisterFile::CallFrameHeaderSize; ++argumentRegister) { 559 // If this is a constructor, then we want to put in a dummy profiling site (to 560 // keep things consistent) but we don't actually want to record the dummy value. 561 if (m_codeBlock->m_isConstructor 562 && argumentRegister == -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters) 563 m_codeBlock->addValueProfile(-1); 564 else { 565 loadPtr(Address(callFrameRegister, argumentRegister * sizeof(Register)), regT0); 566 emitValueProfilingSite(FirstProfilingSite); 567 } 568 } 560 569 } 561 570 #endif
Note: See TracChangeset
for help on using the changeset viewer.