Changeset 267304 in webkit
- Timestamp:
- Sep 18, 2020, 6:22:42 PM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
heap/PreciseAllocation.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r267301 r267304 1 2020-09-18 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] PreciseAllocation's isNewlyAllocated flag should be propagated from isMarked at GC begin phase to make isLive correct 4 https://bugs.webkit.org/show_bug.cgi?id=216717 5 6 Reviewed by Mark Lam. 7 8 When starting full GC, at beginMarking, PreciseAllocation's mark bit is cleared to be usable for upcoming marking. 9 However, this means that HeapCell::isLive will see this object as dead until it is marked. 10 Let's consider that this object is not newly allocated one. Then, its isNewlyAllocated is false. And now mark bit 11 is also cleared. Since PreciseAllocation::isLive is isNewlyAllocated || isMarked, then it looks dead, while it is live. 12 This confuses HeapCell:isLive function and makes some of watchpoints perform wrong decisions (e.g. this condition is 13 no longer valid, let's just discard it). 14 At the beginning of full collection, we should propagate the old mark bit to isNewlyAllocated so that it looks live 15 during marking. This is similar trick to MarkedBlock::aboutToMark. 16 17 * heap/PreciseAllocation.cpp: 18 (JSC::PreciseAllocation::flip): 19 1 20 2020-09-18 Saam Barati <sbarati@apple.com> 2 21 -
trunk/Source/JavaScriptCore/heap/PreciseAllocation.cpp
r262570 r267304 214 214 { 215 215 ASSERT(heap()->collectionScope() == CollectionScope::Full); 216 clearMarked(); 216 // Propagate the last time's mark bit to m_isNewlyAllocated so that `isLive` will say "yes" until this GC cycle finishes. 217 // After that, m_isNewlyAllocated is cleared again. So only previously marked or actually newly created objects survive. 218 // We do not need to care about concurrency here since marking thread is stopped right now. This is equivalent to the logic 219 // of MarkedBlock::aboutToMarkSlow. 220 // We invoke this function only when this is full collection. This ensures that at the end of upcoming cycle, we will 221 // clear NewlyAllocated bits of all objects. So this works correctly. 222 // 223 // N: NewlyAllocated, M: Marked 224 // after this at the end When cycle 225 // N M function N M of cycle N M is finished N M 226 // The live object survives the last cycle 0 1 => 1 0 => 1 1 => 0 1 => live 227 // The dead object in the last cycle 0 0 => 0 0 => 0 0 => 0 0 => dead 228 // The live object newly created after this => 1 0 => 1 1 => 0 1 => live 229 // The dead object newly created after this => 1 0 => 1 0 => 0 0 => dead 230 // The live object newly created before this 1 0 => 1 0 => 1 1 => 0 1 => live 231 // The dead object newly created before this 1 0 => 1 0 => 1 0 => 0 0 => dead 232 // ^ 233 // This is ensured since this function is used only for full GC. 234 m_isNewlyAllocated |= isMarked(); 235 m_isMarked.store(false, std::memory_order_relaxed); 217 236 } 218 237
Note:
See TracChangeset
for help on using the changeset viewer.