Changeset 134080 in webkit for trunk/Source/JavaScriptCore/heap/MarkStack.cpp
- Timestamp:
- Nov 9, 2012, 9:58:19 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r133995 r134080 46 46 namespace JSC { 47 47 48 MarkStackSegmentAllocator::MarkStackSegmentAllocator() 49 : m_nextFreeSegment(0) 50 { 51 m_lock.Init(); 52 } 53 54 MarkStackSegmentAllocator::~MarkStackSegmentAllocator() 55 { 56 shrinkReserve(); 57 } 58 59 MarkStackSegment* MarkStackSegmentAllocator::allocate() 60 { 61 { 62 SpinLockHolder locker(&m_lock); 63 if (m_nextFreeSegment) { 64 MarkStackSegment* result = m_nextFreeSegment; 65 m_nextFreeSegment = result->m_previous; 66 return result; 67 } 68 } 69 70 return static_cast<MarkStackSegment*>(OSAllocator::reserveAndCommit(Options::gcMarkStackSegmentSize())); 71 } 72 73 void MarkStackSegmentAllocator::release(MarkStackSegment* segment) 74 { 75 SpinLockHolder locker(&m_lock); 76 segment->m_previous = m_nextFreeSegment; 77 m_nextFreeSegment = segment; 78 } 79 80 void MarkStackSegmentAllocator::shrinkReserve() 81 { 82 MarkStackSegment* segments; 83 { 84 SpinLockHolder locker(&m_lock); 85 segments = m_nextFreeSegment; 86 m_nextFreeSegment = 0; 87 } 88 while (segments) { 89 MarkStackSegment* toFree = segments; 90 segments = segments->m_previous; 91 OSAllocator::decommitAndRelease(toFree, Options::gcMarkStackSegmentSize()); 92 } 93 } 94 95 MarkStackArray::MarkStackArray(MarkStackSegmentAllocator& allocator) 96 : m_allocator(allocator) 48 MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator) 49 : m_blockAllocator(blockAllocator) 97 50 , m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize())) 98 51 , m_top(0) 99 , m_numberOf PreviousSegments(0)52 , m_numberOfSegments(0) 100 53 { 101 m_topSegment = m_allocator.allocate(); 102 #if !ASSERT_DISABLED 103 m_topSegment->m_top = 0; 104 #endif 105 m_topSegment->m_previous = 0; 54 ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize); 55 m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>())); 56 m_numberOfSegments++; 106 57 } 107 58 108 59 MarkStackArray::~MarkStackArray() 109 60 { 110 ASSERT( !m_topSegment->m_previous);111 m_ allocator.release(m_topSegment);61 ASSERT(m_numberOfSegments == 1 && m_segments.size() == 1); 62 m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead())); 112 63 } 113 64 114 65 void MarkStackArray::expand() 115 66 { 116 ASSERT(m_ topSegment->m_top == m_segmentCapacity);67 ASSERT(m_segments.head()->m_top == m_segmentCapacity); 117 68 118 m_numberOfPreviousSegments++; 69 MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()); 70 m_numberOfSegments++; 119 71 120 MarkStackSegment* nextSegment = m_allocator.allocate();121 72 #if !ASSERT_DISABLED 122 73 nextSegment->m_top = 0; 123 74 #endif 124 nextSegment->m_previous = m_topSegment; 125 m_ topSegment = nextSegment;75 76 m_segments.push(nextSegment); 126 77 setTopForEmptySegment(); 127 78 validatePrevious(); … … 133 84 if (top()) 134 85 return true; 135 MarkStackSegment* toFree = m_topSegment; 136 MarkStackSegment* previous = m_topSegment->m_previous; 137 if (!previous) 138 return false; 139 ASSERT(m_numberOfPreviousSegments); 140 m_numberOfPreviousSegments--; 141 m_topSegment = previous; 142 m_allocator.release(toFree); 86 m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead())); 87 ASSERT(m_numberOfSegments > 1); 88 m_numberOfSegments--; 143 89 setTopForFullSegment(); 144 90 validatePrevious(); … … 154 100 ASSERT(m_segmentCapacity == other.m_segmentCapacity); 155 101 156 size_t segmentsToDonate = (m_numberOfPreviousSegments + 2 - 1) / 2; // Round up to donate 1 / 1 previoussegments.102 size_t segmentsToDonate = m_numberOfSegments / 2; // If we only have one segment (our head) we don't donate any segments. 157 103 158 104 if (!segmentsToDonate) { … … 168 114 other.validatePrevious(); 169 115 170 MarkStackSegment* previous = m_topSegment->m_previous; 116 // Remove our head and the head of the other list before we start moving segments around. 117 // We'll add them back on once we're done donating. 118 MarkStackSegment* myHead = m_segments.removeHead(); 119 MarkStackSegment* otherHead = other.m_segments.removeHead(); 120 171 121 while (segmentsToDonate--) { 172 ASSERT(previous); 173 ASSERT(m_numberOfPreviousSegments); 122 MarkStackSegment* current = m_segments.removeHead(); 123 ASSERT(current); 124 ASSERT(m_numberOfSegments > 1); 125 other.m_segments.push(current); 126 m_numberOfSegments--; 127 other.m_numberOfSegments++; 128 } 174 129 175 MarkStackSegment* current = previous; 176 previous = current->m_previous; 177 178 current->m_previous = other.m_topSegment->m_previous; 179 other.m_topSegment->m_previous = current; 180 181 m_numberOfPreviousSegments--; 182 other.m_numberOfPreviousSegments++; 183 } 184 m_topSegment->m_previous = previous; 130 // Put the original heads back in their places. 131 m_segments.push(myHead); 132 other.m_segments.push(otherHead); 185 133 186 134 validatePrevious(); … … 199 147 200 148 // If other has an entire segment, steal it and return. 201 if (other.m_ topSegment->m_previous) {202 ASSERT(other.m_topSegment->m_previous->m_top == m_segmentCapacity);203 204 // First remove a segment from other.205 MarkStackSegment* current = other.m_topSegment->m_previous; 206 other.m_topSegment->m_previous = current->m_previous;207 other.m_numberOfPreviousSegments--; 208 209 ASSERT(!!other.m_numberOfPreviousSegments == !!other.m_topSegment->m_previous); 210 211 // Now add it to this.212 current->m_previous = m_topSegment->m_previous;213 m_ topSegment->m_previous = current;214 m_numberOfPreviousSegments++;215 149 if (other.m_numberOfSegments > 1) { 150 // Move the heads of the lists aside. We'll push them back on after. 151 MarkStackSegment* otherHead = other.m_segments.removeHead(); 152 MarkStackSegment* myHead = m_segments.removeHead(); 153 154 ASSERT(other.m_segments.head()->m_top == m_segmentCapacity); 155 156 m_segments.push(other.m_segments.removeHead()); 157 158 m_numberOfSegments++; 159 other.m_numberOfSegments--; 160 161 m_segments.push(myHead); 162 other.m_segments.push(otherHead); 163 216 164 validatePrevious(); 217 165 other.validatePrevious();
Note:
See TracChangeset
for help on using the changeset viewer.