diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-23 17:03:15 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-23 17:03:15 +0200 |
commit | a73d1c176f2f3e0458861de8590dc20321a501ae (patch) | |
tree | d897fc5974797c3cb300d7f5916f258df765401f /Source/JavaScriptCore/heap | |
parent | c311cf639cc1d6570d67b0a80a8ba04dc992a658 (diff) | |
download | qtwebkit-a73d1c176f2f3e0458861de8590dc20321a501ae.tar.gz |
Imported WebKit commit a5ae8a56a48e44ebfb9b81aaa5488affaffdb175 (http://svn.webkit.org/repository/webkit/trunk@126420)
New snapshot with OS X 10.6 build fix
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r-- | Source/JavaScriptCore/heap/GCThreadSharedData.cpp | 121 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/GCThreadSharedData.h | 84 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/Heap.h | 5 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/ListableHandler.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 88 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.h | 165 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStackInlineMethods.h | 130 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/SlotVisitor.h | 6 |
8 files changed, 360 insertions, 241 deletions
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp new file mode 100644 index 000000000..82c52d22e --- /dev/null +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp @@ -0,0 +1,121 @@ +/* + * 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GCThreadSharedData.h" + +#include "JSGlobalData.h" +#include "MarkStack.h" +#include "SlotVisitor.h" +#include <wtf/MainThread.h> + +namespace JSC { + +#if ENABLE(PARALLEL_GC) +void GCThreadSharedData::resetChildren() +{ + for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) + m_markingThreadsMarkStack[i]->reset(); +} + +size_t GCThreadSharedData::childVisitCount() +{ + unsigned long result = 0; + for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) + result += m_markingThreadsMarkStack[i]->visitCount(); + return result; +} + +void GCThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) +{ + WTF::registerGCThread(); + { + ParallelModeEnabler enabler(*slotVisitor); + slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); + } + delete slotVisitor; +} + +void GCThreadSharedData::markingThreadStartFunc(void* myVisitor) +{ + SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); + + slotVisitor->sharedData().markingThreadMain(slotVisitor); +} +#endif + +GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData) + : m_globalData(globalData) + , m_copiedSpace(&globalData->heap.m_storageSpace) + , m_shouldHashConst(false) + , m_sharedMarkStack(m_segmentAllocator) + , m_numberOfActiveParallelMarkers(0) + , m_parallelMarkersShouldExit(false) +{ +#if ENABLE(PARALLEL_GC) + for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { + SlotVisitor* slotVisitor = new SlotVisitor(*this); + m_markingThreadsMarkStack.append(slotVisitor); + m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); + ASSERT(m_markingThreads.last()); + } +#endif +} + +GCThreadSharedData::~GCThreadSharedData() +{ +#if ENABLE(PARALLEL_GC) + // Destroy our marking threads. + { + MutexLocker locker(m_markingLock); + m_parallelMarkersShouldExit = true; + m_markingCondition.broadcast(); + } + for (unsigned i = 0; i < m_markingThreads.size(); ++i) + waitForThreadCompletion(m_markingThreads[i]); +#endif +} + +void GCThreadSharedData::reset() +{ + ASSERT(!m_numberOfActiveParallelMarkers); + ASSERT(!m_parallelMarkersShouldExit); + ASSERT(m_sharedMarkStack.isEmpty()); + +#if ENABLE(PARALLEL_GC) + m_segmentAllocator.shrinkReserve(); + m_opaqueRoots.clear(); +#else + ASSERT(m_opaqueRoots.isEmpty()); +#endif + m_weakReferenceHarvesters.removeAll(); + + if (m_shouldHashConst) { + m_globalData->resetNewStringsSinceLastHashConst(); + m_shouldHashConst = false; + } +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.h b/Source/JavaScriptCore/heap/GCThreadSharedData.h new file mode 100644 index 000000000..8868b440c --- /dev/null +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.h @@ -0,0 +1,84 @@ +/* + * 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GCThreadSharedData_h +#define GCThreadSharedData_h + +#include "MarkStack.h" +#include <wtf/Vector.h> + +namespace JSC { + +class JSGlobalData; +class CopiedSpace; + +class GCThreadSharedData { +public: + GCThreadSharedData(JSGlobalData*); + ~GCThreadSharedData(); + + void reset(); + +#if ENABLE(PARALLEL_GC) + void resetChildren(); + size_t childVisitCount(); + size_t childDupStrings(); +#endif + +private: + friend class MarkStack; + friend class SlotVisitor; + +#if ENABLE(PARALLEL_GC) + void markingThreadMain(SlotVisitor*); + static void markingThreadStartFunc(void* heap); +#endif + + JSGlobalData* m_globalData; + CopiedSpace* m_copiedSpace; + + MarkStackSegmentAllocator m_segmentAllocator; + + bool m_shouldHashConst; + + Vector<ThreadIdentifier> m_markingThreads; + Vector<MarkStack*> m_markingThreadsMarkStack; + + Mutex m_markingLock; + ThreadCondition m_markingCondition; + MarkStackArray m_sharedMarkStack; + unsigned m_numberOfActiveParallelMarkers; + bool m_parallelMarkersShouldExit; + + Mutex m_opaqueRootsLock; + HashSet<void*> m_opaqueRoots; + + ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; + ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; +}; + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h index f3474f2ea..6f13afb72 100644 --- a/Source/JavaScriptCore/heap/Heap.h +++ b/Source/JavaScriptCore/heap/Heap.h @@ -24,6 +24,7 @@ #include "BlockAllocator.h" #include "DFGCodeBlocks.h" +#include "GCThreadSharedData.h" #include "HandleSet.h" #include "HandleStack.h" #include "JITStubRoutineSet.h" @@ -74,7 +75,7 @@ namespace JSC { WTF_MAKE_NONCOPYABLE(Heap); public: friend class JIT; - friend class MarkStackThreadSharedData; + friend class GCThreadSharedData; static Heap* heap(const JSValue); // 0 for immediate values static Heap* heap(const JSCell*); @@ -231,7 +232,7 @@ namespace JSC { MachineThreads m_machineThreads; - MarkStackThreadSharedData m_sharedData; + GCThreadSharedData m_sharedData; SlotVisitor m_slotVisitor; HandleSet m_handleSet; diff --git a/Source/JavaScriptCore/heap/ListableHandler.h b/Source/JavaScriptCore/heap/ListableHandler.h index 2cb03251f..16c34146c 100644 --- a/Source/JavaScriptCore/heap/ListableHandler.h +++ b/Source/JavaScriptCore/heap/ListableHandler.h @@ -52,7 +52,7 @@ protected: private: // Allow these classes to use ListableHandler::List. friend class MarkStack; - friend class MarkStackThreadSharedData; + friend class GCThreadSharedData; friend class SlotVisitor; class List { diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index 02a13077d..9d3062154 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "MarkStack.h" +#include "MarkStackInlineMethods.h" #include "CopiedSpace.h" #include "CopiedSpaceInlineMethods.h" @@ -223,89 +224,22 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread append(other.removeLast()); } -#if ENABLE(PARALLEL_GC) -void MarkStackThreadSharedData::resetChildren() -{ - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - m_markingThreadsMarkStack[i]->reset(); -} - -size_t MarkStackThreadSharedData::childVisitCount() -{ - unsigned long result = 0; - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - result += m_markingThreadsMarkStack[i]->visitCount(); - return result; -} - -void MarkStackThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) -{ - WTF::registerGCThread(); - { - ParallelModeEnabler enabler(*slotVisitor); - slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); - } - delete slotVisitor; -} - -void MarkStackThreadSharedData::markingThreadStartFunc(void* myVisitor) -{ - SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); - - slotVisitor->sharedData().markingThreadMain(slotVisitor); -} +MarkStack::MarkStack(GCThreadSharedData& shared) + : m_stack(shared.m_segmentAllocator) +#if !ASSERT_DISABLED + , m_isCheckingForDefaultMarkViolation(false) + , m_isDraining(false) #endif - -MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData) - : m_globalData(globalData) - , m_copiedSpace(&globalData->heap.m_storageSpace) + , m_visitCount(0) + , m_isInParallelMode(false) + , m_shared(shared) , m_shouldHashConst(false) - , m_sharedMarkStack(m_segmentAllocator) - , m_numberOfActiveParallelMarkers(0) - , m_parallelMarkersShouldExit(false) { -#if ENABLE(PARALLEL_GC) - for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { - SlotVisitor* slotVisitor = new SlotVisitor(*this); - m_markingThreadsMarkStack.append(slotVisitor); - m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); - ASSERT(m_markingThreads.last()); - } -#endif } -MarkStackThreadSharedData::~MarkStackThreadSharedData() +MarkStack::~MarkStack() { -#if ENABLE(PARALLEL_GC) - // Destroy our marking threads. - { - MutexLocker locker(m_markingLock); - m_parallelMarkersShouldExit = true; - m_markingCondition.broadcast(); - } - for (unsigned i = 0; i < m_markingThreads.size(); ++i) - waitForThreadCompletion(m_markingThreads[i]); -#endif -} - -void MarkStackThreadSharedData::reset() -{ - ASSERT(!m_numberOfActiveParallelMarkers); - ASSERT(!m_parallelMarkersShouldExit); - ASSERT(m_sharedMarkStack.isEmpty()); - -#if ENABLE(PARALLEL_GC) - m_segmentAllocator.shrinkReserve(); - m_opaqueRoots.clear(); -#else - ASSERT(m_opaqueRoots.isEmpty()); -#endif - m_weakReferenceHarvesters.removeAll(); - - if (m_shouldHashConst) { - m_globalData->resetNewStringsSinceLastHashConst(); - m_shouldHashConst = false; - } + ASSERT(m_stack.isEmpty()); } void MarkStack::setup() diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h index 467a5bf46..54ae1cb02 100644 --- a/Source/JavaScriptCore/heap/MarkStack.h +++ b/Source/JavaScriptCore/heap/MarkStack.h @@ -74,6 +74,7 @@ namespace JSC { class ConservativeRoots; class JSGlobalData; class MarkStack; + class GCThreadSharedData; class ParallelModeEnabler; class Register; class SlotVisitor; @@ -192,57 +193,12 @@ namespace JSC { #endif }; - class MarkStackThreadSharedData { - public: - MarkStackThreadSharedData(JSGlobalData*); - ~MarkStackThreadSharedData(); - - void reset(); - -#if ENABLE(PARALLEL_GC) - void resetChildren(); - size_t childVisitCount(); - size_t childDupStrings(); -#endif - - private: - friend class MarkStack; - friend class SlotVisitor; - -#if ENABLE(PARALLEL_GC) - void markingThreadMain(SlotVisitor*); - static void markingThreadStartFunc(void* heap); -#endif - - JSGlobalData* m_globalData; - CopiedSpace* m_copiedSpace; - - MarkStackSegmentAllocator m_segmentAllocator; - - bool m_shouldHashConst; - - Vector<ThreadIdentifier> m_markingThreads; - Vector<MarkStack*> m_markingThreadsMarkStack; - - Mutex m_markingLock; - ThreadCondition m_markingCondition; - MarkStackArray m_sharedMarkStack; - unsigned m_numberOfActiveParallelMarkers; - bool m_parallelMarkersShouldExit; - - Mutex m_opaqueRootsLock; - HashSet<void*> m_opaqueRoots; - - ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; - ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; - }; - class MarkStack { WTF_MAKE_NONCOPYABLE(MarkStack); friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly. public: - MarkStack(MarkStackThreadSharedData&); + MarkStack(GCThreadSharedData&); ~MarkStack(); void append(ConservativeRoots&); @@ -259,7 +215,7 @@ namespace JSC { bool containsOpaqueRoot(void*); int opaqueRootCount(); - MarkStackThreadSharedData& sharedData() { return m_shared; } + GCThreadSharedData& sharedData() { return m_shared; } bool isEmpty() { return m_stack.isEmpty(); } void setup(); @@ -271,15 +227,8 @@ namespace JSC { VTableSpectrum m_visitedTypeCounts; #endif - void addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester) - { - m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester); - } - - void addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer) - { - m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer); - } + void addWeakReferenceHarvester(WeakReferenceHarvester*); + void addUnconditionalFinalizer(UnconditionalFinalizer*); #if ENABLE(OBJECT_MARK_LOGGING) inline void resetChildCount() { m_logChildCount = 0; } @@ -328,7 +277,7 @@ namespace JSC { size_t m_visitCount; bool m_isInParallelMode; - MarkStackThreadSharedData& m_shared; + GCThreadSharedData& m_shared; bool m_shouldHashConst; // Local per-thread copy of shared flag for performance reasons typedef HashMap<StringImpl*, JSValue> UniqueStringMap; @@ -339,63 +288,6 @@ namespace JSC { #endif }; - inline MarkStack::MarkStack(MarkStackThreadSharedData& shared) - : m_stack(shared.m_segmentAllocator) -#if !ASSERT_DISABLED - , m_isCheckingForDefaultMarkViolation(false) - , m_isDraining(false) -#endif - , m_visitCount(0) - , m_isInParallelMode(false) - , m_shared(shared) - , m_shouldHashConst(false) - { - } - - inline MarkStack::~MarkStack() - { - ASSERT(m_stack.isEmpty()); - } - - inline void MarkStack::addOpaqueRoot(void* root) - { -#if ENABLE(PARALLEL_GC) - if (Options::numberOfGCMarkers() == 1) { - // Put directly into the shared HashSet. - m_shared.m_opaqueRoots.add(root); - return; - } - // Put into the local set, but merge with the shared one every once in - // a while to make sure that the local sets don't grow too large. - mergeOpaqueRootsIfProfitable(); - m_opaqueRoots.add(root); -#else - m_opaqueRoots.add(root); -#endif - } - - inline bool MarkStack::containsOpaqueRoot(void* root) - { - ASSERT(!m_isInParallelMode); -#if ENABLE(PARALLEL_GC) - ASSERT(m_opaqueRoots.isEmpty()); - return m_shared.m_opaqueRoots.contains(root); -#else - return m_opaqueRoots.contains(root); -#endif - } - - inline int MarkStack::opaqueRootCount() - { - ASSERT(!m_isInParallelMode); -#if ENABLE(PARALLEL_GC) - ASSERT(m_opaqueRoots.isEmpty()); - return m_shared.m_opaqueRoots.size(); -#else - return m_opaqueRoots.size(); -#endif - } - inline void MarkStackArray::append(const JSCell* cell) { if (m_top == m_segmentCapacity) @@ -429,51 +321,6 @@ namespace JSC { return m_top + m_segmentCapacity * m_numberOfPreviousSegments; } - ALWAYS_INLINE void MarkStack::append(JSValue* slot, size_t count) - { - for (size_t i = 0; i < count; ++i) { - JSValue& value = slot[i]; - if (!value) - continue; - internalAppend(value); - } - } - - template<typename T> - inline void MarkStack::appendUnbarrieredPointer(T** slot) - { - ASSERT(slot); - JSCell* cell = *slot; - if (cell) - internalAppend(cell); - } - - ALWAYS_INLINE void MarkStack::append(JSValue* slot) - { - ASSERT(slot); - internalAppend(*slot); - } - - ALWAYS_INLINE void MarkStack::appendUnbarrieredValue(JSValue* slot) - { - ASSERT(slot); - internalAppend(*slot); - } - - ALWAYS_INLINE void MarkStack::append(JSCell** slot) - { - ASSERT(slot); - internalAppend(*slot); - } - - ALWAYS_INLINE void MarkStack::internalAppend(JSValue value) - { - ASSERT(value); - if (!value.isCell()) - return; - internalAppend(value.asCell()); - } - class ParallelModeEnabler { public: ParallelModeEnabler(MarkStack& stack) diff --git a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h new file mode 100644 index 000000000..8b420d637 --- /dev/null +++ b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h @@ -0,0 +1,130 @@ +/* + * 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MarkStackInlineMethods_h +#define MarkStackInlineMethods_h + +#include "GCThreadSharedData.h" +#include "MarkStack.h" + +namespace JSC { + +ALWAYS_INLINE void MarkStack::append(JSValue* slot, size_t count) +{ + for (size_t i = 0; i < count; ++i) { + JSValue& value = slot[i]; + if (!value) + continue; + internalAppend(value); + } +} + +template<typename T> +inline void MarkStack::appendUnbarrieredPointer(T** slot) +{ + ASSERT(slot); + JSCell* cell = *slot; + if (cell) + internalAppend(cell); +} + +ALWAYS_INLINE void MarkStack::append(JSValue* slot) +{ + ASSERT(slot); + internalAppend(*slot); +} + +ALWAYS_INLINE void MarkStack::appendUnbarrieredValue(JSValue* slot) +{ + ASSERT(slot); + internalAppend(*slot); +} + +ALWAYS_INLINE void MarkStack::append(JSCell** slot) +{ + ASSERT(slot); + internalAppend(*slot); +} + +ALWAYS_INLINE void MarkStack::internalAppend(JSValue value) +{ + ASSERT(value); + if (!value.isCell()) + return; + internalAppend(value.asCell()); +} + +inline void MarkStack::addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester) +{ + m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester); +} + +inline void MarkStack::addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer) +{ + m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer); +} + +inline void MarkStack::addOpaqueRoot(void* root) +{ +#if ENABLE(PARALLEL_GC) + if (Options::numberOfGCMarkers() == 1) { + // Put directly into the shared HashSet. + m_shared.m_opaqueRoots.add(root); + return; + } + // Put into the local set, but merge with the shared one every once in + // a while to make sure that the local sets don't grow too large. + mergeOpaqueRootsIfProfitable(); + m_opaqueRoots.add(root); +#else + m_opaqueRoots.add(root); +#endif +} + +inline bool MarkStack::containsOpaqueRoot(void* root) +{ + ASSERT(!m_isInParallelMode); +#if ENABLE(PARALLEL_GC) + ASSERT(m_opaqueRoots.isEmpty()); + return m_shared.m_opaqueRoots.contains(root); +#else + return m_opaqueRoots.contains(root); +#endif +} + +inline int MarkStack::opaqueRootCount() +{ + ASSERT(!m_isInParallelMode); +#if ENABLE(PARALLEL_GC) + ASSERT(m_opaqueRoots.isEmpty()); + return m_shared.m_opaqueRoots.size(); +#else + return m_opaqueRoots.size(); +#endif +} + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h index a31e88c08..6364b23e4 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.h +++ b/Source/JavaScriptCore/heap/SlotVisitor.h @@ -28,15 +28,17 @@ #include "CopiedSpace.h" #include "MarkStack.h" +#include "MarkStackInlineMethods.h" namespace JSC { class Heap; +class GCThreadSharedData; class SlotVisitor : public MarkStack { friend class HeapRootVisitor; public: - SlotVisitor(MarkStackThreadSharedData&); + SlotVisitor(GCThreadSharedData&); void donate() { @@ -85,7 +87,7 @@ private: CopiedAllocator m_copiedAllocator; }; -inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared) +inline SlotVisitor::SlotVisitor(GCThreadSharedData& shared) : MarkStack(shared) { } |