Changeset 106676 in webkit for trunk/Source/JavaScriptCore/heap
- Timestamp:
- Feb 3, 2012, 11:21:28 AM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore/heap
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/Heap.cpp
r105442 r106676 812 812 { 813 813 GCPHASE(ResetAllocator); 814 resetAllocator ();814 resetAllocators(); 815 815 } 816 816 … … 847 847 } 848 848 849 void Heap::resetAllocator ()849 void Heap::resetAllocators() 850 850 { 851 851 m_extraCost = 0; 852 m_objectSpace.resetAllocator ();852 m_objectSpace.resetAllocators(); 853 853 } 854 854 -
trunk/Source/JavaScriptCore/heap/Heap.h
r106078 r106676 26 26 #include "HandleHeap.h" 27 27 #include "HandleStack.h" 28 #include "MarkedAllocator.h" 28 29 #include "MarkedBlock.h" 29 30 #include "MarkedBlockSet.h" … … 95 96 inline bool isBusy(); 96 97 97 Marked Space::SizeClass& sizeClassForObject(size_t bytes) { return m_objectSpace.sizeClassFor(bytes); }98 MarkedAllocator& allocatorForObject(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } 98 99 void* allocate(size_t); 99 100 CheckedBoolean tryAllocateStorage(size_t, void**); … … 137 138 private: 138 139 friend class MarkedSpace; 140 friend class MarkedAllocator; 139 141 friend class MarkedBlock; 140 142 friend class BumpSpace; … … 161 163 void canonicalizeCellLivenessData(); 162 164 163 void resetAllocator ();165 void resetAllocators(); 164 166 void freeBlocks(MarkedBlock*); 165 167 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r106078 r106676 36 36 , m_heap(heap) 37 37 { 38 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) 39 sizeClassFor(cellSize).cellSize = cellSize; 38 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 39 allocatorFor(cellSize).setCellSize(cellSize); 40 allocatorFor(cellSize).setHeap(heap); 41 allocatorFor(cellSize).setMarkedSpace(this); 42 } 40 43 41 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) 42 sizeClassFor(cellSize).cellSize = cellSize; 44 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 45 allocatorFor(cellSize).setCellSize(cellSize); 46 allocatorFor(cellSize).setHeap(heap); 47 allocatorFor(cellSize).setMarkedSpace(this); 48 } 43 49 } 44 50 45 void MarkedSpace::addBlock(SizeClass& sizeClass, MarkedBlock* block) 46 { 47 ASSERT(!sizeClass.currentBlock); 48 ASSERT(!sizeClass.firstFreeCell); 49 50 sizeClass.blockList.append(block); 51 sizeClass.currentBlock = block; 52 sizeClass.firstFreeCell = block->sweep(MarkedBlock::SweepToFreeList); 53 } 54 55 void MarkedSpace::removeBlock(MarkedBlock* block) 56 { 57 SizeClass& sizeClass = sizeClassFor(block->cellSize()); 58 if (sizeClass.currentBlock == block) 59 sizeClass.currentBlock = 0; 60 sizeClass.blockList.remove(block); 61 } 62 63 void MarkedSpace::resetAllocator() 51 void MarkedSpace::resetAllocators() 64 52 { 65 53 m_waterMark = 0; … … 67 55 68 56 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) 69 sizeClassFor(cellSize).resetAllocator();57 allocatorFor(cellSize).reset(); 70 58 71 59 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) 72 sizeClassFor(cellSize).resetAllocator();60 allocatorFor(cellSize).reset(); 73 61 } 74 62 … … 76 64 { 77 65 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) 78 sizeClassFor(cellSize).zapFreeList();66 allocatorFor(cellSize).zapFreeList(); 79 67 80 68 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) 81 sizeClassFor(cellSize).zapFreeList();69 allocatorFor(cellSize).zapFreeList(); 82 70 } 83 71 84 inline void* MarkedSpace::tryAllocateHelper(MarkedSpace::SizeClass& sizeClass)85 {86 MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;87 if (!firstFreeCell) {88 for (MarkedBlock*& block = sizeClass.currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {89 firstFreeCell = block->sweep(MarkedBlock::SweepToFreeList);90 if (firstFreeCell)91 break;92 m_nurseryWaterMark += block->capacity() - block->size();93 m_waterMark += block->capacity();94 block->didConsumeFreeList();95 }96 97 if (!firstFreeCell)98 return 0;99 }100 101 ASSERT(firstFreeCell);102 sizeClass.firstFreeCell = firstFreeCell->next;103 return firstFreeCell;104 }105 106 inline void* MarkedSpace::tryAllocate(MarkedSpace::SizeClass& sizeClass)107 {108 m_heap->m_operationInProgress = Allocation;109 void* result = tryAllocateHelper(sizeClass);110 m_heap->m_operationInProgress = NoOperation;111 return result;112 }113 114 void* MarkedSpace::allocateSlowCase(MarkedSpace::SizeClass& sizeClass)115 {116 #if COLLECT_ON_EVERY_ALLOCATION117 m_heap->collectAllGarbage();118 ASSERT(m_heap->m_operationInProgress == NoOperation);119 #endif120 121 void* result = tryAllocate(sizeClass);122 123 if (LIKELY(result != 0))124 return result;125 126 AllocationEffort allocationEffort;127 128 if ((129 #if ENABLE(GGC)130 nurseryWaterMark() < m_heap->m_minBytesPerCycle131 #else132 m_heap->waterMark() < m_heap->highWaterMark()133 #endif134 ) || !m_heap->m_isSafeToCollect)135 allocationEffort = AllocationMustSucceed;136 else137 allocationEffort = AllocationCanFail;138 139 MarkedBlock* block = allocateBlock(sizeClass.cellSize, allocationEffort);140 if (block) {141 addBlock(sizeClass, block);142 void* result = tryAllocate(sizeClass);143 ASSERT(result);144 return result;145 }146 147 m_heap->collect(Heap::DoNotSweep);148 149 result = tryAllocate(sizeClass);150 151 if (result)152 return result;153 154 ASSERT(m_heap->waterMark() < m_heap->highWaterMark());155 156 addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));157 158 result = tryAllocate(sizeClass);159 ASSERT(result);160 return result;161 }162 163 MarkedBlock* MarkedSpace::allocateBlock(size_t cellSize, AllocationEffort allocationEffort)164 {165 MarkedBlock* block;166 167 {168 MutexLocker locker(m_heap->m_freeBlockLock);169 if (m_heap->m_numberOfFreeBlocks) {170 block = static_cast<MarkedBlock*>(m_heap->m_freeBlocks.removeHead());171 ASSERT(block);172 m_heap->m_numberOfFreeBlocks--;173 } else174 block = 0;175 }176 if (block)177 block = MarkedBlock::recycle(block, m_heap, cellSize);178 else if (allocationEffort == AllocationCanFail)179 return 0;180 else181 block = MarkedBlock::create(m_heap, cellSize);182 183 m_blocks.add(block);184 185 return block;186 }187 72 188 73 void MarkedSpace::freeBlocks(MarkedBlock* head) … … 223 108 return; 224 109 225 m_markedSpace-> removeBlock(block);110 m_markedSpace->allocatorFor(block->cellSize()).removeBlock(block); 226 111 m_empties.append(block); 227 112 } -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r106433 r106676 24 24 25 25 #include "MachineStackMarker.h" 26 #include "MarkedAllocator.h" 26 27 #include "MarkedBlock.h" 27 28 #include "MarkedBlockSet.h" … … 49 50 static const size_t maxCellSize = 2048; 50 51 51 struct SizeClass {52 SizeClass();53 void resetAllocator();54 void zapFreeList();55 56 MarkedBlock::FreeCell* firstFreeCell;57 MarkedBlock* currentBlock;58 DoublyLinkedList<HeapBlock> blockList;59 size_t cellSize;60 };61 62 52 MarkedSpace(Heap*); 63 53 64 SizeClass& sizeClassFor(size_t);54 MarkedAllocator& allocatorFor(size_t); 65 55 void* allocate(size_t); 66 void* allocate(SizeClass&);67 56 68 void resetAllocator ();57 void resetAllocators(); 69 58 70 void addBlock(SizeClass&, MarkedBlock*);71 void removeBlock(MarkedBlock*);72 59 MarkedBlockSet& blocks() { return m_blocks; } 73 60 … … 86 73 void shrink(); 87 74 void freeBlocks(MarkedBlock* head); 75 void didAddBlock(MarkedBlock*); 76 void didConsumeFreeList(MarkedBlock*); 88 77 89 78 private: 90 JS_EXPORT_PRIVATE void* allocateSlowCase(SizeClass&);91 void* tryAllocateHelper(MarkedSpace::SizeClass&);92 void* tryAllocate(MarkedSpace::SizeClass&);93 MarkedBlock* allocateBlock(size_t, AllocationEffort);94 95 79 // [ 32... 256 ] 96 80 static const size_t preciseStep = MarkedBlock::atomSize; … … 103 87 static const size_t impreciseCount = impreciseCutoff / impreciseStep; 104 88 105 FixedArray< SizeClass, preciseCount> m_preciseSizeClasses;106 FixedArray< SizeClass, impreciseCount> m_impreciseSizeClasses;89 FixedArray<MarkedAllocator, preciseCount> m_preciseSizeClasses; 90 FixedArray<MarkedAllocator, impreciseCount> m_impreciseSizeClasses; 107 91 size_t m_waterMark; 108 92 size_t m_nurseryWaterMark; … … 137 121 } 138 122 139 inline Marked Space::SizeClass& MarkedSpace::sizeClassFor(size_t bytes)123 inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes) 140 124 { 141 125 ASSERT(bytes && bytes <= maxCellSize); … … 147 131 inline void* MarkedSpace::allocate(size_t bytes) 148 132 { 149 SizeClass& sizeClass = sizeClassFor(bytes); 150 return allocate(sizeClass); 151 } 152 153 inline void* MarkedSpace::allocate(SizeClass& sizeClass) 154 { 155 // This is a light-weight fast path to cover the most common case. 156 MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell; 157 if (UNLIKELY(!firstFreeCell)) 158 return allocateSlowCase(sizeClass); 159 160 sizeClass.firstFreeCell = firstFreeCell->next; 161 return firstFreeCell; 133 return allocatorFor(bytes).allocate(); 162 134 } 163 135 … … 165 137 { 166 138 for (size_t i = 0; i < preciseCount; ++i) { 167 SizeClass& sizeClass = m_preciseSizeClasses[i]; 168 HeapBlock* next; 169 for (HeapBlock* block = sizeClass.blockList.head(); block; block = next) { 170 next = block->next(); 171 functor(static_cast<MarkedBlock*>(block)); 172 } 139 m_preciseSizeClasses[i].forEachBlock(functor); 173 140 } 174 141 175 142 for (size_t i = 0; i < impreciseCount; ++i) { 176 SizeClass& sizeClass = m_impreciseSizeClasses[i]; 177 HeapBlock* next; 178 for (HeapBlock* block = sizeClass.blockList.head(); block; block = next) { 179 next = block->next(); 180 functor(static_cast<MarkedBlock*>(block)); 181 } 143 m_impreciseSizeClasses[i].forEachBlock(functor); 182 144 } 183 145 … … 191 153 } 192 154 193 inline MarkedSpace::SizeClass::SizeClass() 194 : firstFreeCell(0) 195 , currentBlock(0) 196 , cellSize(0) 155 inline void MarkedSpace::didAddBlock(MarkedBlock* block) 197 156 { 157 m_blocks.add(block); 198 158 } 199 159 200 inline void MarkedSpace:: SizeClass::resetAllocator()160 inline void MarkedSpace::didConsumeFreeList(MarkedBlock* block) 201 161 { 202 currentBlock = static_cast<MarkedBlock*>(blockList.head()); 203 } 204 205 inline void MarkedSpace::SizeClass::zapFreeList() 206 { 207 if (!currentBlock) { 208 ASSERT(!firstFreeCell); 209 return; 210 } 211 212 currentBlock->zapFreeList(firstFreeCell); 213 firstFreeCell = 0; 162 m_nurseryWaterMark += block->capacity() - block->size(); 163 m_waterMark += block->capacity(); 214 164 } 215 165
Note:
See TracChangeset
for help on using the changeset viewer.