Changeset 123169 in webkit
- Timestamp:
- Jul 19, 2012 8:50:02 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r123164 r123169 1 2012-07-18 Filip Pizlo <fpizlo@apple.com> 2 3 DFG cell checks should be hoisted 4 https://bugs.webkit.org/show_bug.cgi?id=91717 5 6 Reviewed by Geoffrey Garen. 7 8 The DFG has always had the policy of hoisting array and integer checks to 9 the point of variable assignment. Eventually, we added doubles and booleans 10 to the mix. But cells should really be part of this as well, particularly 11 for 32-bit where accessing a known-type variable is dramatically cheaper 12 than accessing a variable whose types is only predicted but otherwise 13 unproven. 14 15 This appears to be a definite speed-up for V8 on 32-bit, a possible speed-up 16 for Kraken, and a possible slow-down for V8 on 64-bit (around 0.2% if at 17 all). Any slow-downs can, and should, be addressed by making the hoisting 18 logic cognizant of variables that are never used in a manner that requires 19 type checks, and by sinking argument checks to the point(s) of first use. 20 21 To make this work I had to change some OSR machinery, and special-case the 22 type predictions of the 'this' argument for constructors. OSR exit normally 23 assumes that arguments are boxed, which happens to be true because the 24 type prediction used for check hoisting is LUB'd with the type of the 25 argument that was passed in - so either the arguments are always stored to 26 with the full tag+payload, or if only the payload is stored then the tag 27 matches whatever the caller would have set. But not so with the 'this' 28 argument for constructors, which is not initialized by the caller. We 29 could make this more precise by having argument types for OSR be inferred 30 using similar machinery to other locals, but I figured that for this patch 31 I should use the surgical fix. 32 33 * assembler/MacroAssemblerX86_64.h: 34 (JSC::MacroAssemblerX86_64::branchTestPtr): 35 (MacroAssemblerX86_64): 36 * assembler/X86Assembler.h: 37 (JSC::X86Assembler::testq_rm): 38 (X86Assembler): 39 * dfg/DFGAbstractState.cpp: 40 (JSC::DFG::AbstractState::initialize): 41 (JSC::DFG::AbstractState::execute): 42 * dfg/DFGDriver.cpp: 43 (JSC::DFG::compile): 44 * dfg/DFGGraph.h: 45 (JSC::DFG::Graph::isCreatedThisArgument): 46 (Graph): 47 * dfg/DFGSpeculativeJIT.cpp: 48 (JSC::DFG::SpeculativeJIT::checkArgumentTypes): 49 * dfg/DFGSpeculativeJIT32_64.cpp: 50 (JSC::DFG::SpeculativeJIT::compile): 51 * dfg/DFGSpeculativeJIT64.cpp: 52 (JSC::DFG::SpeculativeJIT::compile): 53 * dfg/DFGValueSource.h: 54 (JSC::DFG::ValueSource::forSpeculation): 55 1 56 2012-07-19 Filip Pizlo <fpizlo@apple.com> 2 57 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r122677 r123169 477 477 } 478 478 479 Jump branchTestPtr(ResultCondition cond, Address address, RegisterID reg) 480 { 481 m_assembler.testq_rm(reg, address.offset, address.base); 482 return Jump(m_assembler.jCC(x86Condition(cond))); 483 } 484 479 485 Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) 480 486 { -
trunk/Source/JavaScriptCore/assembler/X86Assembler.h
r122677 r123169 998 998 } 999 999 1000 void testq_rm(RegisterID src, int offset, RegisterID base) 1001 { 1002 m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset); 1003 } 1004 1000 1005 void testq_i32r(int imm, RegisterID dst) 1001 1006 { -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r123052 r123169 129 129 else if (isFloat64ArraySpeculation(prediction)) 130 130 root->valuesAtHead.argument(i).set(SpecFloat64Array); 131 else if (isCellSpeculation(prediction)) 132 root->valuesAtHead.argument(i).set(SpecCell); 131 133 else 132 134 root->valuesAtHead.argument(i).makeTop(); … … 273 275 274 276 case SetLocal: { 275 if (node.variableAccessData()->isCaptured()) { 277 if (node.variableAccessData()->isCaptured() 278 || m_graph.isCreatedThisArgument(node.local())) { 276 279 m_variables.operand(node.local()) = forNode(node.child1()); 277 280 node.setCanExit(false); … … 291 294 node.setCanExit(!isArraySpeculation(forNode(node.child1()).m_type)); 292 295 forNode(node.child1()).filter(SpecArray); 296 } else if (isCellSpeculation(predictedType)) { 297 node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type)); 298 forNode(node.child1()).filter(SpecCell); 293 299 } else if (isBooleanSpeculation(predictedType)) 294 300 speculateBooleanUnary(node); -
trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp
r121798 r123169 65 65 if (!Options::useDFGJIT()) 66 66 return false; 67 67 68 68 #if DFG_ENABLE(DEBUG_VERBOSE) 69 69 dataLog("DFG compiling code block %p(%p) for executable %p, number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->ownerExecutable(), codeBlock->instructionCount()); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r122678 r123169 442 442 } 443 443 444 bool isCreatedThisArgument(int operand) 445 { 446 if (!operandIsArgument(operand)) 447 return false; 448 if (operandToArgument(operand)) 449 return false; 450 return m_codeBlock->specializationKind() == CodeForConstruct; 451 } 452 444 453 unsigned numSuccessors(BasicBlock* block) 445 454 { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r123164 r123169 1242 1242 speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister)); 1243 1243 speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo))); 1244 } 1244 } else if (isCellSpeculation(predictedType)) 1245 speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, JITCompiler::addressFor(virtualRegister), GPRInfo::tagMaskRegister)); 1245 1246 #else 1246 1247 if (isInt32Speculation(predictedType)) … … 1308 1309 m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr()); 1309 1310 speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo))); 1310 } 1311 } else if (isCellSpeculation(predictedType)) 1312 speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag))); 1311 1313 #endif 1312 1314 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r123052 r123169 1919 1919 } 1920 1920 1921 if (isArraySpeculation(value.m_type) ) {1921 if (isArraySpeculation(value.m_type) || isCellSpeculation(value.m_type)) { 1922 1922 GPRTemporary result(this); 1923 1923 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr()); … … 2011 2011 m_codeOriginForOSR = nextNode->codeOrigin; 2012 2012 2013 if (!node.variableAccessData()->isCaptured() ) {2013 if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) { 2014 2014 if (node.variableAccessData()->shouldUseDoubleFormat()) { 2015 2015 SpeculateDoubleOperand value(this, node.child1()); … … 2047 2047 break; 2048 2048 } 2049 if (isCellSpeculation(predictedType)) { 2050 SpeculateCellOperand cell(this, node.child1()); 2051 GPRReg cellGPR = cell.gpr(); 2052 m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local())); 2053 noResult(m_compileIndex); 2054 recordSetLocal(node.local(), ValueSource(CellInRegisterFile)); 2055 break; 2056 } 2049 2057 if (isBooleanSpeculation(predictedType)) { 2050 2058 SpeculateBooleanOperand value(this, node.child1()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r123052 r123169 2053 2053 m_codeOriginForOSR = nextNode->codeOrigin; 2054 2054 2055 if (!node.variableAccessData()->isCaptured() ) {2055 if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) { 2056 2056 if (node.variableAccessData()->shouldUseDoubleFormat()) { 2057 2057 SpeculateDoubleOperand value(this, node.child1()); … … 2083 2083 break; 2084 2084 } 2085 if (isCellSpeculation(predictedType)) { 2086 SpeculateCellOperand cell(this, node.child1()); 2087 GPRReg cellGPR = cell.gpr(); 2088 m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local())); 2089 noResult(m_compileIndex); 2090 recordSetLocal(node.local(), ValueSource(CellInRegisterFile)); 2091 break; 2092 } 2085 2093 if (isBooleanSpeculation(predictedType)) { 2086 2094 SpeculateBooleanOperand boolean(this, node.child1()); -
trunk/Source/JavaScriptCore/dfg/DFGValueSource.h
r121717 r123169 131 131 if (isInt32Speculation(prediction)) 132 132 return ValueSource(Int32InRegisterFile); 133 if (isArraySpeculation(prediction) )133 if (isArraySpeculation(prediction) || isCellSpeculation(prediction)) 134 134 return ValueSource(CellInRegisterFile); 135 135 if (isBooleanSpeculation(prediction))
Note: See TracChangeset
for help on using the changeset viewer.