Changeset 118112 in webkit
- Timestamp:
- May 22, 2012, 8:48:52 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r118102 r118112 1 2012-05-08 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should support op_get_argument_by_val and op_get_arguments_length 4 https://bugs.webkit.org/show_bug.cgi?id=85911 5 6 Reviewed by Oliver Hunt. 7 8 Merged r116467 from dfgopt. 9 10 This adds a simple and relatively conservative implementation of op_get_argument_by_val 11 and op_get_arguments_length. We can optimize these later. For now it's great to have 12 the additional coverage. 13 14 This patch appears to be perf-neutral. 15 16 * dfg/DFGAbstractState.cpp: 17 (JSC::DFG::AbstractState::execute): 18 * dfg/DFGAssemblyHelpers.h: 19 (JSC::DFG::AssemblyHelpers::addressFor): 20 (JSC::DFG::AssemblyHelpers::tagFor): 21 (JSC::DFG::AssemblyHelpers::payloadFor): 22 * dfg/DFGByteCodeParser.cpp: 23 (JSC::DFG::ByteCodeParser::parseBlock): 24 * dfg/DFGCapabilities.h: 25 (JSC::DFG::canCompileOpcode): 26 (JSC::DFG::canInlineOpcode): 27 * dfg/DFGNode.h: 28 (JSC::DFG::Node::hasHeapPrediction): 29 * dfg/DFGNodeType.h: 30 (DFG): 31 * dfg/DFGOperations.cpp: 32 * dfg/DFGOperations.h: 33 * dfg/DFGPredictionPropagationPhase.cpp: 34 (JSC::DFG::PredictionPropagationPhase::propagate): 35 * dfg/DFGSpeculativeJIT.h: 36 (JSC::DFG::SpeculativeJIT::callOperation): 37 (SpeculativeJIT): 38 * dfg/DFGSpeculativeJIT32_64.cpp: 39 (JSC::DFG::SpeculativeJIT::compile): 40 * dfg/DFGSpeculativeJIT64.cpp: 41 (JSC::DFG::SpeculativeJIT::compile): 42 * jit/JITOpcodes.cpp: 43 (JSC::JIT::emit_op_get_argument_by_val): 44 * jit/JITOpcodes32_64.cpp: 45 (JSC::JIT::emit_op_get_argument_by_val): 46 * llint/LowLevelInterpreter32_64.asm: 47 * llint/LowLevelInterpreter64.asm: 48 1 49 2012-05-07 Filip Pizlo <fpizlo@apple.com> 2 50 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r118102 r118112 1069 1069 break; 1070 1070 1071 case GetMyArgumentsLength: 1072 // This potentially clobbers all structures if the arguments object had a getter 1073 // installed on the length property. 1074 clobberStructures(indexInBlock); 1075 // We currently make no guarantee about what this returns because it does not 1076 // speculate that the length property is actually a length. 1077 forNode(nodeIndex).makeTop(); 1078 break; 1079 1080 case GetMyArgumentByVal: 1081 // This potentially clobbers all structures if the property we're accessing has 1082 // a getter. We don't speculate against this. 1083 clobberStructures(indexInBlock); 1084 // But we do speculate that the index is an integer. 1085 forNode(node.child1()).filter(PredictInt32); 1086 // And the result is unknown. 1087 forNode(nodeIndex).makeTop(); 1088 break; 1089 1071 1090 case NewFunction: 1072 1091 case NewFunctionExpression: -
trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
r117729 r118112 135 135 return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register)); 136 136 } 137 static Address addressFor(int operand) 138 { 139 return addressFor(static_cast<VirtualRegister>(operand)); 140 } 137 141 138 142 static Address tagFor(VirtualRegister virtualRegister) … … 140 144 return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); 141 145 } 146 static Address tagFor(int operand) 147 { 148 return tagFor(static_cast<VirtualRegister>(operand)); 149 } 142 150 143 151 static Address payloadFor(VirtualRegister virtualRegister) 144 152 { 145 153 return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); 154 } 155 static Address payloadFor(int operand) 156 { 157 return payloadFor(static_cast<VirtualRegister>(operand)); 146 158 } 147 159 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r118102 r118112 2388 2388 } 2389 2389 2390 case op_get_arguments_length: { 2391 set(currentInstruction[1].u.operand, addToGraph(GetMyArgumentsLength)); 2392 NEXT_OPCODE(op_get_arguments_length); 2393 } 2394 2395 case op_get_argument_by_val: { 2396 set(currentInstruction[1].u.operand, 2397 addToGraph( 2398 GetMyArgumentByVal, OpInfo(0), OpInfo(getPrediction()), 2399 get(currentInstruction[3].u.operand))); 2400 NEXT_OPCODE(op_get_argument_by_val); 2401 } 2402 2390 2403 case op_new_func: { 2391 2404 if (!currentInstruction[3].u.operand) { -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.h
r118102 r118112 168 168 case op_new_func: 169 169 case op_new_func_exp: 170 case op_get_argument_by_val: 171 case op_get_arguments_length: 170 172 return true; 171 173 … … 203 205 case op_create_arguments: 204 206 case op_tear_off_arguments: 207 case op_get_argument_by_val: 208 case op_get_arguments_length: 205 209 return false; 206 210 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r118030 r118112 513 513 case GetByIdFlush: 514 514 case GetByVal: 515 case GetMyArgumentByVal: 515 516 case Call: 516 517 case Construct: -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r118102 r118112 196 196 macro(CreateArguments, NodeResultJS) \ 197 197 macro(TearOffArguments, NodeMustGenerate) \ 198 macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 199 macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 198 200 \ 199 201 /* Nodes for creating functions. */\ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r118102 r118112 1065 1065 ASSERT(exec->codeBlock()->usesArguments() && !exec->codeBlock()->needsFullScopeChain()); 1066 1066 asArguments(argumentsCell)->tearOff(exec); 1067 } 1068 1069 EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec) 1070 { 1071 Identifier ident(&exec->globalData(), "length"); 1072 JSValue baseValue = exec->uncheckedR(exec->codeBlock()->argumentsRegister()).jsValue(); 1073 PropertySlot slot(baseValue); 1074 return JSValue::encode(baseValue.get(exec, ident, slot)); 1075 } 1076 1077 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t index) 1078 { 1079 return JSValue::encode( 1080 exec->uncheckedR(exec->codeBlock()->argumentsRegister()).jsValue().get(exec, index)); 1067 1081 } 1068 1082 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r118102 r118112 61 61 G: GlobalResolveInfo* 62 62 */ 63 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_E)(ExecState*); 63 64 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*); 64 65 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*); … … 76 77 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPS)(ExecState*, void*, size_t); 77 78 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESS)(ExecState*, size_t, size_t); 79 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZ)(ExecState*, int32_t); 78 80 typedef JSCell* DFG_OPERATION (*C_DFGOperation_E)(ExecState*); 79 81 typedef JSCell* DFG_OPERATION (*C_DFGOperation_EC)(ExecState*, JSCell*); … … 158 160 void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*, int32_t unmodifiedArgumentsRegister); 159 161 void DFG_OPERATION operationTearOffArguments(ExecState*, JSCell*); 162 EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState*); 163 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState*, int32_t); 160 164 JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*); 161 165 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*); -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r118102 r118112 438 438 } 439 439 440 case GetMyArgumentByVal: { 441 changed |= mergePrediction(node.getHeapPrediction()); 442 changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); 443 break; 444 } 445 446 case GetMyArgumentsLength: { 447 changed |= setPrediction(PredictInt32); 448 break; 449 } 450 440 451 case GetPropertyStorage: 441 452 case GetIndexedPropertyStorage: { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r118102 r118112 1212 1212 // decision as to how to fill the regsiters to setupArguments* methods. 1213 1213 #if USE(JSVALUE64) 1214 JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result) 1215 { 1216 m_jit.setupArgumentsExecState(); 1217 return appendCallWithExceptionCheckSetResult(operation, result); 1218 } 1214 1219 JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer) 1215 1220 { … … 1270 1275 } 1271 1276 JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, GPRReg arg1) 1277 { 1278 m_jit.setupArgumentsWithExecState(arg1); 1279 return appendCallWithExceptionCheckSetResult(operation, result); 1280 } 1281 JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, GPRReg arg1) 1272 1282 { 1273 1283 m_jit.setupArgumentsWithExecState(arg1); … … 1432 1442 return call; 1433 1443 } 1444 JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg resultTag, GPRReg resultPayload) 1445 { 1446 m_jit.setupArgumentsExecState(); 1447 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1448 } 1434 1449 JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer) 1435 1450 { … … 1507 1522 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1508 1523 } 1524 JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1) 1525 { 1526 m_jit.setupArgumentsWithExecState(arg1); 1527 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1528 } 1509 1529 JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result) 1510 1530 { … … 1652 1672 #undef EABI_32BIT_DUMMY_ARG 1653 1673 1674 template<typename FunctionType> 1675 JITCompiler::Call callOperation( 1676 FunctionType operation, JSValueRegs result) 1677 { 1678 return callOperation(operation, result.tagGPR(), result.payloadGPR()); 1679 } 1654 1680 template<typename FunctionType, typename ArgumentType1> 1655 1681 JITCompiler::Call callOperation( … … 1999 2025 void compileGetCharCodeAt(Node&); 2000 2026 void compileGetByValOnString(Node&); 2027 2001 2028 void compileGetByValOnArguments(Node&); 2002 2029 void compileGetArgumentsLength(Node&); 2030 2003 2031 void compileValueToInt32(Node&); 2004 2032 void compileUInt32ToNumber(Node&); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r118102 r118112 3809 3809 } 3810 3810 3811 case GetMyArgumentsLength: { 3812 GPRTemporary resultPayload(this); 3813 GPRTemporary resultTag(this); 3814 GPRReg resultPayloadGPR = resultPayload.gpr(); 3815 GPRReg resultTagGPR = resultTag.gpr(); 3816 3817 JITCompiler::Jump created = m_jit.branch32( 3818 JITCompiler::NotEqual, 3819 JITCompiler::tagFor(m_jit.codeBlock()->argumentsRegister()), 3820 TrustedImm32(JSValue::EmptyValueTag)); 3821 3822 m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultPayloadGPR); 3823 m_jit.sub32(TrustedImm32(1), resultPayloadGPR); 3824 m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR); 3825 3826 // FIXME: the slow path generator should perform a forward speculation that the 3827 // result is an integer. For now we postpone the speculation by having this return 3828 // a JSValue. 3829 3830 addSlowPathGenerator( 3831 slowPathCall( 3832 created, this, operationGetArgumentsLength, 3833 JSValueRegs(resultTagGPR, resultPayloadGPR))); 3834 3835 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex); 3836 break; 3837 } 3838 3839 case GetMyArgumentByVal: { 3840 SpeculateStrictInt32Operand index(this, node.child1()); 3841 GPRTemporary resultPayload(this); 3842 GPRTemporary resultTag(this); 3843 GPRReg indexGPR = index.gpr(); 3844 GPRReg resultPayloadGPR = resultPayload.gpr(); 3845 GPRReg resultTagGPR = resultTag.gpr(); 3846 3847 JITCompiler::JumpList slowPath; 3848 slowPath.append( 3849 m_jit.branch32( 3850 JITCompiler::NotEqual, 3851 JITCompiler::tagFor(m_jit.codeBlock()->argumentsRegister()), 3852 TrustedImm32(JSValue::EmptyValueTag))); 3853 3854 m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR); 3855 slowPath.append( 3856 m_jit.branch32( 3857 JITCompiler::AboveOrEqual, 3858 resultPayloadGPR, 3859 JITCompiler::payloadFor(RegisterFile::ArgumentCount))); 3860 3861 m_jit.neg32(resultPayloadGPR); 3862 3863 m_jit.load32( 3864 JITCompiler::BaseIndex( 3865 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight, 3866 CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register) + 3867 OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), 3868 resultTagGPR); 3869 m_jit.load32( 3870 JITCompiler::BaseIndex( 3871 GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight, 3872 CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register) + 3873 OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), 3874 resultPayloadGPR); 3875 3876 addSlowPathGenerator( 3877 slowPathCall( 3878 slowPath, this, operationGetArgumentByVal, 3879 JSValueRegs(resultTagGPR, resultPayloadGPR), indexGPR)); 3880 3881 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex); 3882 break; 3883 } 3884 3811 3885 case NewFunctionNoCheck: 3812 3886 compileNewFunctionNoCheck(node); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r118102 r118112 3822 3822 } 3823 3823 3824 case GetMyArgumentsLength: { 3825 GPRTemporary result(this); 3826 GPRReg resultGPR = result.gpr(); 3827 3828 JITCompiler::Jump created = m_jit.branchTestPtr( 3829 JITCompiler::NonZero, JITCompiler::addressFor(m_jit.codeBlock()->argumentsRegister())); 3830 3831 m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultGPR); 3832 m_jit.sub32(TrustedImm32(1), resultGPR); 3833 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR); 3834 3835 // FIXME: the slow path generator should perform a forward speculation that the 3836 // result is an integer. For now we postpone the speculation by having this return 3837 // a JSValue. 3838 3839 addSlowPathGenerator( 3840 slowPathCall( 3841 created, this, operationGetArgumentsLength, resultGPR)); 3842 3843 jsValueResult(resultGPR, m_compileIndex); 3844 break; 3845 } 3846 3847 case GetMyArgumentByVal: { 3848 SpeculateStrictInt32Operand index(this, node.child1()); 3849 GPRTemporary result(this); 3850 GPRReg indexGPR = index.gpr(); 3851 GPRReg resultGPR = result.gpr(); 3852 3853 JITCompiler::JumpList slowPath; 3854 slowPath.append( 3855 m_jit.branchTestPtr( 3856 JITCompiler::NonZero, 3857 JITCompiler::addressFor(m_jit.codeBlock()->argumentsRegister()))); 3858 3859 m_jit.add32(TrustedImm32(1), indexGPR, resultGPR); 3860 slowPath.append( 3861 m_jit.branch32( 3862 JITCompiler::AboveOrEqual, 3863 resultGPR, 3864 JITCompiler::payloadFor(RegisterFile::ArgumentCount))); 3865 3866 m_jit.neg32(resultGPR); 3867 m_jit.signExtend32ToPtr(resultGPR, resultGPR); 3868 3869 m_jit.loadPtr( 3870 JITCompiler::BaseIndex( 3871 GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, 3872 CallFrame::argumentOffsetIncludingThis(0) * sizeof(Register)), 3873 resultGPR); 3874 3875 addSlowPathGenerator( 3876 slowPathCall( 3877 slowPath, this, operationGetArgumentByVal, resultGPR, indexGPR)); 3878 3879 jsValueResult(resultGPR, m_compileIndex); 3880 break; 3881 } 3882 3824 3883 case NewFunctionNoCheck: 3825 3884 compileNewFunctionNoCheck(node); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r116673 r118112 1527 1527 signExtend32ToPtr(regT1, regT1); 1528 1528 loadPtr(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0); 1529 emitValueProfilingSite(); 1529 1530 emitPutVirtualRegister(dst, regT0); 1530 1531 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r116673 r118112 1637 1637 loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT0); 1638 1638 loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT1); 1639 emitValueProfilingSite(); 1639 1640 emitStore(dst, regT1, regT0); 1640 1641 } -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r116673 r118112 1215 1215 loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0 1216 1216 loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t1 1217 loadi 16[PC], t2 1217 1218 storei t0, TagOffset[cfr, t3, 8] 1218 1219 storei t1, PayloadOffset[cfr, t3, 8] 1220 valueProfile(t0, t1, t2) 1219 1221 dispatch(5) 1220 1222 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r116673 r118112 1059 1059 sxi2p t2, t2 1060 1060 loadis 8[PB, PC, 8], t3 1061 loadp 32[PB, PC, 8], t1 1061 1062 loadp ThisArgumentOffset[cfr, t2, 8], t0 1062 1063 storep t0, [cfr, t3, 8] 1064 valueProfile(t0, t1) 1063 1065 dispatch(5) 1064 1066
Note:
See TracChangeset
for help on using the changeset viewer.