25e32ea2c8967c790822a948e58c0d9321b2e596
[WebKit-https.git] / Source / JavaScriptCore / heap / SlotVisitor.h
1 /*
2  * Copyright (C) 2011, 2012, 2013 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 "CopyToken.h"
30 #include "HandleTypes.h"
31 #include "MarkStack.h"
32 #include "OpaqueRootSet.h"
33
34 #include <wtf/HashSet.h>
35 #include <wtf/text/StringHash.h>
36
37 namespace JSC {
38
39 class ConservativeRoots;
40 class GCThreadSharedData;
41 class Heap;
42 template<typename T> class JITWriteBarrier;
43 class UnconditionalFinalizer;
44 template<typename T> class Weak;
45 class WeakReferenceHarvester;
46 template<typename T> class WriteBarrierBase;
47
48 class SlotVisitor {
49     WTF_MAKE_NONCOPYABLE(SlotVisitor);
50     friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
51
52 public:
53     SlotVisitor(GCThreadSharedData&);
54     ~SlotVisitor();
55
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
63     void append(ConservativeRoots&);
64     
65     template<typename T> void append(JITWriteBarrier<T>*);
66     template<typename T> void append(WriteBarrierBase<T>*);
67     template<typename Iterator> void append(Iterator begin , Iterator end);
68     void appendValues(WriteBarrierBase<Unknown>*, size_t count);
69     
70     template<typename T>
71     void appendUnbarrieredPointer(T**);
72     void appendUnbarrieredValue(JSValue*);
73     template<typename T>
74     void appendUnbarrieredWeak(Weak<T>*);
75     template<typename T>
76     void appendUnbarrieredReadOnlyPointer(T*);
77     void appendUnbarrieredReadOnlyValue(JSValue);
78     void unconditionallyAppend(JSCell*);
79     
80     void addOpaqueRoot(void*);
81     bool containsOpaqueRoot(void*) const;
82     TriState containsOpaqueRootTriState(void*) const;
83     int opaqueRootCount();
84
85     GCThreadSharedData& sharedData() const { return m_shared; }
86     bool isEmpty() { return m_stack.isEmpty(); }
87
88     void didStartMarking();
89     void reset();
90     void clearMarkStack();
91
92     size_t bytesVisited() const { return m_bytesVisited; }
93     size_t bytesCopied() const { return m_bytesCopied; }
94     size_t visitCount() const { return m_visitCount; }
95
96     void donate();
97     void drain();
98     void donateAndDrain();
99     
100     enum SharedDrainMode { SlaveDrain, MasterDrain };
101     void drainFromShared(SharedDrainMode);
102
103     void harvestWeakReferences();
104     void finalizeUnconditionalFinalizers();
105
106     void copyLater(JSCell*, CopyToken, void*, size_t);
107     
108     void reportExtraMemoryUsage(JSCell* owner, size_t);
109     
110     void addWeakReferenceHarvester(WeakReferenceHarvester*);
111     void addUnconditionalFinalizer(UnconditionalFinalizer*);
112
113     inline void resetChildCount() { m_logChildCount = 0; }
114     inline unsigned childCount() { return m_logChildCount; }
115     inline void incrementChildCount() { m_logChildCount++; }
116
117     void dump(PrintStream&) const;
118
119 private:
120     friend class ParallelModeEnabler;
121     
122     JS_EXPORT_PRIVATE static void validate(JSCell*);
123
124     void append(JSValue*);
125     void append(JSValue*, size_t count);
126     void append(JSCell**);
127     
128     void internalAppend(void* from, JSCell*);
129     void internalAppend(void* from, JSValue);
130     void internalAppend(void* from, JSValue*);
131     
132     JS_EXPORT_PRIVATE void mergeOpaqueRoots();
133     void mergeOpaqueRootsIfNecessary();
134     void mergeOpaqueRootsIfProfitable();
135     
136     void donateKnownParallel();
137
138     MarkStackArray m_stack;
139     OpaqueRootSet m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
140     
141     size_t m_bytesVisited;
142     size_t m_bytesCopied;
143     size_t m_visitCount;
144     bool m_isInParallelMode;
145     
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
152     unsigned m_logChildCount;
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()
171     {
172         ASSERT(m_stack.m_isInParallelMode);
173         m_stack.m_isInParallelMode = false;
174     }
175     
176 private:
177     SlotVisitor& m_stack;
178 };
179
180 } // namespace JSC
181
182 #endif // SlotVisitor_h