1/* 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef SlotVisitor_h 27#define SlotVisitor_h 28 29#include "HandleTypes.h" 30#include "MarkStackInlines.h" 31 32#include <wtf/text/StringHash.h> 33 34namespace JSC { 35 36class ConservativeRoots; 37class GCThreadSharedData; 38class Heap; 39template<typename T> class Weak; 40template<typename T> class WriteBarrierBase; 41template<typename T> class JITWriteBarrier; 42 43class SlotVisitor { 44 WTF_MAKE_NONCOPYABLE(SlotVisitor); 45 friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly. 46 47public: 48 SlotVisitor(GCThreadSharedData&); 49 ~SlotVisitor(); 50 51 void append(ConservativeRoots&); 52 53 template<typename T> void append(JITWriteBarrier<T>*); 54 template<typename T> void append(WriteBarrierBase<T>*); 55 void appendValues(WriteBarrierBase<Unknown>*, size_t count); 56 57 template<typename T> 58 void appendUnbarrieredPointer(T**); 59 void appendUnbarrieredValue(JSValue*); 60 template<typename T> 61 void appendUnbarrieredWeak(Weak<T>*); 62 63 void addOpaqueRoot(void*); 64 bool containsOpaqueRoot(void*); 65 TriState containsOpaqueRootTriState(void*); 66 int opaqueRootCount(); 67 68 GCThreadSharedData& sharedData() { return m_shared; } 69 bool isEmpty() { return m_stack.isEmpty(); } 70 71 void setup(); 72 void reset(); 73 74 size_t visitCount() const { return m_visitCount; } 75 76 void donate(); 77 void drain(); 78 void donateAndDrain(); 79 80 enum SharedDrainMode { SlaveDrain, MasterDrain }; 81 void drainFromShared(SharedDrainMode); 82 83 void harvestWeakReferences(); 84 void finalizeUnconditionalFinalizers(); 85 86 void copyLater(JSCell*, void*, size_t); 87 88#if ENABLE(SIMPLE_HEAP_PROFILING) 89 VTableSpectrum m_visitedTypeCounts; 90#endif 91 92 void addWeakReferenceHarvester(WeakReferenceHarvester*); 93 void addUnconditionalFinalizer(UnconditionalFinalizer*); 94 95#if ENABLE(OBJECT_MARK_LOGGING) 96 inline void resetChildCount() { m_logChildCount = 0; } 97 inline unsigned childCount() { return m_logChildCount; } 98 inline void incrementChildCount() { m_logChildCount++; } 99#endif 100 101private: 102 friend class ParallelModeEnabler; 103 104 JS_EXPORT_PRIVATE static void validate(JSCell*); 105 106 void append(JSValue*); 107 void append(JSValue*, size_t count); 108 void append(JSCell**); 109 110 void internalAppend(JSCell*); 111 void internalAppend(JSValue); 112 void internalAppend(JSValue*); 113 114 JS_EXPORT_PRIVATE void mergeOpaqueRoots(); 115 void mergeOpaqueRootsIfNecessary(); 116 void mergeOpaqueRootsIfProfitable(); 117 118 void donateKnownParallel(); 119 120 MarkStackArray m_stack; 121 HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector. 122 123 size_t m_visitCount; 124 bool m_isInParallelMode; 125 126 GCThreadSharedData& m_shared; 127 128 bool m_shouldHashCons; // Local per-thread copy of shared flag for performance reasons 129 typedef HashMap<StringImpl*, JSValue> UniqueStringMap; 130 UniqueStringMap m_uniqueStrings; 131 132#if ENABLE(OBJECT_MARK_LOGGING) 133 unsigned m_logChildCount; 134#endif 135 136public: 137#if !ASSERT_DISABLED 138 bool m_isCheckingForDefaultMarkViolation; 139 bool m_isDraining; 140#endif 141}; 142 143class ParallelModeEnabler { 144public: 145 ParallelModeEnabler(SlotVisitor& stack) 146 : m_stack(stack) 147 { 148 ASSERT(!m_stack.m_isInParallelMode); 149 m_stack.m_isInParallelMode = true; 150 } 151 152 ~ParallelModeEnabler() 153 { 154 ASSERT(m_stack.m_isInParallelMode); 155 m_stack.m_isInParallelMode = false; 156 } 157 158private: 159 SlotVisitor& m_stack; 160}; 161 162} // namespace JSC 163 164#endif // SlotVisitor_h 165