]>
Commit | Line | Data |
---|---|---|
14957cd0 | 1 | /* |
81345200 | 2 | * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. |
14957cd0 A |
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 | ||
6fe7ccc8 A |
26 | #ifndef SlotVisitor_h |
27 | #define SlotVisitor_h | |
14957cd0 | 28 | |
81345200 | 29 | #include "CopyToken.h" |
93a37866 | 30 | #include "HandleTypes.h" |
81345200 A |
31 | #include "MarkStack.h" |
32 | #include "OpaqueRootSet.h" | |
93a37866 | 33 | |
81345200 | 34 | #include <wtf/HashSet.h> |
93a37866 | 35 | #include <wtf/text/StringHash.h> |
14957cd0 | 36 | |
6fe7ccc8 A |
37 | namespace JSC { |
38 | ||
93a37866 A |
39 | class ConservativeRoots; |
40 | class GCThreadSharedData; | |
6fe7ccc8 | 41 | class Heap; |
81345200 A |
42 | template<typename T> class JITWriteBarrier; |
43 | class UnconditionalFinalizer; | |
93a37866 | 44 | template<typename T> class Weak; |
81345200 | 45 | class WeakReferenceHarvester; |
93a37866 | 46 | template<typename T> class WriteBarrierBase; |
93a37866 A |
47 | |
48 | class SlotVisitor { | |
49 | WTF_MAKE_NONCOPYABLE(SlotVisitor); | |
50 | friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly. | |
6fe7ccc8 | 51 | |
14957cd0 | 52 | public: |
93a37866 A |
53 | SlotVisitor(GCThreadSharedData&); |
54 | ~SlotVisitor(); | |
6fe7ccc8 | 55 | |
81345200 A |
56 | MarkStackArray& markStack() { return m_stack; } |
57 | const MarkStackArray& markStack() const { return m_stack; } | |
58 | ||
59 | VM& vm(); | |
60 | const VM& vm() const; | |
61 | Heap* heap() const; | |
62 | ||
93a37866 | 63 | void append(ConservativeRoots&); |
6fe7ccc8 | 64 | |
93a37866 A |
65 | template<typename T> void append(JITWriteBarrier<T>*); |
66 | template<typename T> void append(WriteBarrierBase<T>*); | |
81345200 | 67 | template<typename Iterator> void append(Iterator begin , Iterator end); |
93a37866 | 68 | void appendValues(WriteBarrierBase<Unknown>*, size_t count); |
6fe7ccc8 | 69 | |
93a37866 A |
70 | template<typename T> |
71 | void appendUnbarrieredPointer(T**); | |
72 | void appendUnbarrieredValue(JSValue*); | |
73 | template<typename T> | |
74 | void appendUnbarrieredWeak(Weak<T>*); | |
81345200 A |
75 | template<typename T> |
76 | void appendUnbarrieredReadOnlyPointer(T*); | |
77 | void appendUnbarrieredReadOnlyValue(JSValue); | |
78 | void unconditionallyAppend(JSCell*); | |
93a37866 A |
79 | |
80 | void addOpaqueRoot(void*); | |
81345200 A |
81 | bool containsOpaqueRoot(void*) const; |
82 | TriState containsOpaqueRootTriState(void*) const; | |
93a37866 A |
83 | int opaqueRootCount(); |
84 | ||
81345200 | 85 | GCThreadSharedData& sharedData() const { return m_shared; } |
93a37866 A |
86 | bool isEmpty() { return m_stack.isEmpty(); } |
87 | ||
81345200 | 88 | void didStartMarking(); |
93a37866 | 89 | void reset(); |
81345200 | 90 | void clearMarkStack(); |
93a37866 | 91 | |
81345200 A |
92 | size_t bytesVisited() const { return m_bytesVisited; } |
93 | size_t bytesCopied() const { return m_bytesCopied; } | |
93a37866 A |
94 | size_t visitCount() const { return m_visitCount; } |
95 | ||
96 | void donate(); | |
97 | void drain(); | |
98 | void donateAndDrain(); | |
14957cd0 | 99 | |
6fe7ccc8 A |
100 | enum SharedDrainMode { SlaveDrain, MasterDrain }; |
101 | void drainFromShared(SharedDrainMode); | |
14957cd0 | 102 | |
6fe7ccc8 A |
103 | void harvestWeakReferences(); |
104 | void finalizeUnconditionalFinalizers(); | |
14957cd0 | 105 | |
81345200 A |
106 | void copyLater(JSCell*, CopyToken, void*, size_t); |
107 | ||
ed1e77d3 | 108 | void reportExtraMemoryVisited(JSCell* owner, size_t); |
93a37866 | 109 | |
93a37866 A |
110 | void addWeakReferenceHarvester(WeakReferenceHarvester*); |
111 | void addUnconditionalFinalizer(UnconditionalFinalizer*); | |
112 | ||
93a37866 A |
113 | inline void resetChildCount() { m_logChildCount = 0; } |
114 | inline unsigned childCount() { return m_logChildCount; } | |
115 | inline void incrementChildCount() { m_logChildCount++; } | |
81345200 A |
116 | |
117 | void dump(PrintStream&) const; | |
93a37866 | 118 | |
14957cd0 | 119 | private: |
93a37866 A |
120 | friend class ParallelModeEnabler; |
121 | ||
122 | JS_EXPORT_PRIVATE static void validate(JSCell*); | |
14957cd0 | 123 | |
93a37866 A |
124 | void append(JSValue*); |
125 | void append(JSValue*, size_t count); | |
126 | void append(JSCell**); | |
81345200 A |
127 | |
128 | void internalAppend(void* from, JSCell*); | |
129 | void internalAppend(void* from, JSValue); | |
130 | void internalAppend(void* from, JSValue*); | |
93a37866 A |
131 | |
132 | JS_EXPORT_PRIVATE void mergeOpaqueRoots(); | |
133 | void mergeOpaqueRootsIfNecessary(); | |
134 | void mergeOpaqueRootsIfProfitable(); | |
135 | ||
136 | void donateKnownParallel(); | |
137 | ||
138 | MarkStackArray m_stack; | |
81345200 | 139 | OpaqueRootSet m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector. |
93a37866 | 140 | |
81345200 A |
141 | size_t m_bytesVisited; |
142 | size_t m_bytesCopied; | |
93a37866 A |
143 | size_t m_visitCount; |
144 | bool m_isInParallelMode; | |
6fe7ccc8 | 145 | |
93a37866 A |
146 | GCThreadSharedData& m_shared; |
147 | ||
148 | bool m_shouldHashCons; // Local per-thread copy of shared flag for performance reasons | |
149 | typedef HashMap<StringImpl*, JSValue> UniqueStringMap; | |
150 | UniqueStringMap m_uniqueStrings; | |
151 | ||
93a37866 | 152 | unsigned m_logChildCount; |
93a37866 A |
153 | |
154 | public: | |
155 | #if !ASSERT_DISABLED | |
156 | bool m_isCheckingForDefaultMarkViolation; | |
157 | bool m_isDraining; | |
158 | #endif | |
159 | }; | |
160 | ||
161 | class ParallelModeEnabler { | |
162 | public: | |
163 | ParallelModeEnabler(SlotVisitor& stack) | |
164 | : m_stack(stack) | |
165 | { | |
166 | ASSERT(!m_stack.m_isInParallelMode); | |
167 | m_stack.m_isInParallelMode = true; | |
168 | } | |
169 | ||
170 | ~ParallelModeEnabler() | |
6fe7ccc8 | 171 | { |
93a37866 A |
172 | ASSERT(m_stack.m_isInParallelMode); |
173 | m_stack.m_isInParallelMode = false; | |
6fe7ccc8 A |
174 | } |
175 | ||
93a37866 A |
176 | private: |
177 | SlotVisitor& m_stack; | |
6fe7ccc8 | 178 | }; |
14957cd0 | 179 | |
6fe7ccc8 | 180 | } // namespace JSC |
14957cd0 | 181 | |
6fe7ccc8 | 182 | #endif // SlotVisitor_h |