Changeset 128563 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Sep 14, 2012, 12:06:23 AM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r128558 r128563 1 2012-09-14 Mark Hahnenberg <[email protected]> 2 3 Remove the Zapped BlockState 4 https://bugs.webkit.org/show_bug.cgi?id=96708 5 6 Reviewed by Geoffrey Garen. 7 8 The Zapped block state is rather confusing. It indicates that a block is in one of two different states that we 9 can't tell the difference between: 10 11 1) I have run all destructors of things that are zapped, and I have not allocated any more objects. This block 12 is ready for reclaiming if you so choose. 13 2) I have run all the destructors of things that are zapped, but I have allocated more stuff since then, so it 14 is not safe to reclaim this block. 15 16 This state adds a lot of complexity to our state transition model for MarkedBlocks. We should get rid of it. 17 We can replace this state by making sure mark bits represent all of the liveness information we need when running 18 our conservative stack scan. Instead of zapping the free list when canonicalizing cell liveness data prior to 19 a conservative scan, we can instead mark all objects in the block except for those in the free list. This should 20 incur no performance penalty since we're doing it on a very small O(1) number of blocks at the beginning of the collection. 21 22 For the time being we still need to use zapping to determine whether we have run an object's destructor or not. 23 24 * heap/MarkedAllocator.cpp: 25 (JSC::MarkedAllocator::tryAllocateHelper): Renaming stuff. 26 * heap/MarkedAllocator.h: Renamed zapFreeList to canonicalizeCellLivenessData to match. 27 (MarkedAllocator): 28 (JSC::MarkedAllocator::canonicalizeCellLivenessData): Same as old zapFreeList, but just call canonicalize instead. 29 * heap/MarkedBlock.cpp: 30 (JSC::MarkedBlock::specializedSweep): Remove the check for Zapped block stuff. Also change the block state to Marked 31 instead of Zapped if we're not producing a FreeList since that's the only other state that really makes any sense. 32 (JSC::MarkedBlock::sweepHelper): Remove Zapped related code. 33 (SetAllMarksFunctor): Functor to set all the mark bits in the block since there's not a simple function to call on 34 the Bitmap itself. 35 (JSC::SetAllMarksFunctor::operator()): 36 (JSC): 37 (JSC::MarkedBlock::canonicalizeCellLivenessData): Remove all the stuff for Zapped. For FreeListed, set all the mark bits 38 and then clear the ones for the objects in the FreeList. This ensures that only the things that were in the FreeList 39 are considered to be dead by the conservative scan, just like if we were to have zapped the FreeList like before. 40 * heap/MarkedBlock.h: 41 (MarkedBlock): 42 (JSC::MarkedBlock::clearMarked): Add function to clear individual mark bits, since we need that functionality now. 43 (JSC): 44 (JSC::MarkedBlock::isLive): Remove code for Zapped stuff. Marked handles all interesting cases now. 45 (JSC::MarkedBlock::forEachCell): Add new iterator function that iterates over all cells in the block, regardless of 46 whether they're live or a dead. 47 * heap/MarkedSpace.cpp: 48 (JSC::MarkedSpace::canonicalizeCellLivenessData): Change to call the renamed canonicalize function. 49 1 50 2012-09-13 Kevin Funk <[email protected]> 2 51 -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp
r128141 r128563 50 50 51 51 if (bytes > block->cellSize()) { 52 block-> zapFreeList(freeList);52 block->canonicalizeCellLivenessData(freeList); 53 53 continue; 54 54 } -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r128141 r128563 22 22 MarkedAllocator(); 23 23 void reset(); 24 void zapFreeList();24 void canonicalizeCellLivenessData(); 25 25 size_t cellSize() { return m_cellSize; } 26 26 bool cellsNeedDestruction() { return m_cellsNeedDestruction; } … … 93 93 } 94 94 95 inline void MarkedAllocator:: zapFreeList()95 inline void MarkedAllocator::canonicalizeCellLivenessData() 96 96 { 97 97 if (!m_currentBlock) { … … 100 100 } 101 101 102 m_currentBlock-> zapFreeList(m_freeList);102 m_currentBlock->canonicalizeCellLivenessData(m_freeList); 103 103 m_currentBlock = 0; 104 104 m_freeList = MarkedBlock::FreeList(); -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r127338 r128563 82 82 83 83 JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); 84 if (blockState == Zapped && !cell->isZapped())85 continue;86 84 87 85 if (destructorCallNeeded && blockState != New) … … 96 94 } 97 95 98 m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Zapped);96 m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked); 99 97 return FreeList(head, count * cellSize()); 100 98 } … … 133 131 ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>() 134 132 : specializedSweep<Marked, SweepOnly, destructorCallNeeded>(); 135 case Zapped:136 ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures());137 return sweepMode == SweepToFreeList138 ? specializedSweep<Zapped, SweepToFreeList, destructorCallNeeded>()139 : specializedSweep<Zapped, SweepOnly, destructorCallNeeded>();140 133 } 141 134 … … 144 137 } 145 138 146 void MarkedBlock::zapFreeList(const FreeList& freeList) 139 class SetAllMarksFunctor : public MarkedBlock::VoidFunctor { 140 public: 141 void operator()(JSCell* cell) 142 { 143 MarkedBlock::blockFor(cell)->setMarked(cell); 144 } 145 }; 146 147 void MarkedBlock::canonicalizeCellLivenessData(const FreeList& freeList) 147 148 { 148 149 HEAP_LOG_BLOCK_STATE_TRANSITION(this); … … 157 158 158 159 ASSERT(!head); 159 160 160 return; 161 161 } 162 163 if (m_state == Zapped) { 164 // If the block is in the Zapped state then we know that someone already 165 // zapped it for us. This could not have happened during a GC, but might 166 // be the result of someone having done a GC scan to perform some operation 167 // over all live objects (or all live blocks). It also means that somebody 168 // had allocated in this block since the last GC, swept all dead objects 169 // onto the free list, left the block in the FreeListed state, then the heap 170 // scan happened, and canonicalized the block, leading to all dead objects 171 // being zapped. Therefore, it is safe for us to simply do nothing, since 172 // dead objects will have 0 in their vtables and live objects will have 173 // non-zero vtables, which is consistent with the block being zapped. 174 175 ASSERT(!head); 176 177 return; 178 } 179 162 180 163 ASSERT(m_state == FreeListed); 181 164 182 165 // Roll back to a coherent state for Heap introspection. Cells newly 183 166 // allocated from our free list are not currently marked, so we need another 184 // way to tell what's live vs dead. We use zapping for that.167 // way to tell what's live vs dead. 185 168 169 SetAllMarksFunctor functor; 170 forEachCell(functor); 171 186 172 FreeCell* next; 187 173 for (FreeCell* current = head; current; current = next) { 188 174 next = current->next; 189 175 reinterpret_cast<JSCell*>(current)->zap(); 176 clearMarked(current); 190 177 } 191 178 192 m_state = Zapped;179 m_state = Marked; 193 180 } 194 181 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r128498 r128563 137 137 // of these functions: 138 138 void didConsumeFreeList(); // Call this once you've allocated all the items in the free list. 139 void zapFreeList(const FreeList&); // Call this to undo the free list.139 void canonicalizeCellLivenessData(const FreeList&); 140 140 141 141 void clearMarks(); … … 155 155 bool isLiveCell(const void*); 156 156 void setMarked(const void*); 157 157 void clearMarked(const void*); 158 158 159 bool needsSweeping(); 159 160 … … 186 187 #endif 187 188 189 template <typename Functor> void forEachCell(Functor&); 188 190 template <typename Functor> void forEachLiveCell(Functor&); 189 191 template <typename Functor> void forEachDeadCell(Functor&); … … 192 194 static const size_t atomAlignmentMask = atomSize - 1; // atomSize must be a power of two. 193 195 194 enum BlockState { New, FreeListed, Allocated, Marked , Zapped};196 enum BlockState { New, FreeListed, Allocated, Marked }; 195 197 template<bool destructorCallNeeded> FreeList sweepHelper(SweepMode = SweepOnly); 196 198 … … 365 367 } 366 368 369 inline void MarkedBlock::clearMarked(const void* p) 370 { 371 ASSERT(m_marks.get(atomNumber(p))); 372 m_marks.clear(atomNumber(p)); 373 } 374 367 375 inline bool MarkedBlock::isLive(const JSCell* cell) 368 376 { … … 370 378 case Allocated: 371 379 return true; 372 case Zapped: 373 if (isZapped(cell)) { 374 // Object dead in previous collection, not allocated since previous collection: mark bit should not be set. 375 ASSERT(!m_marks.get(atomNumber(cell))); 376 return false; 377 } 378 379 // Newly allocated objects: mark bit not set. 380 // Objects that survived prior collection: mark bit set. 381 return true; 380 382 381 case Marked: 383 382 return m_marks.get(atomNumber(cell)); … … 406 405 407 406 return isLive(static_cast<const JSCell*>(p)); 407 } 408 409 template <typename Functor> inline void MarkedBlock::forEachCell(Functor& functor) 410 { 411 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 412 JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); 413 functor(cell); 414 } 408 415 } 409 416 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r128141 r128563 147 147 { 148 148 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 149 allocatorFor(cellSize). zapFreeList();150 destructorAllocatorFor(cellSize). zapFreeList();151 } 152 153 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 154 allocatorFor(cellSize). zapFreeList();155 destructorAllocatorFor(cellSize). zapFreeList();156 } 157 158 m_largeAllocator. zapFreeList();159 m_structureAllocator. zapFreeList();149 allocatorFor(cellSize).canonicalizeCellLivenessData(); 150 destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 151 } 152 153 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 154 allocatorFor(cellSize).canonicalizeCellLivenessData(); 155 destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 156 } 157 158 m_largeAllocator.canonicalizeCellLivenessData(); 159 m_structureAllocator.canonicalizeCellLivenessData(); 160 160 } 161 161
Note:
See TracChangeset
for help on using the changeset viewer.