summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/MarkStack.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/heap/MarkStack.cpp
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-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.cpp154
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;