Changeset 207263 in webkit
- Timestamp:
- Oct 12, 2016 4:56:34 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r207241 r207263 1 2016-10-12 Filip Pizlo <fpizlo@apple.com> 2 3 The blackening of CellState is a bad way of tracking if the object is being marked for the first time 4 https://bugs.webkit.org/show_bug.cgi?id=163343 5 6 Reviewed by Mark Lam. 7 8 When I first added the concept of NewGrey/OldGrey, I had the SlotVisitor store the old cell 9 state in itself, so that it could use it to decide what to do for reportExtraMemoryVisited(). 10 11 Then I changed it in a recent commit, because I wanted the freedom to have SlotVisitor visit 12 multiple objects in tandem. But I never ended up using this capability. Still, I liked the 13 new way better: instead of the SlotVisitor rembemering the state-before-blackening, we would 14 make the object's state reflect whether it was black for the first time or not. That seemed 15 convenient. 16 17 Unfortunately it's wrong. After we blacken the object, a concurrent barrier could instantly 18 grey it. Then we would forget that we are visiting this object for the first time. 19 Subsequent visits will think that they are not the first. So, we will fail to do the right 20 thing in reportExtraMemoryVisited(). 21 22 So, this reverts that change. This is a little more than just a revert, though. I've changed 23 the terminology a bit. For example, I got tired of reading Black and having to remind myself 24 that it really means that the object has begun being visited, instead of the more strict 25 meaning that implies that it has already been visited. We want to say that it's Black or 26 currently being scanned. I'm going to adopt Siebert's term for this: Anthracite [1]. So, our 27 black CellState is now called AnthraciteOrBlack. 28 29 [1] https://pdfs.semanticscholar.org/7ae4/633265aead1f8835cf7966e179d02c2c8a4b.pdf 30 31 * heap/CellState.h: 32 (JSC::isBlack): Deleted. 33 (JSC::blacken): Deleted. 34 * heap/Heap.cpp: 35 (JSC::Heap::addToRememberedSet): 36 (JSC::Heap::writeBarrierSlowPath): 37 * heap/Heap.h: 38 * heap/HeapInlines.h: 39 (JSC::Heap::reportExtraMemoryVisited): 40 (JSC::Heap::reportExternalMemoryVisited): 41 * heap/SlotVisitor.cpp: 42 (JSC::SlotVisitor::appendToMarkStack): 43 (JSC::SlotVisitor::visitChildren): 44 * heap/SlotVisitor.h: 45 * heap/SlotVisitorInlines.h: 46 (JSC::SlotVisitor::reportExtraMemoryVisited): 47 (JSC::SlotVisitor::reportExternalMemoryVisited): 48 * llint/LLIntData.cpp: 49 (JSC::LLInt::Data::performAssertions): 50 * llint/LowLevelInterpreter.asm: 51 1 52 2016-10-12 Mark Lam <mark.lam@apple.com> 2 53 -
trunk/Source/JavaScriptCore/heap/CellState.h
r206555 r207263 31 31 32 32 enum class CellState : uint8_t { 33 // The object is black for the first time during this GC. 34 NewBlack = 0, 35 36 // The object is black for the Nth time during this full GC cycle (N > 1). An object may get to 37 // this state if it transitions from black back to grey during a concurrent GC, or because it 38 // wound up in the remembered set because of a generational barrier. 39 OldBlack = 1, 33 // The object is either currently being scanned (anthracite) or it has finished being scanned 34 // (black). It could be scanned for the first time this GC, or the Nth time - if it's anthracite 35 // then the SlotVisitor knows. We explicitly say "anthracite or black" to emphasize the fact that 36 // this is no guarantee that we have finished scanning the object, unless you also know that all 37 // SlotVisitors are done. 38 AnthraciteOrBlack = 0, 40 39 41 40 // The object is in eden. During GC, this means that the object has not been marked yet. 42 NewWhite = 2,41 NewWhite = 1, 43 42 44 43 // The object is grey - i.e. it will be scanned - and this is the first time in this GC that we are 45 44 // going to scan it. If this is an eden GC, this also means that the object is in eden. 46 NewGrey = 3,45 NewGrey = 2, 47 46 48 47 // The object is grey - i.e. it will be scanned - but it either belongs to old gen (if this is eden 49 48 // GC) or it is grey a second time in this current GC (because a concurrent store barrier requested 50 49 // re-greying). 51 OldGrey = 450 OldGrey = 3 52 51 }; 53 52 54 static const unsigned blackThreshold = 1; // x <= blackThreshold means x is black.53 static const unsigned blackThreshold = 0; // x <= blackThreshold means x is AnthraciteOrBlack. 55 54 static const unsigned tautologicalThreshold = 100; // x <= tautologicalThreshold is always true. 56 55 … … 60 59 } 61 60 62 inline bool isBlack(CellState cellState)63 {64 return isWithinThreshold(cellState, blackThreshold);65 }66 67 inline CellState blacken(CellState cellState)68 {69 if (cellState == CellState::NewGrey)70 return CellState::NewBlack;71 ASSERT(cellState == CellState::NewBlack || cellState == CellState::OldBlack || cellState == CellState::OldGrey);72 return CellState::OldBlack;73 }74 75 61 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r207179 r207263 917 917 ASSERT(cell); 918 918 ASSERT(!Options::useConcurrentJIT() || !isCompilationThread()); 919 ASSERT( isBlack(cell->cellState()));919 ASSERT(cell->cellState() == CellState::AnthraciteOrBlack); 920 920 // Indicate that this object is grey and that it's one of the following: 921 921 // - A re-greyed object during a concurrent collection. … … 1553 1553 // not black. But we can't know for sure until we fire off a fence. 1554 1554 WTF::storeLoadFence(); 1555 if ( !isBlack(from->cellState()))1555 if (from->cellState() != CellState::AnthraciteOrBlack) 1556 1556 return; 1557 1557 } -
trunk/Source/JavaScriptCore/heap/Heap.h
r207179 r207263 182 182 // memory growth. 183 183 void reportExtraMemoryAllocated(size_t); 184 void reportExtraMemoryVisited( JSCell*, size_t);184 void reportExtraMemoryVisited(CellState oldState, size_t); 185 185 186 186 #if ENABLE(RESOURCE_USAGE) 187 187 // Use this API to report the subset of extra memory that lives outside this process. 188 void reportExternalMemoryVisited( JSCell*, size_t);188 void reportExternalMemoryVisited(CellState oldState, size_t); 189 189 size_t externalMemorySize() { return m_externalMemorySize; } 190 190 #endif -
trunk/Source/JavaScriptCore/heap/HeapInlines.h
r206555 r207263 159 159 } 160 160 161 inline void Heap::reportExtraMemoryVisited( JSCell* cell, size_t size)161 inline void Heap::reportExtraMemoryVisited(CellState oldState, size_t size) 162 162 { 163 163 // We don't want to double-count the extra memory that was reported in previous collections. 164 if (operationInProgress() == EdenCollection && cell->cellState() == CellState::OldBlack)164 if (operationInProgress() == EdenCollection && oldState == CellState::OldGrey) 165 165 return; 166 166 … … 175 175 176 176 #if ENABLE(RESOURCE_USAGE) 177 inline void Heap::reportExternalMemoryVisited( JSCell* cell, size_t size)177 inline void Heap::reportExternalMemoryVisited(CellState oldState, size_t size) 178 178 { 179 179 // We don't want to double-count the external memory that was reported in previous collections. 180 if (operationInProgress() == EdenCollection && cell->cellState() == CellState::OldBlack)180 if (operationInProgress() == EdenCollection && oldState == CellState::OldGrey) 181 181 return; 182 182 -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r207230 r207263 229 229 ASSERT(Heap::isMarkedConcurrently(cell)); 230 230 ASSERT(!cell->isZapped()); 231 ASSERT(cell->cellState() == CellState::NewGrey || cell->cellState() == CellState::OldGrey); 231 232 232 233 container.noteMarked(); … … 294 295 SetCurrentCellScope currentCellScope(*this, cell); 295 296 296 cell->setCellState(blacken(cell->cellState())); 297 m_oldCellState = cell->cellState(); 298 299 // There is no race here - the cell state cannot change right now. Grey objects can only be 300 // visited by one marking thread. Neither the barrier nor marking will change the state of an 301 // object that is already grey. 302 ASSERT(m_oldCellState == CellState::OldGrey || m_oldCellState == CellState::NewGrey); 303 304 cell->setCellState(CellState::AnthraciteOrBlack); 297 305 298 306 WTF::storeLoadFence(); … … 319 327 320 328 if (UNLIKELY(m_heapSnapshotBuilder)) { 321 if ( cell->cellState() != CellState::OldBlack)329 if (m_oldCellState == CellState::NewGrey) 322 330 m_heapSnapshotBuilder->appendNode(const_cast<JSCell*>(cell)); 323 331 } -
trunk/Source/JavaScriptCore/heap/SlotVisitor.h
r207222 r207263 166 166 HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr }; 167 167 JSCell* m_currentCell { nullptr }; 168 CellState m_oldCellState; 168 169 169 170 public: -
trunk/Source/JavaScriptCore/heap/SlotVisitorInlines.h
r206525 r207263 106 106 inline void SlotVisitor::reportExtraMemoryVisited(size_t size) 107 107 { 108 heap()->reportExtraMemoryVisited(m_ currentCell, size);108 heap()->reportExtraMemoryVisited(m_oldCellState, size); 109 109 } 110 110 … … 112 112 inline void SlotVisitor::reportExternalMemoryVisited(size_t size) 113 113 { 114 heap()->reportExternalMemoryVisited(m_ currentCell, size);114 heap()->reportExternalMemoryVisited(m_oldCellState, size); 115 115 } 116 116 #endif -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r207239 r207263 215 215 216 216 STATIC_ASSERT(MarkedBlock::blockSize == 16 * 1024); 217 STATIC_ASSERT(blackThreshold == 1);217 STATIC_ASSERT(blackThreshold == 0); 218 218 219 219 ASSERT(bitwise_cast<uintptr_t>(ShadowChicken::Packet::tailMarker()) == static_cast<uintptr_t>(0x7a11)); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r207239 r207263 410 410 const MarkedBlockMask = ~(MarkedBlockSize - 1) 411 411 412 const BlackThreshold = 1412 const BlackThreshold = 0 413 413 414 414 # Allocation constants
Note: See TracChangeset
for help on using the changeset viewer.