Changeset 124123 in webkit
- Timestamp:
- Jul 30, 2012 5:33:53 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r123989 r124123 1 2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Structures should be swept after all other objects 4 https://bugs.webkit.org/show_bug.cgi?id=92679 5 6 Reviewed by Filip Pizlo. 7 8 In order to get rid of ClassInfo from our objects, we need to be able to safely get the 9 ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the 10 Structure, but currently it is not safe to do so because the order of destruction of objects 11 is not guaranteed to sweep objects before their corresponding Structure. We can fix this by 12 sweeping Structures after everything else. 13 14 * heap/Heap.cpp: 15 (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures. 16 If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is 17 safe to sweep structures since we'll always do Structures last anyways due to the ordering of 18 MarkedSpace::forEachBlock. 19 (JSC): 20 (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now 21 calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out 22 these pointers after it has invalidated them to prevent accidental use-after-free in the sweep() 23 calls during lastChanceToFinalize(). 24 * heap/Heap.h: 25 (Heap): 26 * heap/HeapTimer.h: 27 (HeapTimer): 28 * heap/IncrementalSweeper.cpp: 29 (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures. 30 This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping 31 the first time. 32 (JSC): 33 (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we 34 make our first pass. We now null out the slots as we sweep them so that we can quickly find the 35 Structures during the second pass. 36 (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index. 37 (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify 38 the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can 39 assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock 40 iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds. 41 (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index. 42 * heap/IncrementalSweeper.h: Add declarations for new stuff. 43 (IncrementalSweeper): 44 * heap/MarkedAllocator.cpp: 45 (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and 46 if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing 47 the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that 48 will sweep some number of other blocks in place of the current block to mitigate the cost of the floating 49 Structure garbage. 50 (JSC::MarkedAllocator::addBlock): 51 * heap/MarkedAllocator.h: 52 (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no 53 longer valid to allocate from, so we set the current block to null. 54 * heap/MarkedBlock.cpp: 55 (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures 56 at an unsafe time. 57 * heap/MarkedSpace.cpp: 58 (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping. 59 (JSC): 60 * heap/MarkedSpace.h: 61 (JSC): 62 * runtime/JSGlobalData.cpp: 63 (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown. 64 1 65 2012-07-29 Filip Pizlo <fpizlo@apple.com> 2 66 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r122166 r124123 831 831 } 832 832 833 bool Heap::isSafeToSweepStructures() 834 { 835 return !m_sweeper || m_sweeper->structuresCanBeSwept(); 836 } 837 838 void Heap::didStartVMShutdown() 839 { 840 m_activityCallback->didStartVMShutdown(); 841 m_activityCallback = 0; 842 m_sweeper->didStartVMShutdown(); 843 m_sweeper = 0; 844 lastChanceToFinalize(); 845 } 846 833 847 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/Heap.h
r123813 r124123 169 169 170 170 bool isPagedOut(double deadline); 171 bool isSafeToSweepStructures(); 172 void didStartVMShutdown(); 171 173 172 174 private: -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
r121381 r124123 70 70 } 71 71 72 bool IncrementalSweeper::structuresCanBeSwept() 73 { 74 ASSERT(m_currentBlockToSweepIndex <= m_blocksToSweep.size()); 75 return !m_blocksToSweep.size() || m_currentBlockToSweepIndex >= m_blocksToSweep.size(); 76 } 77 72 78 void IncrementalSweeper::doSweep(double sweepBeginTime) 73 79 { 74 80 while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { 75 MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; 81 MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex]; 82 if (block->onlyContainsStructures()) { 83 m_currentBlockToSweepIndex++; 84 continue; 85 } 86 87 m_blocksToSweep[m_currentBlockToSweepIndex++] = 0; 88 89 if (!block->needsSweeping()) 90 continue; 91 92 block->sweep(); 93 m_globalData->heap.objectSpace().freeOrShrinkBlock(block); 94 95 CFTimeInterval elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime; 96 if (elapsedTime < sweepTimeSlice) 97 continue; 98 99 scheduleTimer(); 100 return; 101 } 102 103 while (m_currentStructureBlockToSweepIndex < m_blocksToSweep.size()) { 104 MarkedBlock* block = m_blocksToSweep[m_currentStructureBlockToSweepIndex]; 105 if (!block) { 106 m_currentStructureBlockToSweepIndex++; 107 continue; 108 } 109 110 m_blocksToSweep[m_currentStructureBlockToSweepIndex++] = 0; 111 76 112 if (!block->needsSweeping()) 77 113 continue; … … 96 132 WTF::copyToVector(blockSnapshot, m_blocksToSweep); 97 133 m_currentBlockToSweepIndex = 0; 134 m_currentStructureBlockToSweepIndex = 0; 98 135 scheduleTimer(); 136 } 137 138 void IncrementalSweeper::willFinishSweeping() 139 { 140 m_currentBlockToSweepIndex = m_currentStructureBlockToSweepIndex = 0; 141 m_blocksToSweep.clear(); 142 if (m_globalData) 143 cancelTimer(); 99 144 } 100 145 … … 103 148 IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) 104 149 : HeapTimer(globalData) 150 , m_structuresCanBeSwept(false) 105 151 { 106 152 } … … 115 161 } 116 162 163 bool IncrementalSweeper::structuresCanBeSwept() 164 { 165 return m_structuresCanBeSwept; 166 } 167 117 168 void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&) 118 169 { 170 m_structuresCanBeSwept = false; 119 171 } 120 172 173 void IncrementalSweeper::willFinishSweeping() 174 { 175 m_structuresCanBeSwept = true; 176 } 177 121 178 #endif 122 179 -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h
r121381 r124123 43 43 void startSweeping(const HashSet<MarkedBlock*>& blockSnapshot); 44 44 virtual void doWork(); 45 bool structuresCanBeSwept(); 46 void willFinishSweeping(); 45 47 46 48 private: 49 47 50 #if USE(CF) 48 51 IncrementalSweeper(Heap*, CFRunLoopRef); … … 53 56 54 57 unsigned m_currentBlockToSweepIndex; 58 unsigned m_currentStructureBlockToSweepIndex; 55 59 Vector<MarkedBlock*> m_blocksToSweep; 56 60 #else 57 61 58 62 IncrementalSweeper(JSGlobalData*); 59 63 64 bool m_structuresCanBeSwept; 65 60 66 #endif 61 67 }; -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp
r123931 r124123 4 4 #include "GCActivityCallback.h" 5 5 #include "Heap.h" 6 #include "IncrementalSweeper.h" 6 7 #include "JSGlobalData.h" 7 8 #include <wtf/CurrentTime.h> … … 30 31 { 31 32 if (!m_freeList.head) { 33 if (m_onlyContainsStructures && !m_heap->isSafeToSweepStructures()) { 34 if (m_currentBlock) { 35 m_currentBlock->didConsumeFreeList(); 36 m_currentBlock = 0; 37 } 38 return 0; 39 } 40 32 41 for (MarkedBlock*& block = m_blocksToSweep; block; block = static_cast<MarkedBlock*>(block->next())) { 33 42 m_freeList = block->sweep(MarkedBlock::SweepToFreeList); … … 105 114 { 106 115 ASSERT(!m_currentBlock); 107 ASSERT(!m_blocksToSweep);108 116 ASSERT(!m_freeList.head); 109 117 -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r123931 r124123 102 102 103 103 m_currentBlock->zapFreeList(m_freeList); 104 m_currentBlock = 0; 104 105 m_freeList = MarkedBlock::FreeList(); 105 106 } -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r123813 r124123 27 27 #include "MarkedBlock.h" 28 28 29 #include "IncrementalSweeper.h" 29 30 #include "JSCell.h" 30 31 #include "JSObject.h" … … 141 142 return FreeList(); 142 143 case Marked: 144 ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures()); 143 145 return sweepMode == SweepToFreeList 144 146 ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>() 145 147 : specializedSweep<Marked, SweepOnly, destructorCallNeeded>(); 146 148 case Zapped: 149 ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures()); 147 150 return sweepMode == SweepToFreeList 148 151 ? specializedSweep<Zapped, SweepToFreeList, destructorCallNeeded>() -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r123813 r124123 22 22 #include "MarkedSpace.h" 23 23 24 #include "IncrementalSweeper.h" 24 25 #include "JSGlobalObject.h" 25 26 #include "JSLock.h" … … 107 108 canonicalizeCellLivenessData(); 108 109 forEachBlock<LastChanceToFinalize>(); 110 } 111 112 void MarkedSpace::sweep() 113 { 114 m_heap->sweeper()->willFinishSweeping(); 115 forEachBlock<Sweep>(); 109 116 } 110 117 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r123813 r124123 236 236 } 237 237 238 inline void MarkedSpace::sweep()239 {240 forEachBlock<Sweep>();241 }242 243 238 inline size_t MarkedSpace::objectCount() 244 239 { -
trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp
r121806 r124123 224 224 { 225 225 ASSERT(!m_apiLock.currentThreadIsHoldingLock()); 226 heap.activityCallback()->didStartVMShutdown(); 227 heap.sweeper()->didStartVMShutdown(); 228 heap.lastChanceToFinalize(); 226 heap.didStartVMShutdown(); 229 227 230 228 delete interpreter;
Note: See TracChangeset
for help on using the changeset viewer.