Changeset 92593 in webkit
- Timestamp:
- Aug 8, 2011 5:50:59 AM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r92573 r92593 1 2011-08-08 Filip Pizlo <fpizlo@apple.com> 2 3 DFG JIT does not track speculation decisions for global variables 4 https://bugs.webkit.org/show_bug.cgi?id=65825 5 6 Reviewed by Gavin Barraclough. 7 8 Added the capability to track predictions for global variables, and 9 ensured that code can abstract over the source of prediction (local 10 versus global variable) wherever it is appropriate to do so. Also 11 cleaned up the code in SpeculativeJIT that decides how to speculate 12 based on recorded predictions (for example instead of using isInteger, 13 which makes sense for local predictions where the GetLocal would 14 return an integer value, we now tend to use shouldSpeculateInteger, 15 which checks if the value is either already an integer or should be 16 speculated to be an integer). 17 18 This is an 0.8% win on SunSpider, almost entirely thanks to a 25% 19 win on controlflow-recursive. It's also a 4.8% win on v8-crypto. 20 21 * dfg/DFGByteCodeParser.cpp: 22 (JSC::DFG::ByteCodeParser::predictArray): 23 (JSC::DFG::ByteCodeParser::predictInt32): 24 (JSC::DFG::ByteCodeParser::parseBlock): 25 * dfg/DFGGraph.cpp: 26 (JSC::DFG::Graph::dump): 27 * dfg/DFGGraph.h: 28 (JSC::DFG::Graph::predictGlobalVar): 29 (JSC::DFG::Graph::predict): 30 (JSC::DFG::Graph::getGlobalVarPrediction): 31 (JSC::DFG::Graph::getPrediction): 32 * dfg/DFGSpeculativeJIT.cpp: 33 (JSC::DFG::SpeculativeJIT::compile): 34 * dfg/DFGSpeculativeJIT.h: 35 (JSC::DFG::SpeculativeJIT::shouldSpeculateInteger): 36 (JSC::DFG::SpeculativeJIT::shouldSpeculateDouble): 37 1 38 2011-08-07 Martin Robinson <mrobinson@igalia.com> 2 39 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r91728 r92593 431 431 void predictArray(NodeIndex nodeIndex) 432 432 { 433 Node* nodePtr = &m_graph[nodeIndex]; 434 435 if (nodePtr->op == GetLocal) 436 m_graph.predict(nodePtr->local(), PredictArray); 433 m_graph.predict(m_graph[nodeIndex], PredictArray); 437 434 } 438 435 … … 446 443 if (nodePtr->op == ValueToInt32) 447 444 nodePtr = &m_graph[nodePtr->child1()]; 448 449 if (nodePtr->op == GetLocal) 450 m_graph.predict(nodePtr->local(), PredictInt32); 445 446 m_graph.predict(*nodePtr, PredictInt32); 451 447 } 452 448 … … 702 698 // If both operands can statically be determined to the numbers, then this is an arithmetic add. 703 699 // Otherwise, we must assume this may be performing a concatenation to a string. 704 if ( m_graph[op1].hasNumericResult() && m_graph[op2].hasNumericResult()) {705 if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) {706 predictInt32(op1);707 predictInt32(op2);708 }700 if (isSmallInt32Constant(op1) || isSmallInt32Constant(op2)) { 701 predictInt32(op1); 702 predictInt32(op2); 703 } 704 if (m_graph[op1].hasNumericResult() && m_graph[op2].hasNumericResult()) 709 705 set(currentInstruction[1].u.operand, addToGraph(ArithAdd, toNumber(op1), toNumber(op2))); 710 }else706 else 711 707 set(currentInstruction[1].u.operand, addToGraph(ValueAdd, op1, op2)); 712 708 NEXT_OPCODE(op_add); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r92038 r92593 137 137 if (node.hasLocal()) 138 138 printf(" predicting %s", predictionToString(getPrediction(node.local()))); 139 if (node.hasVarNumber()) 140 printf(" predicting %s", predictionToString(getGlobalVarPrediction(node.varNumber()))); 139 141 140 142 printf("\n"); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r92038 r92593 31 31 #include <RegisterFile.h> 32 32 #include <dfg/DFGNode.h> 33 #include <wtf/HashMap.h> 33 34 #include <wtf/Vector.h> 34 35 #include <wtf/StdLibExtras.h> … … 195 196 } else if ((unsigned)operand < m_variablePredictions.size()) 196 197 m_variablePredictions[operand].m_value |= prediction; 197 198 } 199 200 void predictGlobalVar(unsigned varNumber, PredictedType prediction) 201 { 202 HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVarPredictions.find(varNumber + 1); 203 if (iter == m_globalVarPredictions.end()) { 204 PredictionSlot predictionSlot; 205 predictionSlot.m_value |= prediction; 206 m_globalVarPredictions.add(varNumber + 1, predictionSlot); 207 } else 208 iter->second.m_value |= prediction; 209 } 210 211 void predict(Node& node, PredictedType prediction) 212 { 213 switch (node.op) { 214 case GetLocal: 215 predict(node.local(), prediction); 216 break; 217 case GetGlobalVar: 218 predictGlobalVar(node.varNumber(), prediction); 219 break; 220 default: 221 break; 222 } 198 223 } 199 224 … … 208 233 return PredictNone; 209 234 } 235 236 PredictedType getGlobalVarPrediction(unsigned varNumber) 237 { 238 HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVarPredictions.find(varNumber + 1); 239 if (iter == m_globalVarPredictions.end()) 240 return PredictNone; 241 return iter->second.m_value; 242 } 243 244 PredictedType getPrediction(Node& node) 245 { 246 Node* nodePtr = &node; 247 248 if (nodePtr->op == ValueToNumber) 249 nodePtr = &(*this)[nodePtr->child1()]; 250 251 if (nodePtr->op == ValueToInt32) 252 nodePtr = &(*this)[nodePtr->child1()]; 253 254 switch (nodePtr->op) { 255 case GetLocal: 256 return getPrediction(nodePtr->local()); 257 case GetGlobalVar: 258 return getGlobalVarPrediction(nodePtr->varNumber()); 259 default: 260 return PredictNone; 261 } 262 } 210 263 211 264 #ifndef NDEBUG … … 224 277 Vector<PredictionSlot, 16> m_argumentPredictions; 225 278 Vector<PredictionSlot, 16> m_variablePredictions; 279 HashMap<unsigned, PredictionSlot> m_globalVarPredictions; 226 280 }; 227 281 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r92148 r92593 655 655 656 656 case ValueToNumber: { 657 if ( isInteger(node.child1())) {657 if (shouldSpeculateInteger(node.child1())) { 658 658 SpeculateIntegerOperand op1(this, node.child1()); 659 659 GPRTemporary result(this, op1); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r92148 r92593 156 156 || (info.spillFormat() | DataFormatJS) == DataFormatJSInteger; 157 157 } 158 159 bool isRegisterDataFormatDouble(NodeIndex nodeIndex) 158 159 bool shouldSpeculateInteger(NodeIndex nodeIndex) 160 { 161 if (isInteger(nodeIndex)) 162 return true; 163 164 if (isInt32Prediction(m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]))) 165 return true; 166 167 return false; 168 } 169 170 bool shouldSpeculateDouble(NodeIndex nodeIndex) 160 171 { 161 172 Node& node = m_jit.graph()[nodeIndex]; … … 167 178 return true; 168 179 169 if ( node.op == GetLocal && isDoublePrediction(m_jit.graph().getPrediction(node.local())))180 if (isDoublePrediction(m_jit.graph().getPrediction(node))) 170 181 return true; 171 182 … … 175 186 bool shouldSpeculateInteger(NodeIndex op1, NodeIndex op2) 176 187 { 177 return !( isRegisterDataFormatDouble(op1) || isRegisterDataFormatDouble(op2)) && (isInteger(op1) || isInteger(op2));188 return !(shouldSpeculateDouble(op1) || shouldSpeculateDouble(op2)) && (shouldSpeculateInteger(op1) || shouldSpeculateInteger(op2)); 178 189 } 179 190
Note: See TracChangeset
for help on using the changeset viewer.