Backed out changeset 4191b252db9b (bug 1886734) for causing build bustages @netwerk...
[gecko.git] / js / src / gc / GC.h
blob7f603b066f049d5e4d52b34df703c416d67b5bad
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/. */
7 /*
8 * JS engine garbage collector API.
9 */
11 #ifndef gc_GC_h
12 #define gc_GC_h
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/TraceKind.h"
21 class JSTracer;
23 namespace JS {
24 class RealmOptions;
27 namespace js {
29 class Nursery;
31 namespace gc {
33 class Arena;
34 class TenuredChunk;
36 } /* namespace gc */
38 // Define name, key and writability for the GC parameters.
39 #define FOR_EACH_GC_PARAM(_) \
40 _("maxBytes", JSGC_MAX_BYTES, true) \
41 _("minNurseryBytes", JSGC_MIN_NURSERY_BYTES, true) \
42 _("maxNurseryBytes", JSGC_MAX_NURSERY_BYTES, true) \
43 _("gcBytes", JSGC_BYTES, false) \
44 _("nurseryBytes", JSGC_NURSERY_BYTES, false) \
45 _("gcNumber", JSGC_NUMBER, false) \
46 _("majorGCNumber", JSGC_MAJOR_GC_NUMBER, false) \
47 _("minorGCNumber", JSGC_MINOR_GC_NUMBER, false) \
48 _("incrementalGCEnabled", JSGC_INCREMENTAL_GC_ENABLED, true) \
49 _("perZoneGCEnabled", JSGC_PER_ZONE_GC_ENABLED, true) \
50 _("unusedChunks", JSGC_UNUSED_CHUNKS, false) \
51 _("totalChunks", JSGC_TOTAL_CHUNKS, false) \
52 _("sliceTimeBudgetMS", JSGC_SLICE_TIME_BUDGET_MS, true) \
53 _("highFrequencyTimeLimit", JSGC_HIGH_FREQUENCY_TIME_LIMIT, true) \
54 _("smallHeapSizeMax", JSGC_SMALL_HEAP_SIZE_MAX, true) \
55 _("largeHeapSizeMin", JSGC_LARGE_HEAP_SIZE_MIN, true) \
56 _("highFrequencySmallHeapGrowth", JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH, \
57 true) \
58 _("highFrequencyLargeHeapGrowth", JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH, \
59 true) \
60 _("lowFrequencyHeapGrowth", JSGC_LOW_FREQUENCY_HEAP_GROWTH, true) \
61 _("balancedHeapLimitsEnabled", JSGC_BALANCED_HEAP_LIMITS_ENABLED, true) \
62 _("heapGrowthFactor", JSGC_HEAP_GROWTH_FACTOR, true) \
63 _("allocationThreshold", JSGC_ALLOCATION_THRESHOLD, true) \
64 _("smallHeapIncrementalLimit", JSGC_SMALL_HEAP_INCREMENTAL_LIMIT, true) \
65 _("largeHeapIncrementalLimit", JSGC_LARGE_HEAP_INCREMENTAL_LIMIT, true) \
66 _("minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT, true) \
67 _("maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT, true) \
68 _("compactingEnabled", JSGC_COMPACTING_ENABLED, true) \
69 _("parallelMarkingEnabled", JSGC_PARALLEL_MARKING_ENABLED, true) \
70 _("parallelMarkingThresholdMB", JSGC_PARALLEL_MARKING_THRESHOLD_MB, true) \
71 _("minLastDitchGCPeriod", JSGC_MIN_LAST_DITCH_GC_PERIOD, true) \
72 _("nurseryEagerCollectionThresholdKB", \
73 JSGC_NURSERY_EAGER_COLLECTION_THRESHOLD_KB, true) \
74 _("nurseryEagerCollectionThresholdPercent", \
75 JSGC_NURSERY_EAGER_COLLECTION_THRESHOLD_PERCENT, true) \
76 _("nurseryEagerCollectionTimeoutMS", \
77 JSGC_NURSERY_EAGER_COLLECTION_TIMEOUT_MS, true) \
78 _("zoneAllocDelayKB", JSGC_ZONE_ALLOC_DELAY_KB, true) \
79 _("mallocThresholdBase", JSGC_MALLOC_THRESHOLD_BASE, true) \
80 _("urgentThreshold", JSGC_URGENT_THRESHOLD_MB, true) \
81 _("chunkBytes", JSGC_CHUNK_BYTES, false) \
82 _("helperThreadRatio", JSGC_HELPER_THREAD_RATIO, true) \
83 _("maxHelperThreads", JSGC_MAX_HELPER_THREADS, true) \
84 _("helperThreadCount", JSGC_HELPER_THREAD_COUNT, false) \
85 _("markingThreadCount", JSGC_MARKING_THREAD_COUNT, true) \
86 _("systemPageSizeKB", JSGC_SYSTEM_PAGE_SIZE_KB, false) \
87 _("semispaceNurseryEnabled", JSGC_SEMISPACE_NURSERY_ENABLED, true)
89 // Get the key and writability give a GC parameter name.
90 extern bool GetGCParameterInfo(const char* name, JSGCParamKey* keyOut,
91 bool* writableOut);
93 extern void TraceRuntime(JSTracer* trc);
95 // Trace roots but don't evict the nursery first; used from DumpHeap.
96 extern void TraceRuntimeWithoutEviction(JSTracer* trc);
98 extern void ReleaseAllJITCode(JS::GCContext* gcx);
100 extern void PrepareForDebugGC(JSRuntime* rt);
102 /* Functions for managing cross compartment gray pointers. */
104 extern void NotifyGCNukeWrapper(JSContext* cx, JSObject* wrapper);
106 extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b);
108 extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned removedFlags);
110 using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::TenuredChunk*,
111 const JS::AutoRequireNoGC&);
112 using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*,
113 const JS::AutoRequireNoGC&);
114 using IterateArenaCallback = void (*)(JSRuntime*, void*, gc::Arena*,
115 JS::TraceKind, size_t,
116 const JS::AutoRequireNoGC&);
117 using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t,
118 const JS::AutoRequireNoGC&);
121 * This function calls |zoneCallback| on every zone, |realmCallback| on
122 * every realm, |arenaCallback| on every in-use arena, and |cellCallback|
123 * on every in-use cell in the GC heap.
125 * Note that no read barrier is triggered on the cells passed to cellCallback,
126 * so no these pointers must not escape the callback.
128 extern void IterateHeapUnbarriered(JSContext* cx, void* data,
129 IterateZoneCallback zoneCallback,
130 JS::IterateRealmCallback realmCallback,
131 IterateArenaCallback arenaCallback,
132 IterateCellCallback cellCallback);
135 * This function is like IterateHeapUnbarriered, but does it for a single zone.
137 extern void IterateHeapUnbarrieredForZone(
138 JSContext* cx, JS::Zone* zone, void* data, IterateZoneCallback zoneCallback,
139 JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback,
140 IterateCellCallback cellCallback);
143 * Invoke chunkCallback on every in-use chunk.
145 extern void IterateChunks(JSContext* cx, void* data,
146 IterateChunkCallback chunkCallback);
148 using IterateScriptCallback = void (*)(JSRuntime*, void*, BaseScript*,
149 const JS::AutoRequireNoGC&);
152 * Invoke scriptCallback on every in-use script for the given realm or for all
153 * realms if it is null. The scripts may or may not have bytecode.
155 extern void IterateScripts(JSContext* cx, JS::Realm* realm, void* data,
156 IterateScriptCallback scriptCallback);
158 JS::Realm* NewRealm(JSContext* cx, JSPrincipals* principals,
159 const JS::RealmOptions& options);
161 namespace gc {
163 void FinishGC(JSContext* cx, JS::GCReason = JS::GCReason::FINISH_GC);
165 void WaitForBackgroundTasks(JSContext* cx);
167 enum VerifierType { PreBarrierVerifier };
169 #ifdef JS_GC_ZEAL
171 extern const char ZealModeHelpText[];
173 /* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
174 void VerifyBarriers(JSRuntime* rt, VerifierType type);
176 void MaybeVerifyBarriers(JSContext* cx, bool always = false);
178 void DumpArenaInfo();
180 #else
182 static inline void VerifyBarriers(JSRuntime* rt, VerifierType type) {}
184 static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}
186 #endif
189 * Instances of this class prevent GC from happening while they are live. If an
190 * allocation causes a heap threshold to be exceeded, no GC will be performed
191 * and the allocation will succeed. Allocation may still fail for other reasons.
193 * Use of this class is highly discouraged, since without GC system memory can
194 * become exhausted and this can cause crashes at places where we can't handle
195 * allocation failure.
197 * Use of this is permissible in situations where it would be impossible (or at
198 * least very difficult) to tolerate GC and where only a fixed number of objects
199 * are allocated, such as:
201 * - error reporting
202 * - JIT bailout handling
203 * - brain transplants (JSObject::swap)
204 * - debugging utilities not exposed to the browser
206 * This works by updating the |JSContext::suppressGC| counter which is checked
207 * at the start of GC.
209 class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC
210 : public JS::AutoRequireNoGC {
211 int32_t& suppressGC_;
213 public:
214 explicit AutoSuppressGC(JSContext* cx);
216 ~AutoSuppressGC() { suppressGC_--; }
219 const char* StateName(State state);
221 } /* namespace gc */
223 /* Use this to avoid assertions when manipulating the wrapper map. */
224 class MOZ_RAII AutoDisableProxyCheck {
225 public:
226 #ifdef DEBUG
227 AutoDisableProxyCheck();
228 ~AutoDisableProxyCheck();
229 #else
230 AutoDisableProxyCheck() {}
231 #endif
234 struct MOZ_RAII AutoDisableCompactingGC {
235 explicit AutoDisableCompactingGC(JSContext* cx);
236 ~AutoDisableCompactingGC();
238 private:
239 JSContext* cx;
243 * Dynamically select the GC heap to allocate into for a graph of GC things.
245 * Initially |heap()| will return Heap::Default to select nursery allocation,
246 * but when a specified number of nursery collections have been triggered it
247 * switches to returning Heap::Tenured.
249 class MOZ_RAII AutoSelectGCHeap {
250 public:
251 explicit AutoSelectGCHeap(JSContext* cx,
252 size_t allowedNurseryCollections = 0);
253 ~AutoSelectGCHeap();
255 gc::Heap heap() const { return heap_; }
256 operator gc::Heap() const { return heap_; }
258 void onNurseryCollectionEnd();
260 private:
261 static void NurseryCollectionCallback(JSContext* cx,
262 JS::GCNurseryProgress progress,
263 JS::GCReason reason, void* data);
265 JSContext* cx_;
266 size_t allowedNurseryCollections_;
267 gc::Heap heap_ = gc::Heap::Default;
270 } /* namespace js */
272 #endif /* gc_GC_h */