Changeset 178441 in webkit for trunk/Source/JavaScriptCore/jit/Repatch.cpp
- Timestamp:
- Jan 14, 2015, 1:00:52 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r177401 r178441 298 298 CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, RefPtr<JITStubRoutine>& stubRoutine) 299 299 { 300 300 301 VM* vm = &exec->vm(); 301 302 GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR); … … 349 350 watchpointSet->add(stubInfo.addWatchpoint(codeBlock)); 350 351 351 Structure* currStructure = structure; 352 Structure* currStructure = structure; 352 353 JSObject* protoObject = 0; 353 354 if (chain) { … … 748 749 749 750 JSCell* baseCell = baseValue.asCell(); 750 Structure* structure = baseCell->structure( );751 Structure* structure = baseCell->structure(*vm); 751 752 752 753 InlineCacheAction action = actionForCell(*vm, baseCell); … … 833 834 834 835 if (slot.isUnset()) 835 count = normalizePrototypeChain(exec, baseCell);836 count = normalizePrototypeChain(exec, structure); 836 837 else 837 838 count = normalizePrototypeChainForChainAccess( 838 exec, baseValue, slot.slotBase(), ident, offset);839 exec, structure, slot.slotBase(), ident, offset); 839 840 if (count == InvalidPrototypeChain) 840 841 return GiveUpOnCache; … … 908 909 static void emitPutReplaceStub( 909 910 ExecState* exec, 910 JSValue,911 911 const Identifier&, 912 912 const PutPropertySlot& slot, 913 913 StructureStubInfo& stubInfo, 914 PutKind,915 914 Structure* structure, 916 915 CodeLocationLabel failureLabel, … … 986 985 } 987 986 988 static void emitPutTransitionStub( 989 ExecState* exec, 990 JSValue, 991 const Identifier&, 992 const PutPropertySlot& slot, 993 StructureStubInfo& stubInfo, 994 PutKind putKind, 995 Structure* structure, 996 Structure* oldStructure, 997 StructureChain* prototypeChain, 998 CodeLocationLabel failureLabel, 999 RefPtr<JITStubRoutine>& stubRoutine) 1000 { 1001 VM* vm = &exec->vm(); 987 static Structure* emitPutTransitionStubAndGetOldStructure(ExecState* exec, VM* vm, Structure*& structure, const Identifier& ident, 988 const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 989 { 990 PropertyName pname(ident); 991 Structure* oldStructure = structure; 992 if (!oldStructure->isObject() || oldStructure->isDictionary() || pname.asIndex() != PropertyName::NotAnIndex) 993 return nullptr; 994 995 PropertyOffset propertyOffset; 996 structure = Structure::addPropertyTransitionToExistingStructureConcurrently(oldStructure, ident.impl(), 0, propertyOffset); 997 998 if (!structure || !structure->isObject() || structure->isDictionary() || !structure->propertyAccessesAreCacheable()) 999 return nullptr; 1000 1001 // Skip optimizing the case where we need a realloc, if we don't have 1002 // enough registers to make it happen. 1003 if (GPRInfo::numberOfRegisters < 6 1004 && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity() 1005 && oldStructure->outOfLineCapacity()) { 1006 return nullptr; 1007 } 1008 1009 // Skip optimizing the case where we need realloc, and the structure has 1010 // indexing storage. 1011 // FIXME: We shouldn't skip this! Implement it! 1012 // https://bugs.webkit.org/show_bug.cgi?id=130914 1013 if (oldStructure->couldHaveIndexingHeader()) 1014 return nullptr; 1015 1016 if (normalizePrototypeChain(exec, structure) == InvalidPrototypeChain) 1017 return nullptr; 1018 1019 StructureChain* prototypeChain = structure->prototypeChain(exec); 1020 1021 // emitPutTransitionStub 1022 1023 CodeLocationLabel failureLabel = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase); 1024 RefPtr<JITStubRoutine>& stubRoutine = stubInfo.stubRoutine; 1002 1025 1003 1026 GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR); … … 1223 1246 structure->outOfLineCapacity() != oldStructure->outOfLineCapacity(), 1224 1247 structure); 1225 } 1226 1227 static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 1248 1249 return oldStructure; 1250 } 1251 1252 static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 1228 1253 { 1229 1254 if (Options::forceICFailure()) … … 1235 1260 if (!baseValue.isCell()) 1236 1261 return GiveUpOnCache; 1237 JSCell* baseCell = baseValue.asCell();1238 Structure* structure = baseCell->structure(*vm);1239 Structure* oldStructure = structure->previousID();1240 1262 1241 1263 if (!slot.isCacheablePut() && !slot.isCacheableCustom() && !slot.isCacheableSetter()) 1242 1264 return GiveUpOnCache; 1265 1243 1266 if (!structure->propertyAccessesAreCacheable()) 1244 1267 return GiveUpOnCache; … … 1247 1270 if (slot.base() == baseValue && slot.isCacheablePut()) { 1248 1271 if (slot.type() == PutPropertySlot::NewProperty) { 1249 if (structure->isDictionary()) 1272 1273 Structure* oldStructure = emitPutTransitionStubAndGetOldStructure(exec, vm, structure, ident, slot, stubInfo, putKind); 1274 if (!oldStructure) 1250 1275 return GiveUpOnCache; 1251 1276 1252 // Skip optimizing the case where we need a realloc, if we don't have1253 // enough registers to make it happen.1254 if (GPRInfo::numberOfRegisters < 61255 && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()1256 && oldStructure->outOfLineCapacity())1257 return GiveUpOnCache;1258 1259 // Skip optimizing the case where we need realloc, and the structure has1260 // indexing storage.1261 // FIXME: We shouldn't skip this! Implement it!1262 // https://bugs.webkit.org/show_bug.cgi?id=1309141263 if (oldStructure->couldHaveIndexingHeader())1264 return GiveUpOnCache;1265 1266 if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)1267 return GiveUpOnCache;1268 1269 1277 StructureChain* prototypeChain = structure->prototypeChain(exec); 1270 1271 emitPutTransitionStub(1272 exec, baseValue, ident, slot, stubInfo, putKind,1273 structure, oldStructure, prototypeChain,1274 stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase),1275 stubInfo.stubRoutine);1276 1278 1277 1279 RepatchBuffer repatchBuffer(codeBlock); … … 1295 1297 return RetryCacheLater; 1296 1298 } 1299 1297 1300 if ((slot.isCacheableCustom() || slot.isCacheableSetter()) 1298 1301 && stubInfo.patch.spillMode == DontSpill) { … … 1303 1306 size_t count = 0; 1304 1307 if (baseValue != slot.base()) { 1305 count = normalizePrototypeChainForChainAccess(exec, baseCell, slot.base(), ident, offset);1308 count = normalizePrototypeChainForChainAccess(exec, structure, slot.base(), ident, offset); 1306 1309 if (count == InvalidPrototypeChain) 1307 1310 return GiveUpOnCache; 1308 1309 1311 prototypeChain = structure->prototypeChain(exec); 1310 1312 } … … 1334 1336 } 1335 1337 1336 void repatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)1338 void repatchPutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 1337 1339 { 1338 1340 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 1339 1341 1340 if (tryCachePutByID(exec, baseValue, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)1342 if (tryCachePutByID(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache) 1341 1343 repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind)); 1342 1344 } … … 1347 1349 VM* vm = &exec->vm(); 1348 1350 1349 if (!baseValue.isCell() || !structure)1351 if (!baseValue.isCell()) 1350 1352 return GiveUpOnCache; 1351 JSCell* baseCell = baseValue.asCell(); 1352 1353 if (baseCell->structure(*vm)->id() != structure->id()) 1354 return GiveUpOnCache; 1355 1356 Structure* oldStructure = structure->previousID(); 1357 1358 1353 1359 1354 if (!slot.isCacheablePut() && !slot.isCacheableCustom() && !slot.isCacheableSetter()) 1360 1355 return GiveUpOnCache; … … 1369 1364 1370 1365 if (slot.type() == PutPropertySlot::NewProperty) { 1371 if (structure->isDictionary())1372 return GiveUpOnCache;1373 1374 // Skip optimizing the case where we need a realloc, if we don't have1375 // enough registers to make it happen.1376 if (GPRInfo::numberOfRegisters < 61377 && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()1378 && oldStructure->outOfLineCapacity())1379 return GiveUpOnCache;1380 1381 // Skip optimizing the case where we need realloc, and the structure has1382 // indexing storage.1383 if (oldStructure->couldHaveIndexingHeader())1384 return GiveUpOnCache;1385 1386 if (normalizePrototypeChain(exec, baseCell) == InvalidPrototypeChain)1387 return GiveUpOnCache;1388 1389 StructureChain* prototypeChain = structure->prototypeChain(exec);1390 1391 1366 list = PolymorphicPutByIdList::from(putKind, stubInfo); 1392 1367 if (list->isFull()) 1393 1368 return GiveUpOnCache; // Will get here due to recursion. 1394 1395 // We're now committed to creating the stub. Mogrify the meta-data accordingly.1396 emitPutTransitionStub( 1397 exec, baseValue, propertyName, slot, stubInfo, putKind,1398 structure, oldStructure, prototypeChain,1399 CodeLocationLabel(list->currentSlowPathTarget()), 1400 stubRoutine);1401 1369 1370 Structure* oldStructure = emitPutTransitionStubAndGetOldStructure(exec, vm, structure, propertyName, slot, stubInfo, putKind); 1371 1372 if (!oldStructure) 1373 return GiveUpOnCache; 1374 1375 StructureChain* prototypeChain = structure->prototypeChain(exec); 1376 stubRoutine = stubInfo.stubRoutine; 1402 1377 list->addAccess( 1403 1378 PutByIdAccess::transition( … … 1405 1380 oldStructure, structure, prototypeChain, 1406 1381 stubRoutine)); 1382 1407 1383 } else { 1408 1384 list = PolymorphicPutByIdList::from(putKind, stubInfo); … … 1414 1390 // We're now committed to creating the stub. Mogrify the meta-data accordingly. 1415 1391 emitPutReplaceStub( 1416 exec, baseValue, propertyName, slot, stubInfo, putKind,1392 exec, propertyName, slot, stubInfo, 1417 1393 structure, CodeLocationLabel(list->currentSlowPathTarget()), stubRoutine); 1418 1394 1419 1395 list->addAccess( 1420 1396 PutByIdAccess::replace( … … 1422 1398 structure, stubRoutine)); 1423 1399 } 1424 1425 1400 RepatchBuffer repatchBuffer(codeBlock); 1426 1401 repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine->code().code())); 1427 1428 1402 if (list->isFull()) 1429 1403 repatchCall(repatchBuffer, stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind)); 1430 1404 1431 1405 return RetryCacheLater; 1432 1406 } … … 1439 1413 size_t count = 0; 1440 1414 if (baseValue != slot.base()) { 1441 count = normalizePrototypeChainForChainAccess(exec, baseCell, slot.base(), propertyName, offset);1415 count = normalizePrototypeChainForChainAccess(exec, structure, slot.base(), propertyName, offset); 1442 1416 if (count == InvalidPrototypeChain) 1443 1417 return GiveUpOnCache; 1444 1445 1418 prototypeChain = structure->prototypeChain(exec); 1446 1419 } 1420 1447 1421 PolymorphicPutByIdList* list; 1448 1422 list = PolymorphicPutByIdList::from(putKind, stubInfo); … … 1495 1469 CodeBlock* codeBlock = exec->codeBlock(); 1496 1470 VM* vm = &exec->vm(); 1497 Structure* structure = base->structure( );1471 Structure* structure = base->structure(*vm); 1498 1472 1499 1473 PropertyOffset offsetIgnored; 1500 size_t count = normalizePrototypeChainForChainAccess(exec, base, wasFound ? slot.slotBase() : JSValue(), ident, offsetIgnored); 1474 JSValue foundSlotBase = wasFound ? slot.slotBase() : JSValue(); 1475 size_t count = !foundSlotBase || foundSlotBase != base ? 1476 normalizePrototypeChainForChainAccess(exec, structure, foundSlotBase, ident, offsetIgnored) : 0; 1501 1477 if (count == InvalidPrototypeChain) 1502 1478 return GiveUpOnCache;
Note:
See TracChangeset
for help on using the changeset viewer.