diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/heap/MarkStack.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/heap/MarkStack.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 123 |
1 files changed, 111 insertions, 12 deletions
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index 318183a80..688de42e3 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2011 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,14 +25,90 @@ #include "config.h" #include "MarkStack.h" - -#include "JSCInlines.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 { -MarkStackArray::MarkStackArray() - : GCSegmentedArray<const JSCell*>() +COMPILE_ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize, blockSizeMatch); + +MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator) + : m_blockAllocator(blockAllocator) + , m_top(0) + , m_numberOfSegments(0) +{ + m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>())); + m_numberOfSegments++; +} + +MarkStackArray::~MarkStackArray() +{ + ASSERT(m_numberOfSegments == 1); + ASSERT(m_segments.size() == 1); + m_blockAllocator.deallocate(MarkStackSegment::destroy(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); + + MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()); + m_numberOfSegments++; + +#if !ASSERT_DISABLED + nextSegment->m_top = 0; +#endif + + m_segments.push(nextSegment); + setTopForEmptySegment(); + validatePrevious(); +} + +bool MarkStackArray::refill() { + validatePrevious(); + if (top()) + return true; + m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead())); + ASSERT(m_numberOfSegments > 1); + m_numberOfSegments--; + setTopForFullSegment(); + validatePrevious(); + return true; } void MarkStackArray::donateSomeCellsTo(MarkStackArray& other) @@ -57,11 +133,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. - GCArraySegment<const JSCell*>* myHead = m_segments.removeHead(); - GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead(); + MarkStackSegment* myHead = m_segments.removeHead(); + MarkStackSegment* otherHead = other.m_segments.removeHead(); while (segmentsToDonate--) { - GCArraySegment<const JSCell*>* current = m_segments.removeHead(); + MarkStackSegment* current = m_segments.removeHead(); ASSERT(current); ASSERT(m_numberOfSegments > 1); other.m_segments.push(current); @@ -89,8 +165,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. - GCArraySegment<const JSCell*>* otherHead = other.m_segments.removeHead(); - GCArraySegment<const JSCell*>* myHead = m_segments.removeHead(); + MarkStackSegment* otherHead = other.m_segments.removeHead(); + MarkStackSegment* myHead = m_segments.removeHead(); ASSERT(other.m_segments.head()->m_top == s_segmentCapacity); @@ -107,10 +183,33 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread return; } - // Steal ceil(other.size() / idleThreadCount) things. - size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount; + size_t numberOfCellsToSteal = (other.size() + idleThreadCount - 1) / idleThreadCount; // Round up to steal 1 / 1. 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 |