diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:09:45 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:10:13 +0100 |
commit | 470286ecfe79d59df14944e5b5d34630fc739391 (patch) | |
tree | 43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/heap/MarkStack.cpp | |
parent | 23037105e948c2065da5a937d3a2396b0ff45c1e (diff) | |
download | qtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz |
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/heap/MarkStack.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 154 |
1 files changed, 51 insertions, 103 deletions
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index 582439fd2..755a0ad50 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -25,18 +25,18 @@ #include "config.h" #include "MarkStack.h" -#include "MarkStackInlineMethods.h" +#include "MarkStackInlines.h" -#include "CopiedSpace.h" -#include "CopiedSpaceInlineMethods.h" #include "ConservativeRoots.h" +#include "CopiedSpace.h" +#include "CopiedSpaceInlines.h" #include "Heap.h" #include "Options.h" #include "JSArray.h" #include "JSCell.h" #include "JSObject.h" -#include "SlotVisitorInlineMethods.h" +#include "SlotVisitorInlines.h" #include "Structure.h" #include "WriteBarrier.h" #include <wtf/Atomics.h> @@ -45,84 +45,35 @@ namespace JSC { -MarkStackSegmentAllocator::MarkStackSegmentAllocator() - : m_nextFreeSegment(0) -{ - m_lock.Init(); -} - -MarkStackSegmentAllocator::~MarkStackSegmentAllocator() -{ - shrinkReserve(); -} - -MarkStackSegment* MarkStackSegmentAllocator::allocate() -{ - { - SpinLockHolder locker(&m_lock); - if (m_nextFreeSegment) { - MarkStackSegment* result = m_nextFreeSegment; - m_nextFreeSegment = result->m_previous; - return result; - } - } - - return static_cast<MarkStackSegment*>(OSAllocator::reserveAndCommit(Options::gcMarkStackSegmentSize())); -} - -void MarkStackSegmentAllocator::release(MarkStackSegment* segment) -{ - SpinLockHolder locker(&m_lock); - segment->m_previous = m_nextFreeSegment; - m_nextFreeSegment = segment; -} - -void MarkStackSegmentAllocator::shrinkReserve() -{ - MarkStackSegment* segments; - { - SpinLockHolder locker(&m_lock); - segments = m_nextFreeSegment; - m_nextFreeSegment = 0; - } - while (segments) { - MarkStackSegment* toFree = segments; - segments = segments->m_previous; - OSAllocator::decommitAndRelease(toFree, Options::gcMarkStackSegmentSize()); - } -} - -MarkStackArray::MarkStackArray(MarkStackSegmentAllocator& allocator) - : m_allocator(allocator) +MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator) + : m_blockAllocator(blockAllocator) , m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize())) , m_top(0) - , m_numberOfPreviousSegments(0) + , m_numberOfSegments(0) { - m_topSegment = m_allocator.allocate(); -#if !ASSERT_DISABLED - m_topSegment->m_top = 0; -#endif - m_topSegment->m_previous = 0; + ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize); + m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>())); + m_numberOfSegments++; } MarkStackArray::~MarkStackArray() { - ASSERT(!m_topSegment->m_previous); - m_allocator.release(m_topSegment); + ASSERT(m_numberOfSegments == 1 && m_segments.size() == 1); + m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead())); } void MarkStackArray::expand() { - ASSERT(m_topSegment->m_top == m_segmentCapacity); + ASSERT(m_segments.head()->m_top == m_segmentCapacity); - m_numberOfPreviousSegments++; + MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()); + m_numberOfSegments++; - MarkStackSegment* nextSegment = m_allocator.allocate(); #if !ASSERT_DISABLED nextSegment->m_top = 0; #endif - nextSegment->m_previous = m_topSegment; - m_topSegment = nextSegment; + + m_segments.push(nextSegment); setTopForEmptySegment(); validatePrevious(); } @@ -132,14 +83,9 @@ bool MarkStackArray::refill() validatePrevious(); if (top()) return true; - MarkStackSegment* toFree = m_topSegment; - MarkStackSegment* previous = m_topSegment->m_previous; - if (!previous) - return false; - ASSERT(m_numberOfPreviousSegments); - m_numberOfPreviousSegments--; - m_topSegment = previous; - m_allocator.release(toFree); + m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead())); + ASSERT(m_numberOfSegments > 1); + m_numberOfSegments--; setTopForFullSegment(); validatePrevious(); return true; @@ -153,7 +99,7 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other) ASSERT(m_segmentCapacity == other.m_segmentCapacity); - size_t segmentsToDonate = (m_numberOfPreviousSegments + 2 - 1) / 2; // Round up to donate 1 / 1 previous segments. + size_t segmentsToDonate = m_numberOfSegments / 2; // If we only have one segment (our head) we don't donate any segments. if (!segmentsToDonate) { size_t cellsToDonate = m_top / 2; // Round down to donate 0 / 1 cells. @@ -167,21 +113,23 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other) validatePrevious(); other.validatePrevious(); - MarkStackSegment* previous = m_topSegment->m_previous; + // Remove our head and the head of the other list before we start moving segments around. + // We'll add them back on once we're done donating. + MarkStackSegment* myHead = m_segments.removeHead(); + MarkStackSegment* otherHead = other.m_segments.removeHead(); + while (segmentsToDonate--) { - ASSERT(previous); - ASSERT(m_numberOfPreviousSegments); - - MarkStackSegment* current = previous; - previous = current->m_previous; - - current->m_previous = other.m_topSegment->m_previous; - other.m_topSegment->m_previous = current; - - m_numberOfPreviousSegments--; - other.m_numberOfPreviousSegments++; + MarkStackSegment* current = m_segments.removeHead(); + ASSERT(current); + ASSERT(m_numberOfSegments > 1); + other.m_segments.push(current); + m_numberOfSegments--; + other.m_numberOfSegments++; } - m_topSegment->m_previous = previous; + + // Put the original heads back in their places. + m_segments.push(myHead); + other.m_segments.push(otherHead); validatePrevious(); other.validatePrevious(); @@ -198,21 +146,21 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread other.validatePrevious(); // If other has an entire segment, steal it and return. - if (other.m_topSegment->m_previous) { - ASSERT(other.m_topSegment->m_previous->m_top == m_segmentCapacity); - - // First remove a segment from other. - MarkStackSegment* current = other.m_topSegment->m_previous; - other.m_topSegment->m_previous = current->m_previous; - other.m_numberOfPreviousSegments--; - - ASSERT(!!other.m_numberOfPreviousSegments == !!other.m_topSegment->m_previous); - - // Now add it to this. - current->m_previous = m_topSegment->m_previous; - m_topSegment->m_previous = current; - m_numberOfPreviousSegments++; - + if (other.m_numberOfSegments > 1) { + // Move the heads of the lists aside. We'll push them back on after. + MarkStackSegment* otherHead = other.m_segments.removeHead(); + MarkStackSegment* myHead = m_segments.removeHead(); + + ASSERT(other.m_segments.head()->m_top == m_segmentCapacity); + + m_segments.push(other.m_segments.removeHead()); + + m_numberOfSegments++; + other.m_numberOfSegments--; + + m_segments.push(myHead); + other.m_segments.push(otherHead); + validatePrevious(); other.validatePrevious(); return; |