Changeset 102545 in webkit for trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
- Timestamp:
- Dec 11, 2011, 4:35:51 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r102489 r102545 77 77 78 78 // Helper for min and max. 79 bool handleMinMax(bool usesResult, int resultOperand, NodeType op, int firstArg, int lastArg);79 bool handleMinMax(bool usesResult, int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis); 80 80 81 81 // Handle calls. This resolves issues surrounding inlining and intrinsics. 82 82 void handleCall(Interpreter*, Instruction* currentInstruction, NodeType op, CodeSpecializationKind); 83 83 // Handle inlining. Return true if it succeeded, false if we need to plant a call. 84 bool handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction*, int firstArg, int lastArg, unsigned nextOffset, CodeSpecializationKind);84 bool handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction*, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind); 85 85 // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call. 86 bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int firstArg, int lastArg, PredictedType prediction);86 bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, PredictedType prediction); 87 87 // Prepare to parse a block. 88 88 void prepareToParseBlock(); … … 200 200 NodeIndex getArgument(unsigned operand) 201 201 { 202 unsigned argument = operand + m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize;202 unsigned argument = operandToArgument(operand); 203 203 ASSERT(argument < m_numArguments); 204 204 … … 249 249 void setArgument(int operand, NodeIndex value) 250 250 { 251 unsigned argument = operand + m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize;251 unsigned argument = operandToArgument(operand); 252 252 ASSERT(argument < m_numArguments); 253 253 … … 267 267 int index; 268 268 if (operandIsArgument(operand)) { 269 index = operand + m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize;269 index = operandToArgument(operand); 270 270 nodeIndex = m_currentBlock->variablesAtTail.argument(index); 271 271 } else { … … 579 579 addVarArgChild(get(currentInstruction[1].u.operand)); 580 580 int argCount = currentInstruction[2].u.operand; 581 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) 582 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; 583 581 584 int registerOffset = currentInstruction[3].u.operand; 582 int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize; 583 for (int argIdx = firstArg + (op == Construct ? 1 : 0); argIdx < firstArg + argCount; argIdx++) 584 addVarArgChild(get(argIdx)); 585 int dummyThisArgument = op == Call ? 0 : 1; 586 for (int i = 0 + dummyThisArgument; i < argCount; ++i) 587 addVarArgChild(get(registerOffset + argumentToOperand(i))); 588 585 589 NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction)); 586 590 if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) 587 591 set(putInstruction[1].u.operand, call); 588 if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)589 m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;590 592 return call; 591 593 } … … 896 898 callType = UnknownFunction; 897 899 if (callType != UnknownFunction) { 898 int arg Count= currentInstruction[2].u.operand;900 int argumentCountIncludingThis = currentInstruction[2].u.operand; 899 901 int registerOffset = currentInstruction[3].u.operand; 900 int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize; 901 int lastArg = firstArg + argCount - 1; 902 902 903 903 // Do we have a result? 904 904 bool usesResult = false; … … 931 931 addToGraph(CheckFunction, OpInfo(expectedFunction), callTarget); 932 932 933 if (handleIntrinsic(usesResult, resultOperand, intrinsic, firstArg, lastArg, prediction)) {933 if (handleIntrinsic(usesResult, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) { 934 934 if (!certainAboutExpectedFunction) { 935 935 // Need to keep the call target alive for OSR. We could easily optimize this out if we wanted … … 941 941 return; 942 942 } 943 } else if (handleInlining(usesResult, currentInstruction[1].u.operand, callTarget, resultOperand, certainAboutExpectedFunction, expectedFunction, firstArg, lastArg, nextOffset, kind))943 } else if (handleInlining(usesResult, currentInstruction[1].u.operand, callTarget, resultOperand, certainAboutExpectedFunction, expectedFunction, registerOffset, argumentCountIncludingThis, nextOffset, kind)) 944 944 return; 945 945 } … … 948 948 } 949 949 950 bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction* expectedFunction, int firstArg, int lastArg, unsigned nextOffset, CodeSpecializationKind kind)950 bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction* expectedFunction, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind kind) 951 951 { 952 952 // First, the really simple checks: do we have an actual JS function? … … 960 960 // Does the number of arguments we're passing match the arity of the target? We could 961 961 // inline arity check failures, but for simplicity we currently don't. 962 if (static_cast<int>(executable->parameterCount()) + 1 != lastArg - firstArg + 1)962 if (static_cast<int>(executable->parameterCount()) + 1 != argumentCountIncludingThis) 963 963 return false; 964 964 … … 1001 1001 // FIXME: Don't flush constants! 1002 1002 1003 for (int arg = firstArg + 1; arg <= lastArg; ++arg)1004 flush( arg);1005 1006 int inlineCallFrameStart = m_inlineStackTop->remapOperand( lastArg) + 1;1003 for (int i = 1; i < argumentCountIncludingThis; ++i) 1004 flush(registerOffset + argumentToOperand(i)); 1005 1006 int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - RegisterFile::CallFrameHeaderSize; 1007 1007 1008 1008 // Make sure that the area used by the call frame is reserved. … … 1124 1124 } 1125 1125 1126 bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType op, int firstArg, int lastArg)1126 bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis) 1127 1127 { 1128 1128 if (!usesResult) 1129 1129 return true; 1130 1130 1131 if ( lastArg == firstArg) {1131 if (argumentCountIncludingThis == 1) { // Math.min() 1132 1132 set(resultOperand, constantNaN()); 1133 1133 return true; 1134 1134 } 1135 1135 1136 if ( lastArg == firstArg + 1) {1137 set(resultOperand, getToNumber( firstArg + 1));1136 if (argumentCountIncludingThis == 2) { // Math.min(x) 1137 set(resultOperand, getToNumber(registerOffset + argumentToOperand(1))); 1138 1138 return true; 1139 1139 } 1140 1140 1141 if ( lastArg == firstArg + 2) {1142 set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), getToNumber( firstArg + 1), getToNumber(firstArg + 2)));1141 if (argumentCountIncludingThis == 3) { // Math.min(x, y) 1142 set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)), getToNumber(registerOffset + argumentToOperand(2)))); 1143 1143 return true; 1144 1144 } … … 1148 1148 } 1149 1149 1150 bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrinsic intrinsic, int firstArg, int lastArg, PredictedType prediction) 1150 // FIXME: We dead-code-eliminate unused Math intrinsics, but that's invalid because 1151 // they need to perform the ToNumber conversion, which can have side-effects. 1152 bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, PredictedType prediction) 1151 1153 { 1152 1154 switch (intrinsic) { … … 1158 1160 } 1159 1161 1160 // We don't care about the this argument. If we don't have a first 1161 // argument then make this JSConstant(NaN). 1162 int absArg = firstArg + 1; 1163 if (absArg > lastArg) { 1162 if (argumentCountIncludingThis == 1) { // Math.abs() 1164 1163 set(resultOperand, constantNaN()); 1165 1164 return true; … … 1169 1168 return false; 1170 1169 1171 set(resultOperand, addToGraph(ArithAbs, OpInfo(NodeUseBottom), getToNumber( absArg)));1170 set(resultOperand, addToGraph(ArithAbs, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)))); 1172 1171 return true; 1173 1172 } 1174 1173 1175 1174 case MinIntrinsic: 1176 return handleMinMax(usesResult, resultOperand, ArithMin, firstArg, lastArg);1175 return handleMinMax(usesResult, resultOperand, ArithMin, registerOffset, argumentCountIncludingThis); 1177 1176 1178 1177 case MaxIntrinsic: 1179 return handleMinMax(usesResult, resultOperand, ArithMax, firstArg, lastArg);1178 return handleMinMax(usesResult, resultOperand, ArithMax, registerOffset, argumentCountIncludingThis); 1180 1179 1181 1180 case SqrtIntrinsic: { … … 1183 1182 return true; 1184 1183 1185 if ( firstArg == lastArg) {1184 if (argumentCountIncludingThis == 1) { // Math.sqrt() 1186 1185 set(resultOperand, constantNaN()); 1187 1186 return true; … … 1191 1190 return false; 1192 1191 1193 set(resultOperand, addToGraph(ArithSqrt, getToNumber( firstArg + 1)));1192 set(resultOperand, addToGraph(ArithSqrt, getToNumber(registerOffset + argumentToOperand(1)))); 1194 1193 return true; 1195 1194 } 1196 1195 1197 1196 case ArrayPushIntrinsic: { 1198 if ( firstArg + 1 != lastArg)1197 if (argumentCountIncludingThis != 2) 1199 1198 return false; 1200 1199 1201 NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(0), OpInfo(prediction), get( firstArg), get(firstArg + 1));1200 NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1))); 1202 1201 if (usesResult) 1203 1202 set(resultOperand, arrayPush); … … 1207 1206 1208 1207 case ArrayPopIntrinsic: { 1209 if ( firstArg != lastArg)1208 if (argumentCountIncludingThis != 1) 1210 1209 return false; 1211 1210 1212 NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(0), OpInfo(prediction), get( firstArg));1211 NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0))); 1213 1212 if (usesResult) 1214 1213 set(resultOperand, arrayPop); … … 1217 1216 1218 1217 case CharCodeAtIntrinsic: { 1219 if ( firstArg + 1 != lastArg)1218 if (argumentCountIncludingThis != 2) 1220 1219 return false; 1221 if (!(m_graph[get(firstArg)].prediction() & PredictString)) 1220 1221 int thisOperand = registerOffset + argumentToOperand(0); 1222 if (!(m_graph[get(thisOperand)].prediction() & PredictString)) 1222 1223 return false; 1223 1224 1224 NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(firstArg), getToInt32(firstArg + 1)); 1225 NodeIndex charCode = addToGraph(StringCharCodeAt, get(firstArg), getToInt32(firstArg + 1), storage); 1225 int indexOperand = registerOffset + argumentToOperand(1); 1226 NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(thisOperand), getToInt32(indexOperand)); 1227 NodeIndex charCode = addToGraph(StringCharCodeAt, get(thisOperand), getToInt32(indexOperand), storage); 1228 1226 1229 if (usesResult) 1227 1230 set(resultOperand, charCode); … … 1230 1233 1231 1234 case CharAtIntrinsic: { 1232 if ( firstArg + 1 != lastArg)1235 if (argumentCountIncludingThis != 2) 1233 1236 return false; 1234 if (!(m_graph[get(firstArg)].prediction() & PredictString)) 1237 1238 int thisOperand = registerOffset + argumentToOperand(0); 1239 if (!(m_graph[get(thisOperand)].prediction() & PredictString)) 1235 1240 return false; 1236 1241 1237 NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(firstArg), getToInt32(firstArg + 1)); 1238 NodeIndex charCode = addToGraph(StringCharAt, get(firstArg), getToInt32(firstArg + 1), storage); 1242 int indexOperand = registerOffset + argumentToOperand(1); 1243 NodeIndex storage = addToGraph(GetIndexedPropertyStorage, get(thisOperand), getToInt32(indexOperand)); 1244 NodeIndex charCode = addToGraph(StringCharAt, get(thisOperand), getToInt32(indexOperand), storage); 1245 1239 1246 if (usesResult) 1240 1247 set(resultOperand, charCode); … … 1268 1275 m_graph.m_arguments.resize(m_numArguments); 1269 1276 for (unsigned argument = 0; argument < m_numArguments; ++argument) { 1270 NodeIndex setArgument = addToGraph(SetArgument, OpInfo(newVariableAccessData(argument - m_codeBlock->m_numParameters - RegisterFile::CallFrameHeaderSize)));1277 NodeIndex setArgument = addToGraph(SetArgument, OpInfo(newVariableAccessData(argumentToOperand(argument)))); 1271 1278 m_graph.m_arguments[argument] = setArgument; 1272 1279 m_currentBlock->variablesAtHead.setArgumentFirstTime(argument, setArgument); … … 2208 2215 #endif 2209 2216 2210 valueInPredecessor = addToGraph(Phi, OpInfo(newVariableAccessData(stackType == ArgumentPhiStack ? varNo - m_codeBlock->m_numParameters - RegisterFile::CallFrameHeaderSize : varNo)));2217 valueInPredecessor = addToGraph(Phi, OpInfo(newVariableAccessData(stackType == ArgumentPhiStack ? argumentToOperand(varNo) : static_cast<int>(varNo)))); 2211 2218 var = valueInPredecessor; 2212 2219 if (stackType == ArgumentPhiStack)
Note:
See TracChangeset
for help on using the changeset viewer.