summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/MarkStack.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/heap/MarkStack.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/heap/MarkStack.cpp')
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp146
1 files changed, 45 insertions, 101 deletions
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 688de42e3..871b30180 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,90 +25,57 @@
#include "config.h"
#include "MarkStack.h"
-#include "MarkStackInlines.h"
-
-#include "ConservativeRoots.h"
-#include "CopiedSpace.h"
-#include "CopiedSpaceInlines.h"
-#include "Heap.h"
-#include "JSArray.h"
-#include "JSCell.h"
-#include "JSObject.h"
-
-#include "SlotVisitorInlines.h"
-#include "Structure.h"
-#include "WriteBarrier.h"
-#include <wtf/Atomics.h>
-#include <wtf/DataLog.h>
-#include <wtf/MainThread.h>
-namespace JSC {
+#include "GCSegmentedArrayInlines.h"
+#include "JSCInlines.h"
-COMPILE_ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize, blockSizeMatch);
+namespace JSC {
-MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
- : m_blockAllocator(blockAllocator)
- , m_top(0)
- , m_numberOfSegments(0)
+MarkStackArray::MarkStackArray()
+ : GCSegmentedArray<const JSCell*>()
{
- m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()));
- m_numberOfSegments++;
}
-MarkStackArray::~MarkStackArray()
+void MarkStackArray::transferTo(MarkStackArray& other)
{
- ASSERT(m_numberOfSegments == 1);
- ASSERT(m_segments.size() == 1);
- m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
+ RELEASE_ASSERT(this != &other);
+
+ // Remove our head and the head of the other list.
+ GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
+ GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
m_numberOfSegments--;
- ASSERT(!m_numberOfSegments);
- ASSERT(!m_segments.size());
-}
-
-void MarkStackArray::clear()
-{
- if (!m_segments.head())
- return;
- MarkStackSegment* next;
- for (MarkStackSegment* current = m_segments.head(); current->next(); current = next) {
- next = current->next();
- m_segments.remove(current);
- m_blockAllocator.deallocate(MarkStackSegment::destroy(current));
- }
- m_top = 0;
- m_numberOfSegments = 1;
-#if !ASSERT_DISABLED
- m_segments.head()->m_top = 0;
-#endif
-}
-
-void MarkStackArray::expand()
-{
- ASSERT(m_segments.head()->m_top == s_segmentCapacity);
+ other.m_numberOfSegments--;
+
+ other.m_segments.append(m_segments);
- MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>());
+ other.m_numberOfSegments += m_numberOfSegments;
+ m_numberOfSegments = 0;
+
+ // Put the original heads back in their places.
+ m_segments.push(myHead);
+ other.m_segments.push(otherHead);
m_numberOfSegments++;
+ other.m_numberOfSegments++;
-#if !ASSERT_DISABLED
- nextSegment->m_top = 0;
-#endif
-
- m_segments.push(nextSegment);
- setTopForEmptySegment();
- validatePrevious();
+ while (!isEmpty()) {
+ refill();
+ while (canRemoveLast())
+ other.append(removeLast());
+ }
}
-bool MarkStackArray::refill()
+size_t MarkStackArray::transferTo(MarkStackArray& other, size_t limit)
{
- validatePrevious();
- if (top())
- return true;
- m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
- ASSERT(m_numberOfSegments > 1);
- m_numberOfSegments--;
- setTopForFullSegment();
- validatePrevious();
- return true;
+ size_t count = 0;
+ while (count < limit && !isEmpty()) {
+ refill();
+ while (count < limit && canRemoveLast()) {
+ other.append(removeLast());
+ count++;
+ }
+ }
+ RELEASE_ASSERT(count <= limit);
+ return count;
}
void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
@@ -133,11 +100,11 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
// 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();
+ GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
+ GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
while (segmentsToDonate--) {
- MarkStackSegment* current = m_segments.removeHead();
+ GCArraySegment<const JSCell*>* current = m_segments.removeHead();
ASSERT(current);
ASSERT(m_numberOfSegments > 1);
other.m_segments.push(current);
@@ -165,8 +132,8 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
// If other has an entire segment, steal it and return.
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();
+ GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead();
+ GCArraySegment<const JSCell*>* myHead = m_segments.removeHead();
ASSERT(other.m_segments.head()->m_top == s_segmentCapacity);
@@ -183,33 +150,10 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
return;
}
- size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount; // Round up to steal 1 / 1.
+ // Steal ceil(other.size() / idleThreadCount) things.
+ size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount;
while (numberOfCellsToSteal-- > 0 && other.canRemoveLast())
append(other.removeLast());
}
-void MarkStackArray::fillVector(Vector<const JSCell*>& vector)
-{
- ASSERT(vector.size() == size());
-
- MarkStackSegment* currentSegment = m_segments.head();
- if (!currentSegment)
- return;
-
- unsigned count = 0;
- for (unsigned i = 0; i < m_top; ++i) {
- ASSERT(currentSegment->data()[i]);
- vector[count++] = currentSegment->data()[i];
- }
-
- currentSegment = currentSegment->next();
- while (currentSegment) {
- for (unsigned i = 0; i < s_segmentCapacity; ++i) {
- ASSERT(currentSegment->data()[i]);
- vector[count++] = currentSegment->data()[i];
- }
- currentSegment = currentSegment->next();
- }
-}
-
} // namespace JSC