Changeset 97030 in webkit
- Timestamp:
- Oct 9, 2011 1:07:36 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r97025 r97030 1 2011-10-09 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should not always speculate that a ByVal access has an integer index 4 https://bugs.webkit.org/show_bug.cgi?id=69716 5 6 Reviewed by Oliver Hunt. 7 8 1% win on SunSpider, neutral elsewhere. 9 10 * dfg/DFGJITCodeGenerator.h: 11 (JSC::DFG::callOperation): 12 * dfg/DFGNode.h: 13 * dfg/DFGOperations.cpp: 14 * dfg/DFGOperations.h: 15 * dfg/DFGPropagator.cpp: 16 (JSC::DFG::Propagator::byValHasIntBase): 17 (JSC::DFG::Propagator::clobbersWorld): 18 (JSC::DFG::Propagator::getMethodLoadElimination): 19 (JSC::DFG::Propagator::checkStructureLoadElimination): 20 (JSC::DFG::Propagator::getByOffsetLoadElimination): 21 (JSC::DFG::Propagator::getPropertyStorageLoadElimination): 22 (JSC::DFG::Propagator::performNodeCSE): 23 * dfg/DFGSpeculativeJIT32_64.cpp: 24 (JSC::DFG::SpeculativeJIT::compile): 25 * dfg/DFGSpeculativeJIT64.cpp: 26 (JSC::DFG::SpeculativeJIT::compile): 27 1 28 2011-10-09 Yuqiang Xian <yuqiang.xian@intel.com> 2 29 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r96988 r97030 1155 1155 m_jit.move(GPRInfo::returnValueGPR, result); 1156 1156 } 1157 void callOperation(J_DFGOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1158 { 1159 setupStubArguments(arg1, arg2); 1160 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1161 1162 appendCallWithExceptionCheck(operation); 1163 m_jit.move(GPRInfo::returnValueGPR, result); 1164 } 1157 1165 void callOperation(V_DFGOperation_EJJP operation, GPRReg arg1, GPRReg arg2, void* pointer) 1158 1166 { … … 1168 1176 } 1169 1177 void callOperation(V_DFGOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1178 { 1179 setupStubArguments(arg1, arg2, arg3); 1180 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1181 1182 appendCallWithExceptionCheck(operation); 1183 } 1184 void callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1170 1185 { 1171 1186 setupStubArguments(arg1, arg2, arg3); … … 1329 1344 setupResults(resultTag, resultPayload); 1330 1345 } 1346 void callOperation(J_DFGOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload) 1347 { 1348 m_jit.push(arg2Tag); 1349 m_jit.push(arg2Payload); 1350 m_jit.push(arg1); 1351 m_jit.push(GPRInfo::callFrameRegister); 1352 1353 appendCallWithExceptionCheck(operation); 1354 setupResults(resultTag, resultPayload); 1355 } 1331 1356 void callOperation(V_DFGOperation_EJJP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, void* pointer) 1332 1357 { … … 1352 1377 m_jit.push(arg1Tag); 1353 1378 m_jit.push(arg1Payload); 1379 m_jit.push(GPRInfo::callFrameRegister); 1380 1381 appendCallWithExceptionCheck(operation); 1382 } 1383 void callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload) 1384 { 1385 m_jit.push(arg3Tag); 1386 m_jit.push(arg3Payload); 1387 m_jit.push(arg2Tag); 1388 m_jit.push(arg2Payload); 1389 m_jit.push(arg1); 1354 1390 m_jit.push(GPRInfo::callFrameRegister); 1355 1391 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r96993 r97030 322 322 /* Since a put to 'length' may invalidate optimizations here, */\ 323 323 /* this must be the directly subsequent property put. */\ 324 macro(GetByVal, NodeResultJS | NodeMustGenerate ) \324 macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \ 325 325 macro(PutByVal, NodeMustGenerate | NodeClobbersWorld) \ 326 326 macro(PutByValAlias, NodeMustGenerate | NodeClobbersWorld) \ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r96988 r97030 264 264 } 265 265 266 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty) 267 { 268 JSValue property = JSValue::decode(encodedProperty); 269 270 if (property.isUInt32()) 271 return getByVal(exec, base, property.asUInt32()); 272 if (property.isDouble()) { 273 double propertyAsDouble = property.asDouble(); 274 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble); 275 if (propertyAsUInt32 == propertyAsDouble) 276 return getByVal(exec, base, propertyAsUInt32); 277 } else if (property.isString()) { 278 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec))) 279 return JSValue::encode(result); 280 } 281 282 Identifier ident(exec, property.toString(exec)); 283 return JSValue::encode(JSValue(base).get(exec, ident)); 284 } 285 266 286 EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue encodedBase, Identifier* propertyName) 267 287 { … … 365 385 { 366 386 operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue); 387 } 388 389 void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) 390 { 391 operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue); 392 } 393 394 void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) 395 { 396 operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue); 367 397 } 368 398 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r96988 r97030 55 55 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*); 56 56 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJA)(ExecState*, EncodedJSValue, JSArray*); 57 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue); 57 58 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); 58 59 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJ)(ExecState*, EncodedJSValue); … … 66 67 typedef RegisterSizedBoolean DFG_OPERATION (*Z_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); 67 68 typedef void DFG_OPERATION (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue); 69 typedef void DFG_OPERATION (*V_DFGOperation_ECJJ)(ExecState*, JSCell*, EncodedJSValue, EncodedJSValue); 68 70 typedef void DFG_OPERATION (*V_DFGOperation_EJJP)(ExecState*, EncodedJSValue, EncodedJSValue, void*); 69 71 typedef void DFG_OPERATION (*V_DFGOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*); … … 83 85 EncodedJSValue DFG_OPERATION operationArithMod(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); 84 86 EncodedJSValue DFG_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty); 87 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState*, JSCell*, EncodedJSValue encodedProperty); 85 88 EncodedJSValue DFG_OPERATION operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*); 86 89 EncodedJSValue DFG_OPERATION operationGetByIdBuildList(ExecState*, EncodedJSValue encodedBase, Identifier*); … … 101 104 void DFG_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); 102 105 void DFG_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); 106 void DFG_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); 107 void DFG_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); 103 108 void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue); 104 109 EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*); -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r96995 r97030 881 881 } 882 882 883 bool byValHasIntBase(Node& node) 884 { 885 PredictedType prediction = m_graph[node.child2()].prediction(); 886 return (prediction & PredictInt32) || !prediction; 887 } 888 883 889 bool clobbersWorld(NodeIndex nodeIndex) 884 890 { … … 898 904 case LogicalNot: 899 905 return !logicalNotIsPure(node); 906 case GetByVal: 907 return !byValHasIntBase(node); 900 908 default: 901 909 ASSERT_NOT_REACHED(); … … 1012 1020 case PutByVal: 1013 1021 case PutByValAlias: 1014 // PutByVal currently always speculates that it's accessing an array with an 1015 // integer index, which means that it's impossible for it to cause a structure 1016 // change. 1017 break; 1022 if (byValHasIntBase(node)) { 1023 // If PutByVal speculates that it's accessing an array with an 1024 // integer index, then it's impossible for it to cause a structure 1025 // change. 1026 break; 1027 } 1028 return NoNode; 1018 1029 1019 1030 case ArrayPush: … … 1077 1088 case PutByVal: 1078 1089 case PutByValAlias: 1079 // PutByVal currently always speculates that it's accessing an array with an 1080 // integer index, which means that it's impossible for it to cause a structure 1081 // change. 1082 break; 1090 if (byValHasIntBase(node)) { 1091 // If PutByVal speculates that it's accessing an array with an 1092 // integer index, then it's impossible for it to cause a structure 1093 // change. 1094 break; 1095 } 1096 return false; 1083 1097 1084 1098 default: … … 1117 1131 case PutByVal: 1118 1132 case PutByValAlias: 1119 // PutByVal currently always speculates that it's accessing an array with an 1120 // integer index, which means that it's impossible for it to cause a structure 1121 // change. 1122 break; 1133 if (byValHasIntBase(node)) { 1134 // If PutByVal speculates that it's accessing an array with an 1135 // integer index, then it's impossible for it to cause a structure 1136 // change. 1137 break; 1138 } 1139 return NoNode; 1123 1140 1124 1141 default: … … 1150 1167 case PutByVal: 1151 1168 case PutByValAlias: 1152 // PutByVal currently always speculates that it's accessing an array with an 1153 // integer index, which means that it's impossible for it to cause a structure 1154 // change. 1155 break; 1169 if (byValHasIntBase(node)) { 1170 // If PutByVal speculates that it's accessing an array with an 1171 // integer index, then it's impossible for it to cause a structure 1172 // change. 1173 break; 1174 } 1175 return NoNode; 1156 1176 1157 1177 default: … … 1322 1342 1323 1343 case GetByVal: 1324 setReplacement(getByValLoadElimination(node.child1(), node.child2())); 1344 if (byValHasIntBase(node)) 1345 setReplacement(getByValLoadElimination(node.child1(), node.child2())); 1325 1346 break; 1326 1347 1327 1348 case PutByVal: 1328 if ( getByValLoadElimination(node.child1(), node.child2()) != NoNode)1349 if (byValHasIntBase(node) && getByValLoadElimination(node.child1(), node.child2()) != NoNode) 1329 1350 node.op = PutByValAlias; 1330 1351 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r97014 r97030 1273 1273 1274 1274 case GetByVal: { 1275 PredictedType basePrediction = at(node.child2()).prediction(); 1276 if (!(basePrediction & PredictInt32) && basePrediction) { 1277 SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. 1278 JSValueOperand property(this, node.child2()); 1279 GPRReg baseGPR = base.gpr(); 1280 GPRReg propertyTagGPR = property.tagGPR(); 1281 GPRReg propertyPayloadGPR = property.payloadGPR(); 1282 1283 flushRegisters(); 1284 GPRResult2 resultTag(this); 1285 GPRResult resultPayload(this); 1286 callOperation(operationGetByValCell, resultTag.gpr(), resultPayload.gpr(), baseGPR, propertyTagGPR, propertyPayloadGPR); 1287 1288 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); 1289 break; 1290 } 1291 1275 1292 if (at(node.child1()).prediction() == PredictString) { 1276 1293 compileGetByValOnString(node); … … 1315 1332 1316 1333 case PutByVal: { 1334 PredictedType basePrediction = at(node.child2()).prediction(); 1335 if (!(basePrediction & PredictInt32) && basePrediction) { 1336 SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. 1337 JSValueOperand property(this, node.child2()); 1338 JSValueOperand value(this, node.child3()); 1339 GPRReg baseGPR = base.gpr(); 1340 GPRReg propertyTagGPR = property.tagGPR(); 1341 GPRReg propertyPayloadGPR = property.payloadGPR(); 1342 GPRReg valueTagGPR = value.tagGPR(); 1343 GPRReg valuePayloadGPR = value.payloadGPR(); 1344 1345 flushRegisters(); 1346 callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValCellStrict : operationPutByValCellNonStrict, baseGPR, propertyTagGPR, propertyPayloadGPR, valueTagGPR, valuePayloadGPR); 1347 1348 noResult(m_compileIndex); 1349 break; 1350 } 1351 1317 1352 SpeculateCellOperand base(this, node.child1()); 1318 1353 SpeculateStrictInt32Operand property(this, node.child2()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r96993 r97030 1384 1384 1385 1385 case GetByVal: { 1386 PredictedType basePrediction = at(node.child2()).prediction(); 1387 if (!(basePrediction & PredictInt32) && basePrediction) { 1388 JSValueOperand base(this, node.child1()); 1389 JSValueOperand property(this, node.child2()); 1390 GPRReg baseGPR = base.gpr(); 1391 GPRReg propertyGPR = property.gpr(); 1392 1393 flushRegisters(); 1394 GPRResult result(this); 1395 callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR); 1396 1397 jsValueResult(result.gpr(), m_compileIndex); 1398 break; 1399 } 1400 1386 1401 if (at(node.child1()).prediction() == PredictString) { 1387 1402 compileGetByValOnString(node); … … 1425 1440 1426 1441 case PutByVal: { 1442 PredictedType basePrediction = at(node.child2()).prediction(); 1443 if (!(basePrediction & PredictInt32) && basePrediction) { 1444 JSValueOperand arg1(this, node.child1()); 1445 JSValueOperand arg2(this, node.child2()); 1446 JSValueOperand arg3(this, node.child3()); 1447 GPRReg arg1GPR = arg1.gpr(); 1448 GPRReg arg2GPR = arg2.gpr(); 1449 GPRReg arg3GPR = arg3.gpr(); 1450 flushRegisters(); 1451 1452 callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR); 1453 1454 noResult(m_compileIndex); 1455 break; 1456 } 1457 1427 1458 SpeculateCellOperand base(this, node.child1()); 1428 1459 SpeculateStrictInt32Operand property(this, node.child2()); … … 1489 1520 1490 1521 case PutByValAlias: { 1522 PredictedType basePrediction = at(node.child2()).prediction(); 1523 ASSERT_UNUSED(basePrediction, (basePrediction & PredictInt32) || !basePrediction); 1524 1491 1525 SpeculateCellOperand base(this, node.child1()); 1492 1526 SpeculateStrictInt32Operand property(this, node.child2());
Note: See TracChangeset
for help on using the changeset viewer.