Changeset 91894 in webkit
- Timestamp:
- Jul 27, 2011, 8:25:19 PM (14 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r91883 r91894 1 2011-07-27 Filip Pizlo <fpizlo@apple.com> 2 3 DFG graph has no notion of double prediction. 4 https://bugs.webkit.org/show_bug.cgi?id=65234 5 6 Reviewed by Gavin Barraclough. 7 8 Added the notion of PredictDouble, and PredictNumber, which is the least 9 upper bound of PredictInt32 and PredictDouble. Least upper bound is 10 defined as the bitwise-or of two predictions. Bottom is defined as 0, 11 and Top is defined as all bits being set. Added the ability to explicitly 12 distinguish between a node having had a prediction associated with it, 13 and that prediction still being valid (i.e. no conflicting predictions 14 have also been added). Used this to guard the speculative JIT from 15 speculating Int32 in cases where the graph knows that the value is 16 double, which currently only happens for GetLocal nodes on arguments 17 which were double at compile-time. 18 19 * dfg/DFGGraph.cpp: 20 (JSC::DFG::Graph::predictArgumentTypes): 21 * dfg/DFGGraph.h: 22 (JSC::DFG::isCellPrediction): 23 (JSC::DFG::isArrayPrediction): 24 (JSC::DFG::isInt32Prediction): 25 (JSC::DFG::isDoublePrediction): 26 (JSC::DFG::isNumberPrediction): 27 * dfg/DFGSpeculativeJIT.cpp: 28 (JSC::DFG::SpeculativeJIT::compile): 29 (JSC::DFG::SpeculativeJIT::checkArgumentTypes): 30 (JSC::DFG::SpeculativeJIT::initializeVariableTypes): 31 * dfg/DFGSpeculativeJIT.h: 32 (JSC::DFG::SpeculativeJIT::isRegisterDataFormatDouble): 33 1 34 2011-07-27 Gavin Barraclough <barraclough@apple.com> 2 35 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r91115 r91894 182 182 183 183 for (size_t arg = 1; arg < numberOfArguments; ++arg) { 184 if (exec->argument(arg - 1).isInt32()) 184 JSValue argumentValue = exec->argument(arg - 1); 185 if (argumentValue.isInt32()) 185 186 m_argumentPredictions[arg].m_value |= PredictInt32; 187 else if (argumentValue.isDouble()) 188 m_argumentPredictions[arg].m_value |= PredictDouble; 186 189 } 187 190 } -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r91131 r91894 45 45 46 46 typedef uint8_t PredictedType; 47 static const PredictedType PredictNone = 0; 48 static const PredictedType PredictCell = 0x01; 49 static const PredictedType PredictArray = 0x03; 50 static const PredictedType PredictInt32 = 0x04; 47 static const PredictedType PredictNone = 0; 48 static const PredictedType PredictCell = 0x01; 49 static const PredictedType PredictArray = 0x03; 50 static const PredictedType PredictInt32 = 0x04; 51 static const PredictedType PredictDouble = 0x08; 52 static const PredictedType PredictNumber = 0x0c; 53 54 inline bool isCellPrediction(PredictedType value) 55 { 56 return (value & PredictCell) == PredictCell && !(value & ~PredictArray); 57 } 58 59 inline bool isArrayPrediction(PredictedType value) 60 { 61 return value == PredictArray; 62 } 63 64 inline bool isInt32Prediction(PredictedType value) 65 { 66 return value == PredictInt32; 67 } 68 69 inline bool isDoublePrediction(PredictedType value) 70 { 71 return value == PredictDouble; 72 } 73 74 inline bool isNumberPrediction(PredictedType value) 75 { 76 return !!(value & PredictNumber) && !(value & ~PredictNumber); 77 } 51 78 52 79 struct PredictionSlot { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r91807 r91894 538 538 GPRTemporary result(this); 539 539 PredictedType prediction = m_jit.graph().getPrediction(node.local()); 540 if ( prediction == PredictInt32) {540 if (isInt32Prediction(prediction)) { 541 541 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr()); 542 542 … … 553 553 VirtualRegister virtualRegister = node.virtualRegister(); 554 554 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS); 555 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), (prediction == PredictArray) ? DataFormatJSCell : DataFormatJS);555 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), isArrayPrediction(prediction) ? DataFormatJSCell : DataFormatJS); 556 556 } 557 557 break; … … 559 559 560 560 case SetLocal: { 561 switch (m_jit.graph().getPrediction(node.local())) {562 case PredictInt32:{561 PredictedType predictedType = m_jit.graph().getPrediction(node.local()); 562 if (isInt32Prediction(predictedType)) { 563 563 SpeculateIntegerOperand value(this, node.child1()); 564 564 m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); 565 565 noResult(m_compileIndex); 566 break; 567 } 568 case PredictArray: { 566 } else if (isArrayPrediction(predictedType)) { 569 567 SpeculateCellOperand cell(this, node.child1()); 570 568 GPRReg cellGPR = cell.gpr(); … … 572 570 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local())); 573 571 noResult(m_compileIndex); 574 break; 575 } 576 577 default: { 572 } else { 578 573 JSValueOperand value(this, node.child1()); 579 574 m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local())); 580 575 noResult(m_compileIndex); 581 break;582 }583 576 } 584 577 break; … … 919 912 // If we have predicted the base to be type array, we can skip the check. 920 913 Node& baseNode = m_jit.graph()[node.child1()]; 921 if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)914 if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local()))) 922 915 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 923 916 speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()))); … … 954 947 // If we have predicted the base to be type array, we can skip the check. 955 948 Node& baseNode = m_jit.graph()[node.child1()]; 956 if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)949 if (baseNode.op != GetLocal || isArrayPrediction(m_jit.graph().getPrediction(baseNode.local()))) 957 950 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 958 951 … … 1306 1299 for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) { 1307 1300 VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i); 1308 switch (m_jit.graph().getPrediction(virtualRegister)) {1309 case PredictInt32:1301 PredictedType predictedType = m_jit.graph().getPrediction(virtualRegister); 1302 if (isInt32Prediction(predictedType)) 1310 1303 speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister)); 1311 break; 1312 1313 case PredictArray: { 1304 else if (isArrayPrediction(predictedType)) { 1314 1305 GPRTemporary temp(this); 1315 1306 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr()); 1316 1307 speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister)); 1317 1308 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); 1318 break;1319 }1320 1321 default:1322 break;1323 1309 } 1324 1310 } … … 1333 1319 ASSERT(!m_compileIndex); 1334 1320 for (int var = 0; var < m_jit.codeBlock()->m_numVars; ++var) { 1335 if ( m_jit.graph().getPrediction(var) == PredictInt32)1321 if (isInt32Prediction(m_jit.graph().getPrediction(var))) 1336 1322 m_jit.storePtr(GPRInfo::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var)); 1337 1323 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r91807 r91894 163 163 GenerationInfo& info = m_generationInfo[virtualRegister]; 164 164 165 return (info.registerFormat() | DataFormatJS) == DataFormatJSDouble; 165 if ((info.registerFormat() | DataFormatJS) == DataFormatJSDouble 166 || (info.spillFormat() | DataFormatJS) == DataFormatJSDouble) 167 return true; 168 169 if (node.op == GetLocal && isDoublePrediction(m_jit.graph().getPrediction(node.local()))) 170 return true; 171 172 return false; 166 173 } 167 174
Note:
See TracChangeset
for help on using the changeset viewer.