diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/MarkStack.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 146 |
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 |