Changeset 206183 in webkit
- Timestamp:
- Sep 20, 2016 3:57:16 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r206172 r206183 1 2016-09-20 Filip Pizlo <fpizlo@apple.com> 2 3 DFG::StoreBarrierInsertionPhase should assume that any epoch increment may make objects older 4 https://bugs.webkit.org/show_bug.cgi?id=162319 5 6 Reviewed by Saam Barati. 7 8 The store barrier phase needs to be aware of the fact that an object that is not in the 9 OldBlack state may be concurrently brought into that state. That means that: 10 11 - We cannot reason about the relative ages of objects. An object is either new, in which 12 case we can store to it without barriers, or it's not in which case it needs a barrier. 13 14 - After we insert a barrier on an object, the object is no longer new, because now the GC 15 knows about it and the GC may do things to it, like make it OldBlack. 16 17 This is a perf-neutral change. These optimizations were never particularly profitable. 18 19 * dfg/DFGStoreBarrierInsertionPhase.cpp: 20 1 21 2016-09-20 Filip Pizlo <fpizlo@apple.com> 2 22 -
trunk/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
r202955 r206183 411 411 } } 412 412 413 // We don't need a store barrier if the base is at least as new as the child. For414 // example this won't need a barrier:415 //416 // var o = {}417 // var p = {}418 // p.f = o419 //420 // This is stronger than the currentEpoch rule in considerBarrier(Edge), because it will421 // also eliminate barriers in cases like this:422 //423 // var o = {} // o.epoch = 1, currentEpoch = 1424 // var p = {} // o.epoch = 1, p.epoch = 2, currentEpoch = 2425 // var q = {} // o.epoch = 1, p.epoch = 2, q.epoch = 3, currentEpoch = 3426 // p.f = o // p.epoch >= o.epoch427 //428 // This relationship works because if it holds then we are in one of the following429 // scenarios. Note that we don't know *which* of these scenarios we are in, but it's430 // one of them (though without loss of generality, you can replace "a GC happened" with431 // "many GCs happened").432 //433 // 1) There is no GC between the allocation/last-barrier of base, child and now. Then434 // we definitely don't need a barrier.435 //436 // 2) There was a GC after child was allocated but before base was allocated. Then we437 // don't need a barrier, because base is still a new object.438 //439 // 3) There was a GC after both child and base were allocated. Then they are both old.440 // We don't need barriers on stores of old into old. Note that in this case it441 // doesn't matter if there was also a GC between the allocation of child and base.442 //443 // Note that barriers will lift an object into the current epoch. This is sort of weird.444 // It means that later if you store that object into some other object, and that other445 // object was previously newer object, you'll think that you need a barrier. We could446 // avoid this by tracking allocation epoch and barrier epoch separately. For now I think447 // that this would be overkill. But this does mean that there are the following448 // possibilities when this relationship holds:449 //450 // 4) Base is allocated first. A GC happens and base becomes old. Then we allocate451 // child. (Note that alternatively the GC could happen during the allocation of452 // child.) Then we run a barrier on base. Base will appear to be as new as child453 // (same epoch). At this point, we don't need another barrier on base.454 //455 // 5) Base is allocated first. Then we allocate child. Then we run a GC. Then we run a456 // barrier on base. Base will appear newer than child. We don't need a barrier457 // because both objects are old.458 //459 // Something we watch out for here is that the null epoch is a catch-all for objects460 // allocated before we did any epoch tracking. Two objects being in the null epoch461 // means that we don't know their epoch relationship.462 if (!!base->epoch() && !!child->epoch() && base->epoch() >= child->epoch()) {463 if (verbose)464 dataLog(" Rejecting because of epoch ordering.\n");465 return;466 }467 468 413 considerBarrier(base); 469 414 } … … 491 436 void insertBarrier(unsigned nodeIndex, Edge base, bool exitOK = true) 492 437 { 438 // Inserting a barrier means that the object may become marked by the GC, which will make 439 // the object black. 440 base->setEpoch(Epoch()); 441 493 442 // If we're in global mode, we should only insert the barriers once we have converged. 494 443 if (!reallyInsertBarriers()) … … 509 458 m_insertionSet.insertNode( 510 459 nodeIndex, SpecNone, StoreBarrier, m_node->origin.takeValidExit(exitOK), base); 511 512 base->setEpoch(m_currentEpoch);513 460 } 514 461
Note: See TracChangeset
for help on using the changeset viewer.