1/*
2 * Copyright (C) 2011-2013, 2015 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 "CellState.h"
30#include "CopyToken.h"
31#include "HandleTypes.h"
32#include "MarkStack.h"
33#include "OpaqueRootSet.h"
34
35namespace JSC {
36
37class ConservativeRoots;
38class GCThreadSharedData;
39class Heap;
40template<typename T> class JITWriteBarrier;
41class UnconditionalFinalizer;
42template<typename T> class Weak;
43class WeakReferenceHarvester;
44template<typename T> class WriteBarrierBase;
45
46class SlotVisitor {
47 WTF_MAKE_NONCOPYABLE(SlotVisitor);
48 WTF_MAKE_FAST_ALLOCATED;
49
50 friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly.
51 friend class Heap;
52
53public:
54 SlotVisitor(Heap&);
55 ~SlotVisitor();
56
57 MarkStackArray& markStack() { return m_stack; }
58 const MarkStackArray& markStack() const { return m_stack; }
59
60 VM& vm();
61 const VM& vm() const;
62 Heap* heap() const;
63
64 void append(ConservativeRoots&);
65
66 template<typename T> void append(JITWriteBarrier<T>*);
67 template<typename T> void append(WriteBarrierBase<T>*);
68 template<typename Iterator> void append(Iterator begin , Iterator end);
69 void appendValues(WriteBarrierBase<Unknown>*, size_t count);
70
71 template<typename T>
72 void appendUnbarrieredPointer(T**);
73 void appendUnbarrieredValue(JSValue*);
74 template<typename T>
75 void appendUnbarrieredWeak(Weak<T>*);
76 template<typename T>
77 void appendUnbarrieredReadOnlyPointer(T*);
78 void appendUnbarrieredReadOnlyValue(JSValue);
79
80 JS_EXPORT_PRIVATE void addOpaqueRoot(void*);
81 JS_EXPORT_PRIVATE bool containsOpaqueRoot(void*) const;
82 TriState containsOpaqueRootTriState(void*) const;
83 int opaqueRootCount();
84
85 bool isEmpty() { return m_stack.isEmpty(); }
86
87 void didStartMarking();
88 void reset();
89 void clearMarkStack();
90
91 size_t bytesVisited() const { return m_bytesVisited; }
92 size_t bytesCopied() const { return m_bytesCopied; }
93 size_t visitCount() const { return m_visitCount; }
94
95 void donate();
96 void drain();
97 void donateAndDrain();
98
99 enum SharedDrainMode { SlaveDrain, MasterDrain };
100 void drainFromShared(SharedDrainMode);
101
102 void harvestWeakReferences();
103 void finalizeUnconditionalFinalizers();
104
105 void copyLater(JSCell*, CopyToken, void*, size_t);
106
107 void reportExtraMemoryVisited(size_t);
108
109 void addWeakReferenceHarvester(WeakReferenceHarvester*);
110 void addUnconditionalFinalizer(UnconditionalFinalizer*);
111
112 void dump(PrintStream&) const;
113
114private:
115 friend class ParallelModeEnabler;
116
117 JS_EXPORT_PRIVATE void append(JSValue); // This is private to encourage clients to use WriteBarrier<T>.
118
119 JS_EXPORT_PRIVATE void setMarkedAndAppendToMarkStack(JSCell*);
120 void appendToMarkStack(JSCell*);
121
122 JS_EXPORT_PRIVATE void mergeOpaqueRoots();
123 void mergeOpaqueRootsIfNecessary();
124 void mergeOpaqueRootsIfProfitable();
125
126 void visitChildren(const JSCell*);
127
128 void donateKnownParallel();
129
130 MarkStackArray m_stack;
131 OpaqueRootSet m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
132
133 size_t m_bytesVisited;
134 size_t m_bytesCopied;
135 size_t m_visitCount;
136 bool m_isInParallelMode;
137
138 Heap& m_heap;
139
140 CellState m_currentObjectCellStateBeforeVisiting { CellState::NewWhite };
141
142public:
143#if !ASSERT_DISABLED
144 bool m_isCheckingForDefaultMarkViolation;
145 bool m_isDraining;
146#endif
147};
148
149class ParallelModeEnabler {
150public:
151 ParallelModeEnabler(SlotVisitor& stack)
152 : m_stack(stack)
153 {
154 ASSERT(!m_stack.m_isInParallelMode);
155 m_stack.m_isInParallelMode = true;
156 }
157
158 ~ParallelModeEnabler()
159 {
160 ASSERT(m_stack.m_isInParallelMode);
161 m_stack.m_isInParallelMode = false;
162 }
163
164private:
165 SlotVisitor& m_stack;
166};
167
168} // namespace JSC
169
170#endif // SlotVisitor_h
171