1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /*
8 * JS engine garbage collector API.
9 */
10
11 #ifndef gc_GC_h
12 #define gc_GC_h
13
14 #include "gc/AllocKind.h"
15 #include "gc/GCEnum.h"
16 #include "js/GCAPI.h"
17 #include "js/HeapAPI.h"
18 #include "js/RealmIterators.h"
19 #include "js/RealmOptions.h"
20 #include "js/TraceKind.h"
21
22 class JSExternalString;
23 class JSFatInlineString;
24 class JSTracer;
25
26 namespace js {
27
28 class FatInlineAtom;
29 class NormalAtom;
30
31 class Nursery;
32
33 namespace gc {
34
35 class Arena;
36 class TenuredChunk;
37 struct Cell;
38
39 /*
40 * Map from C++ type to alloc kind for non-object types. JSObject does not have
41 * a 1:1 mapping, so must use Arena::thingSize.
42 *
43 * The AllocKind is available as MapTypeToFinalizeKind<SomeType>::kind.
44 */
45 template <typename T>
46 struct MapTypeToFinalizeKind {};
47 #define EXPAND_MAPTYPETOFINALIZEKIND(allocKind, traceKind, type, sizedType, \
48 bgFinal, nursery, compact) \
49 template <> \
50 struct MapTypeToFinalizeKind<type> { \
51 static const AllocKind kind = AllocKind::allocKind; \
52 };
53 FOR_EACH_NONOBJECT_ALLOCKIND(EXPAND_MAPTYPETOFINALIZEKIND)
54 #undef EXPAND_MAPTYPETOFINALIZEKIND
55
56 } /* namespace gc */
57
58 extern void TraceRuntime(JSTracer* trc);
59
60 // Trace roots but don't evict the nursery first; used from DumpHeap.
61 extern void TraceRuntimeWithoutEviction(JSTracer* trc);
62
63 extern void ReleaseAllJITCode(JSFreeOp* op);
64
65 extern void PrepareForDebugGC(JSRuntime* rt);
66
67 /* Functions for managing cross compartment gray pointers. */
68
69 extern void NotifyGCNukeWrapper(JSObject* o);
70
71 extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b);
72
73 extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned preResult);
74
75 using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::TenuredChunk*,
76 const JS::AutoRequireNoGC&);
77 using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*,
78 const JS::AutoRequireNoGC&);
79 using IterateArenaCallback = void (*)(JSRuntime*, void*, gc::Arena*,
80 JS::TraceKind, size_t,
81 const JS::AutoRequireNoGC&);
82 using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t,
83 const JS::AutoRequireNoGC&);
84
85 /*
86 * This function calls |zoneCallback| on every zone, |realmCallback| on
87 * every realm, |arenaCallback| on every in-use arena, and |cellCallback|
88 * on every in-use cell in the GC heap.
89 *
90 * Note that no read barrier is triggered on the cells passed to cellCallback,
91 * so no these pointers must not escape the callback.
92 */
93 extern void IterateHeapUnbarriered(JSContext* cx, void* data,
94 IterateZoneCallback zoneCallback,
95 JS::IterateRealmCallback realmCallback,
96 IterateArenaCallback arenaCallback,
97 IterateCellCallback cellCallback);
98
99 /*
100 * This function is like IterateHeapUnbarriered, but does it for a single zone.
101 */
102 extern void IterateHeapUnbarrieredForZone(
103 JSContext* cx, JS::Zone* zone, void* data, IterateZoneCallback zoneCallback,
104 JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback,
105 IterateCellCallback cellCallback);
106
107 /*
108 * Invoke chunkCallback on every in-use chunk.
109 */
110 extern void IterateChunks(JSContext* cx, void* data,
111 IterateChunkCallback chunkCallback);
112
113 using IterateScriptCallback = void (*)(JSRuntime*, void*, BaseScript*,
114 const JS::AutoRequireNoGC&);
115
116 /*
117 * Invoke scriptCallback on every in-use script for the given realm or for all
118 * realms if it is null. The scripts may or may not have bytecode.
119 */
120 extern void IterateScripts(JSContext* cx, JS::Realm* realm, void* data,
121 IterateScriptCallback scriptCallback);
122
123 JS::Realm* NewRealm(JSContext* cx, JSPrincipals* principals,
124 const JS::RealmOptions& options);
125
126 namespace gc {
127
128 void FinishGC(JSContext* cx, JS::GCReason = JS::GCReason::FINISH_GC);
129
130 void WaitForBackgroundTasks(JSContext* cx);
131
132 /*
133 * Merge all contents of source into target. This can only be used if source is
134 * the only realm in its zone.
135 */
136 void MergeRealms(JS::Realm* source, JS::Realm* target);
137
138 void CollectSelfHostingZone(JSContext* cx);
139
140 enum VerifierType { PreBarrierVerifier };
141
142 #ifdef JS_GC_ZEAL
143
144 extern const char ZealModeHelpText[];
145
146 /* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
147 void VerifyBarriers(JSRuntime* rt, VerifierType type);
148
149 void MaybeVerifyBarriers(JSContext* cx, bool always = false);
150
151 void DumpArenaInfo();
152
153 #else
154
VerifyBarriers(JSRuntime * rt,VerifierType type)155 static inline void VerifyBarriers(JSRuntime* rt, VerifierType type) {}
156
157 static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}
158
159 #endif
160
161 /*
162 * Instances of this class prevent GC from happening while they are live. If an
163 * allocation causes a heap threshold to be exceeded, no GC will be performed
164 * and the allocation will succeed. Allocation may still fail for other reasons.
165 *
166 * Use of this class is highly discouraged, since without GC system memory can
167 * become exhausted and this can cause crashes at places where we can't handle
168 * allocation failure.
169 *
170 * Use of this is permissible in situations where it would be impossible (or at
171 * least very difficult) to tolerate GC and where only a fixed number of objects
172 * are allocated, such as:
173 *
174 * - error reporting
175 * - JIT bailout handling
176 * - brain transplants (JSObject::swap)
177 * - debugging utilities not exposed to the browser
178 *
179 * This works by updating the |JSContext::suppressGC| counter which is checked
180 * at the start of GC.
181 */
182 class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC {
183 int32_t& suppressGC_;
184
185 public:
186 explicit AutoSuppressGC(JSContext* cx);
187
~AutoSuppressGC()188 ~AutoSuppressGC() { suppressGC_--; }
189 };
190
191 const char* StateName(State state);
192
193 } /* namespace gc */
194
195 /* Use this to avoid assertions when manipulating the wrapper map. */
196 class MOZ_RAII AutoDisableProxyCheck {
197 public:
198 #ifdef DEBUG
199 AutoDisableProxyCheck();
200 ~AutoDisableProxyCheck();
201 #else
202 AutoDisableProxyCheck() {}
203 #endif
204 };
205
206 struct MOZ_RAII AutoDisableCompactingGC {
207 explicit AutoDisableCompactingGC(JSContext* cx);
208 ~AutoDisableCompactingGC();
209
210 private:
211 JSContext* cx;
212 };
213
214 } /* namespace js */
215
216 #endif /* gc_GC_h */
217