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 JSTracer;
23 
24 namespace js {
25 
26 class FatInlineAtom;
27 class NormalAtom;
28 
29 class Nursery;
30 
31 namespace gc {
32 
33 class Arena;
34 class TenuredChunk;
35 struct Cell;
36 
37 } /* namespace gc */
38 
39 extern void TraceRuntime(JSTracer* trc);
40 
41 // Trace roots but don't evict the nursery first; used from DumpHeap.
42 extern void TraceRuntimeWithoutEviction(JSTracer* trc);
43 
44 extern void ReleaseAllJITCode(JSFreeOp* op);
45 
46 extern void PrepareForDebugGC(JSRuntime* rt);
47 
48 /* Functions for managing cross compartment gray pointers. */
49 
50 extern void NotifyGCNukeWrapper(JSContext* cx, JSObject* wrapper);
51 
52 extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b);
53 
54 extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned preResult);
55 
56 using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::TenuredChunk*,
57                                       const JS::AutoRequireNoGC&);
58 using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*,
59                                      const JS::AutoRequireNoGC&);
60 using IterateArenaCallback = void (*)(JSRuntime*, void*, gc::Arena*,
61                                       JS::TraceKind, size_t,
62                                       const JS::AutoRequireNoGC&);
63 using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t,
64                                      const JS::AutoRequireNoGC&);
65 
66 /*
67  * This function calls |zoneCallback| on every zone, |realmCallback| on
68  * every realm, |arenaCallback| on every in-use arena, and |cellCallback|
69  * on every in-use cell in the GC heap.
70  *
71  * Note that no read barrier is triggered on the cells passed to cellCallback,
72  * so no these pointers must not escape the callback.
73  */
74 extern void IterateHeapUnbarriered(JSContext* cx, void* data,
75                                    IterateZoneCallback zoneCallback,
76                                    JS::IterateRealmCallback realmCallback,
77                                    IterateArenaCallback arenaCallback,
78                                    IterateCellCallback cellCallback);
79 
80 /*
81  * This function is like IterateHeapUnbarriered, but does it for a single zone.
82  */
83 extern void IterateHeapUnbarrieredForZone(
84     JSContext* cx, JS::Zone* zone, void* data, IterateZoneCallback zoneCallback,
85     JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback,
86     IterateCellCallback cellCallback);
87 
88 /*
89  * Invoke chunkCallback on every in-use chunk.
90  */
91 extern void IterateChunks(JSContext* cx, void* data,
92                           IterateChunkCallback chunkCallback);
93 
94 using IterateScriptCallback = void (*)(JSRuntime*, void*, BaseScript*,
95                                        const JS::AutoRequireNoGC&);
96 
97 /*
98  * Invoke scriptCallback on every in-use script for the given realm or for all
99  * realms if it is null. The scripts may or may not have bytecode.
100  */
101 extern void IterateScripts(JSContext* cx, JS::Realm* realm, void* data,
102                            IterateScriptCallback scriptCallback);
103 
104 JS::Realm* NewRealm(JSContext* cx, JSPrincipals* principals,
105                     const JS::RealmOptions& options);
106 
107 namespace gc {
108 
109 void FinishGC(JSContext* cx, JS::GCReason = JS::GCReason::FINISH_GC);
110 
111 void WaitForBackgroundTasks(JSContext* cx);
112 
113 enum VerifierType { PreBarrierVerifier };
114 
115 #ifdef JS_GC_ZEAL
116 
117 extern const char ZealModeHelpText[];
118 
119 /* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
120 void VerifyBarriers(JSRuntime* rt, VerifierType type);
121 
122 void MaybeVerifyBarriers(JSContext* cx, bool always = false);
123 
124 void DumpArenaInfo();
125 
126 #else
127 
VerifyBarriers(JSRuntime * rt,VerifierType type)128 static inline void VerifyBarriers(JSRuntime* rt, VerifierType type) {}
129 
130 static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}
131 
132 #endif
133 
134 /*
135  * Instances of this class prevent GC from happening while they are live. If an
136  * allocation causes a heap threshold to be exceeded, no GC will be performed
137  * and the allocation will succeed. Allocation may still fail for other reasons.
138  *
139  * Use of this class is highly discouraged, since without GC system memory can
140  * become exhausted and this can cause crashes at places where we can't handle
141  * allocation failure.
142  *
143  * Use of this is permissible in situations where it would be impossible (or at
144  * least very difficult) to tolerate GC and where only a fixed number of objects
145  * are allocated, such as:
146  *
147  *  - error reporting
148  *  - JIT bailout handling
149  *  - brain transplants (JSObject::swap)
150  *  - debugging utilities not exposed to the browser
151  *
152  * This works by updating the |JSContext::suppressGC| counter which is checked
153  * at the start of GC.
154  */
155 class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC {
156   int32_t& suppressGC_;
157 
158  public:
159   explicit AutoSuppressGC(JSContext* cx);
160 
~AutoSuppressGC()161   ~AutoSuppressGC() { suppressGC_--; }
162 };
163 
164 const char* StateName(State state);
165 
166 } /* namespace gc */
167 
168 /* Use this to avoid assertions when manipulating the wrapper map. */
169 class MOZ_RAII AutoDisableProxyCheck {
170  public:
171 #ifdef DEBUG
172   AutoDisableProxyCheck();
173   ~AutoDisableProxyCheck();
174 #else
175   AutoDisableProxyCheck() {}
176 #endif
177 };
178 
179 struct MOZ_RAII AutoDisableCompactingGC {
180   explicit AutoDisableCompactingGC(JSContext* cx);
181   ~AutoDisableCompactingGC();
182 
183  private:
184   JSContext* cx;
185 };
186 
187 } /* namespace js */
188 
189 #endif /* gc_GC_h */
190