[SM91] Update to Spidermonkey 91.1.3 APIs
[0ad.git] / libraries / source / spidermonkey / include-win32-debug / js / GCAPI.h
bloba968095c0a471f139738f972f5f0ac5b57b0ae2e
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 * High-level interface to the JS garbage collector.
9 */
11 #ifndef js_GCAPI_h
12 #define js_GCAPI_h
14 #include "mozilla/TimeStamp.h"
15 #include "mozilla/Vector.h"
17 #include "js/GCAnnotations.h"
18 #include "js/TypeDecls.h"
19 #include "js/UniquePtr.h"
20 #include "js/Utility.h"
22 class JS_PUBLIC_API JSTracer;
24 namespace js {
25 namespace gc {
26 class GCRuntime;
27 } // namespace gc
28 namespace gcstats {
29 struct Statistics;
30 } // namespace gcstats
31 } // namespace js
33 namespace JS {
35 // Options used when starting a GC.
36 enum class GCOptions : uint32_t {
37 // Normal GC invocation.
39 // Some objects that are unreachable from the program may still be alive after
40 // collection because of internal references
41 Normal = 0,
43 // Try to release as much memory as possible by clearing internal caches,
44 // aggressively discarding JIT code and decommitting unused chunks. This
45 // ensures all unreferenced objects are removed from the system.
47 // Finally, compact the GC heap.
48 Shrink = 1,
51 } // namespace JS
53 typedef enum JSGCParamKey {
54 /**
55 * Maximum nominal heap before last ditch GC.
57 * Soft limit on the number of bytes we are allowed to allocate in the GC
58 * heap. Attempts to allocate gcthings over this limit will return null and
59 * subsequently invoke the standard OOM machinery, independent of available
60 * physical memory.
62 * Pref: javascript.options.mem.max
63 * Default: 0xffffffff
65 JSGC_MAX_BYTES = 0,
67 /**
68 * Maximum size of the generational GC nurseries.
70 * This will be rounded to the nearest gc::ChunkSize.
72 * Pref: javascript.options.mem.nursery.max_kb
73 * Default: JS::DefaultNurseryMaxBytes
75 JSGC_MAX_NURSERY_BYTES = 2,
77 /** Amount of bytes allocated by the GC. */
78 JSGC_BYTES = 3,
80 /** Number of times GC has been invoked. Includes both major and minor GC. */
81 JSGC_NUMBER = 4,
83 /**
84 * Whether incremental GC is enabled. If not, GC will always run to
85 * completion.
87 * prefs: javascript.options.mem.gc_incremental.
88 * Default: false
90 JSGC_INCREMENTAL_GC_ENABLED = 5,
92 /**
93 * Whether per-zone GC is enabled. If not, all zones are collected every time.
95 * prefs: javascript.options.mem.gc_per_zone
96 * Default: false
98 JSGC_PER_ZONE_GC_ENABLED = 6,
100 /** Number of cached empty GC chunks. */
101 JSGC_UNUSED_CHUNKS = 7,
103 /** Total number of allocated GC chunks. */
104 JSGC_TOTAL_CHUNKS = 8,
107 * Max milliseconds to spend in an incremental GC slice.
109 * A value of zero means there is no maximum.
111 * Pref: javascript.options.mem.gc_incremental_slice_ms
112 * Default: DefaultTimeBudgetMS.
114 JSGC_SLICE_TIME_BUDGET_MS = 9,
117 * Maximum size the GC mark stack can grow to.
119 * Pref: none
120 * Default: MarkStack::DefaultCapacity
122 JSGC_MARK_STACK_LIMIT = 10,
125 * The "do we collect?" decision depends on various parameters and can be
126 * summarised as:
128 * ZoneSize > Max(ThresholdBase, LastSize) * GrowthFactor * ThresholdFactor
130 * Where
131 * ZoneSize: Current size of this zone.
132 * LastSize: Heap size immediately after the most recent collection.
133 * ThresholdBase: The JSGC_ALLOCATION_THRESHOLD parameter
134 * GrowthFactor: A number above 1, calculated based on some of the
135 * following parameters.
136 * See computeZoneHeapGrowthFactorForHeapSize() in GC.cpp
137 * ThresholdFactor: 1.0 to trigger an incremental collections or between
138 * JSGC_SMALL_HEAP_INCREMENTAL_LIMIT and
139 * JSGC_LARGE_HEAP_INCREMENTAL_LIMIT to trigger a
140 * non-incremental collection.
142 * The RHS of the equation above is calculated and sets
143 * zone->gcHeapThreshold.bytes(). When gcHeapSize.bytes() exeeds
144 * gcHeapThreshold.bytes() for a zone, the zone may be scheduled for a GC.
148 * GCs less than this far apart in milliseconds will be considered
149 * 'high-frequency GCs'.
151 * Pref: javascript.options.mem.gc_high_frequency_time_limit_ms
152 * Default: HighFrequencyThreshold
154 JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
157 * Upper limit for classifying a heap as small (MB).
159 * Dynamic heap growth thresholds are based on whether the heap is small,
160 * medium or large. Heaps smaller than this size are classified as small;
161 * larger heaps are classified as medium or large.
163 * Pref: javascript.options.mem.gc_small_heap_size_max_mb
164 * Default: SmallHeapSizeMaxBytes
166 JSGC_SMALL_HEAP_SIZE_MAX = 12,
169 * Lower limit for classifying a heap as large (MB).
171 * Dynamic heap growth thresholds are based on whether the heap is small,
172 * medium or large. Heaps larger than this size are classified as large;
173 * smaller heaps are classified as small or medium.
175 * Pref: javascript.options.mem.gc_large_heap_size_min_mb
176 * Default: LargeHeapSizeMinBytes
178 JSGC_LARGE_HEAP_SIZE_MIN = 13,
181 * Heap growth factor for small heaps in the high-frequency GC state.
183 * Pref: javascript.options.mem.gc_high_frequency_small_heap_growth
184 * Default: HighFrequencySmallHeapGrowth
186 JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH = 14,
189 * Heap growth factor for large heaps in the high-frequency GC state.
191 * Pref: javascript.options.mem.gc_high_frequency_large_heap_growth
192 * Default: HighFrequencyLargeHeapGrowth
194 JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH = 15,
197 * Heap growth factor for low frequency GCs.
199 * This factor is applied regardless of the size of the heap when not in the
200 * high-frequency GC state.
202 * Pref: javascript.options.mem.gc_low_frequency_heap_growth
203 * Default: LowFrequencyHeapGrowth
205 JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
208 * Lower limit for collecting a zone.
210 * Zones smaller than this size will not normally be collected.
212 * Pref: javascript.options.mem.gc_allocation_threshold_mb
213 * Default GCZoneAllocThresholdBase
215 JSGC_ALLOCATION_THRESHOLD = 19,
218 * We try to keep at least this many unused chunks in the free chunk pool at
219 * all times, even after a shrinking GC.
221 * Pref: javascript.options.mem.gc_min_empty_chunk_count
222 * Default: MinEmptyChunkCount
224 JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
227 * We never keep more than this many unused chunks in the free chunk
228 * pool.
230 * Pref: javascript.options.mem.gc_min_empty_chunk_count
231 * Default: MinEmptyChunkCount
233 JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
236 * Whether compacting GC is enabled.
238 * Pref: javascript.options.mem.gc_compacting
239 * Default: CompactingEnabled
241 JSGC_COMPACTING_ENABLED = 23,
244 * Limit of how far over the incremental trigger threshold we allow the heap
245 * to grow before finishing a collection non-incrementally, for small heaps.
247 * We trigger an incremental GC when a trigger threshold is reached but the
248 * collection may not be fast enough to keep up with the mutator. At some
249 * point we finish the collection non-incrementally.
251 * Default: SmallHeapIncrementalLimit
252 * Pref: javascript.options.mem.gc_small_heap_incremental_limit
254 JSGC_SMALL_HEAP_INCREMENTAL_LIMIT = 25,
257 * Limit of how far over the incremental trigger threshold we allow the heap
258 * to grow before finishing a collection non-incrementally, for large heaps.
260 * Default: LargeHeapIncrementalLimit
261 * Pref: javascript.options.mem.gc_large_heap_incremental_limit
263 JSGC_LARGE_HEAP_INCREMENTAL_LIMIT = 26,
266 * Attempt to run a minor GC in the idle time if the free space falls
267 * below this number of bytes.
269 * Default: NurseryChunkUsableSize / 4
270 * Pref: None
272 JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION = 27,
275 * If this percentage of the nursery is tenured and the nursery is at least
276 * 4MB, then proceed to examine which groups we should pretenure.
278 * Default: PretenureThreshold
279 * Pref: None
281 JSGC_PRETENURE_THRESHOLD = 28,
284 * If the above condition is met, then any object group that tenures more than
285 * this number of objects will be pretenured (if it can be).
287 * Default: PretenureGroupThreshold
288 * Pref: None
290 JSGC_PRETENURE_GROUP_THRESHOLD = 29,
293 * Attempt to run a minor GC in the idle time if the free space falls
294 * below this percentage (from 0 to 99).
296 * Default: 25
297 * Pref: None
299 JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT = 30,
302 * Minimum size of the generational GC nurseries.
304 * This value will be rounded to the nearest Nursery::SubChunkStep if below
305 * gc::ChunkSize, otherwise it'll be rounded to the nearest gc::ChunkSize.
307 * Default: Nursery::SubChunkLimit
308 * Pref: javascript.options.mem.nursery.min_kb
310 JSGC_MIN_NURSERY_BYTES = 31,
313 * The minimum time to allow between triggering last ditch GCs in seconds.
315 * Default: 60 seconds
316 * Pref: None
318 JSGC_MIN_LAST_DITCH_GC_PERIOD = 32,
321 * The delay (in heapsize kilobytes) between slices of an incremental GC.
323 * Default: ZoneAllocDelayBytes
325 JSGC_ZONE_ALLOC_DELAY_KB = 33,
328 * The current size of the nursery.
330 * This parameter is read-only.
332 JSGC_NURSERY_BYTES = 34,
335 * Retained size base value for calculating malloc heap threshold.
337 * Default: MallocThresholdBase
339 JSGC_MALLOC_THRESHOLD_BASE = 35,
342 * Growth factor for calculating malloc heap threshold.
344 * Default: MallocGrowthFactor
346 JSGC_MALLOC_GROWTH_FACTOR = 36,
349 * Whether incremental weakmap marking is enabled.
351 * Pref: javascript.options.mem.incremental_weakmap
352 * Default: IncrementalWeakMarkEnabled
354 JSGC_INCREMENTAL_WEAKMAP_ENABLED = 37,
357 * The chunk size in bytes for this system.
359 * This parameter is read-only.
361 JSGC_CHUNK_BYTES = 38,
364 * The number of background threads to use for parallel GC work for each CPU
365 * core, expressed as an integer percentage.
367 * Pref: javascript.options.mem.gc_helper_thread_ratio
369 JSGC_HELPER_THREAD_RATIO = 39,
372 * The maximum number of background threads to use for parallel GC work.
374 * Pref: javascript.options.mem.gc_max_helper_threads
376 JSGC_MAX_HELPER_THREADS = 40,
379 * The number of background threads to use for parallel GC work.
381 * This parameter is read-only and is set based on the
382 * JSGC_HELPER_THREAD_RATIO and JSGC_MAX_HELPER_THREADS parameters.
384 JSGC_HELPER_THREAD_COUNT = 41,
387 * If the percentage of the tenured strings exceeds this threshold, string
388 * will be allocated in tenured heap instead. (Default is allocated in
389 * nursery.)
391 JSGC_PRETENURE_STRING_THRESHOLD = 42,
394 * If the finalization rate of the tenured strings exceeds this threshold,
395 * string will be allocated in nursery.
397 JSGC_STOP_PRETENURE_STRING_THRESHOLD = 43,
400 * A number that is incremented on every major GC slice.
402 JSGC_MAJOR_GC_NUMBER = 44,
405 * A number that is incremented on every minor GC.
407 JSGC_MINOR_GC_NUMBER = 45,
410 * JS::RunIdleTimeGCTask will collect the nursery if it hasn't been collected
411 * in this many milliseconds.
413 * Default: 5000
414 * Pref: None
416 JSGC_NURSERY_TIMEOUT_FOR_IDLE_COLLECTION_MS = 46,
419 * The system page size in KB.
421 * This parameter is read-only.
423 JSGC_SYSTEM_PAGE_SIZE_KB = 47,
424 } JSGCParamKey;
427 * Generic trace operation that calls JS::TraceEdge on each traceable thing's
428 * location reachable from data.
430 typedef void (*JSTraceDataOp)(JSTracer* trc, void* data);
432 typedef enum JSGCStatus { JSGC_BEGIN, JSGC_END } JSGCStatus;
434 typedef void (*JSObjectsTenuredCallback)(JSContext* cx, void* data);
436 typedef enum JSFinalizeStatus {
438 * Called when preparing to sweep a group of zones, before anything has been
439 * swept. The collector will not yield to the mutator before calling the
440 * callback with JSFINALIZE_GROUP_START status.
442 JSFINALIZE_GROUP_PREPARE,
445 * Called after preparing to sweep a group of zones. Weak references to
446 * unmarked things have been removed at this point, but no GC things have
447 * been swept. The collector may yield to the mutator after this point.
449 JSFINALIZE_GROUP_START,
452 * Called after sweeping a group of zones. All dead GC things have been
453 * swept at this point.
455 JSFINALIZE_GROUP_END,
458 * Called at the end of collection when everything has been swept.
460 JSFINALIZE_COLLECTION_END
461 } JSFinalizeStatus;
463 typedef void (*JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status,
464 void* data);
466 typedef void (*JSWeakPointerZonesCallback)(JSContext* cx, void* data);
468 typedef void (*JSWeakPointerCompartmentCallback)(JSContext* cx,
469 JS::Compartment* comp,
470 void* data);
473 * This is called to tell the embedding that a FinalizationRegistry object has
474 * cleanup work, and that the engine should be called back at an appropriate
475 * later time to perform this cleanup, by calling the function |doCleanup|.
477 * This callback must not do anything that could cause GC.
479 using JSHostCleanupFinalizationRegistryCallback =
480 void (*)(JSFunction* doCleanup, JSObject* incumbentGlobal, void* data);
483 * Each external string has a pointer to JSExternalStringCallbacks. Embedders
484 * can use this to implement custom finalization or memory reporting behavior.
486 struct JSExternalStringCallbacks {
488 * Finalizes external strings created by JS_NewExternalString. The finalizer
489 * can be called off the main thread.
491 virtual void finalize(char16_t* chars) const = 0;
494 * Callback used by memory reporting to ask the embedder how much memory an
495 * external string is keeping alive. The embedder is expected to return a
496 * value that corresponds to the size of the allocation that will be released
497 * by the finalizer callback above.
499 * Implementations of this callback MUST NOT do anything that can cause GC.
501 virtual size_t sizeOfBuffer(const char16_t* chars,
502 mozilla::MallocSizeOf mallocSizeOf) const = 0;
505 namespace JS {
507 #define GCREASONS(D) \
508 /* Reasons internal to the JS engine. */ \
509 D(API, 0) \
510 D(EAGER_ALLOC_TRIGGER, 1) \
511 D(DESTROY_RUNTIME, 2) \
512 D(ROOTS_REMOVED, 3) \
513 D(LAST_DITCH, 4) \
514 D(TOO_MUCH_MALLOC, 5) \
515 D(ALLOC_TRIGGER, 6) \
516 D(DEBUG_GC, 7) \
517 D(COMPARTMENT_REVIVED, 8) \
518 D(RESET, 9) \
519 D(OUT_OF_NURSERY, 10) \
520 D(EVICT_NURSERY, 11) \
521 D(DELAYED_ATOMS_GC, 12) \
522 D(SHARED_MEMORY_LIMIT, 13) \
523 D(IDLE_TIME_COLLECTION, 14) \
524 D(BG_TASK_FINISHED, 15) \
525 D(ABORT_GC, 16) \
526 D(FULL_WHOLE_CELL_BUFFER, 17) \
527 D(FULL_GENERIC_BUFFER, 18) \
528 D(FULL_VALUE_BUFFER, 19) \
529 D(FULL_CELL_PTR_OBJ_BUFFER, 20) \
530 D(FULL_SLOT_BUFFER, 21) \
531 D(FULL_SHAPE_BUFFER, 22) \
532 D(TOO_MUCH_WASM_MEMORY, 23) \
533 D(DISABLE_GENERATIONAL_GC, 24) \
534 D(FINISH_GC, 25) \
535 D(PREPARE_FOR_TRACING, 26) \
536 D(UNUSED4, 27) \
537 D(FULL_CELL_PTR_STR_BUFFER, 28) \
538 D(TOO_MUCH_JIT_CODE, 29) \
539 D(FULL_CELL_PTR_BIGINT_BUFFER, 30) \
540 D(INIT_SELF_HOSTING, 31) \
541 D(NURSERY_MALLOC_BUFFERS, 32) \
543 /* \
544 * Reasons from Firefox. \
546 * The JS engine attaches special meanings to some of these reasons. \
547 */ \
548 D(DOM_WINDOW_UTILS, FIRST_FIREFOX_REASON) \
549 D(COMPONENT_UTILS, 34) \
550 D(MEM_PRESSURE, 35) \
551 D(CC_FINISHED, 36) \
552 D(CC_FORCED, 37) \
553 D(LOAD_END, 38) \
554 D(UNUSED3, 39) \
555 D(PAGE_HIDE, 40) \
556 D(NSJSCONTEXT_DESTROY, 41) \
557 D(WORKER_SHUTDOWN, 42) \
558 D(SET_DOC_SHELL, 43) \
559 D(DOM_UTILS, 44) \
560 D(DOM_IPC, 45) \
561 D(DOM_WORKER, 46) \
562 D(INTER_SLICE_GC, 47) \
563 D(UNUSED1, 48) \
564 D(FULL_GC_TIMER, 49) \
565 D(SHUTDOWN_CC, 50) \
566 D(UNUSED2, 51) \
567 D(USER_INACTIVE, 52) \
568 D(XPCONNECT_SHUTDOWN, 53) \
569 D(DOCSHELL, 54) \
570 D(HTML_PARSER, 55) \
572 /* Reasons reserved for embeddings. */ \
573 D(RESERVED1, FIRST_RESERVED_REASON) \
574 D(RESERVED2, 91) \
575 D(RESERVED3, 92) \
576 D(RESERVED4, 93) \
577 D(RESERVED5, 94) \
578 D(RESERVED6, 95) \
579 D(RESERVED7, 96) \
580 D(RESERVED8, 97) \
581 D(RESERVED9, 98)
583 enum class GCReason {
584 FIRST_FIREFOX_REASON = 33,
585 FIRST_RESERVED_REASON = 90,
587 #define MAKE_REASON(name, val) name = val,
588 GCREASONS(MAKE_REASON)
589 #undef MAKE_REASON
590 NO_REASON,
591 NUM_REASONS,
594 * For telemetry, we want to keep a fixed max bucket size over time so we
595 * don't have to switch histograms. 100 is conservative; but the cost of extra
596 * buckets seems to be low while the cost of switching histograms is high.
598 NUM_TELEMETRY_REASONS = 100
602 * Get a statically allocated C string explaining the given GC reason.
604 extern JS_PUBLIC_API const char* ExplainGCReason(JS::GCReason reason);
607 * Return true if the GC reason is internal to the JS engine.
609 extern JS_PUBLIC_API bool InternalGCReason(JS::GCReason reason);
612 * Zone GC:
614 * SpiderMonkey's GC is capable of performing a collection on an arbitrary
615 * subset of the zones in the system. This allows an embedding to minimize
616 * collection time by only collecting zones that have run code recently,
617 * ignoring the parts of the heap that are unlikely to have changed.
619 * When triggering a GC using one of the functions below, it is first necessary
620 * to select the zones to be collected. To do this, you can call
621 * PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select
622 * all zones. Failing to select any zone is an error.
626 * Schedule the given zone to be collected as part of the next GC.
628 extern JS_PUBLIC_API void PrepareZoneForGC(JSContext* cx, Zone* zone);
631 * Schedule all zones to be collected in the next GC.
633 extern JS_PUBLIC_API void PrepareForFullGC(JSContext* cx);
636 * When performing an incremental GC, the zones that were selected for the
637 * previous incremental slice must be selected in subsequent slices as well.
638 * This function selects those slices automatically.
640 extern JS_PUBLIC_API void PrepareForIncrementalGC(JSContext* cx);
643 * Returns true if any zone in the system has been scheduled for GC with one of
644 * the functions above or by the JS engine.
646 extern JS_PUBLIC_API bool IsGCScheduled(JSContext* cx);
649 * Undoes the effect of the Prepare methods above. The given zone will not be
650 * collected in the next GC.
652 extern JS_PUBLIC_API void SkipZoneForGC(JSContext* cx, Zone* zone);
655 * Non-Incremental GC:
657 * The following functions perform a non-incremental GC.
661 * Performs a non-incremental collection of all selected zones.
663 extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx, JS::GCOptions options,
664 GCReason reason);
667 * Incremental GC:
669 * Incremental GC divides the full mark-and-sweep collection into multiple
670 * slices, allowing client JavaScript code to run between each slice. This
671 * allows interactive apps to avoid long collection pauses. Incremental GC does
672 * not make collection take less time, it merely spreads that time out so that
673 * the pauses are less noticable.
675 * For a collection to be carried out incrementally the following conditions
676 * must be met:
677 * - The collection must be run by calling JS::IncrementalGC() rather than
678 * JS_GC().
679 * - The GC parameter JSGC_INCREMENTAL_GC_ENABLED must be true.
681 * Note: Even if incremental GC is enabled and working correctly,
682 * non-incremental collections can still happen when low on memory.
686 * Begin an incremental collection and perform one slice worth of work. When
687 * this function returns, the collection may not be complete.
688 * IncrementalGCSlice() must be called repeatedly until
689 * !IsIncrementalGCInProgress(cx).
691 * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
692 * shorter than the requested interval.
694 extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx,
695 JS::GCOptions options,
696 GCReason reason,
697 int64_t millis = 0);
700 * Perform a slice of an ongoing incremental collection. When this function
701 * returns, the collection may not be complete. It must be called repeatedly
702 * until !IsIncrementalGCInProgress(cx).
704 * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
705 * shorter than the requested interval.
707 extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, GCReason reason,
708 int64_t millis = 0);
711 * Return whether an incremental GC has work to do on the foreground thread and
712 * would make progress if a slice was run now. If this returns false then the GC
713 * is waiting for background threads to finish their work and a slice started
714 * now would return immediately.
716 extern JS_PUBLIC_API bool IncrementalGCHasForegroundWork(JSContext* cx);
719 * If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection
720 * by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx),
721 * this is equivalent to NonIncrementalGC. When this function returns,
722 * IsIncrementalGCInProgress(cx) will always be false.
724 extern JS_PUBLIC_API void FinishIncrementalGC(JSContext* cx, GCReason reason);
727 * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and
728 * performs whatever work needs to be done to return the collector to its idle
729 * state. This may take an arbitrarily long time. When this function returns,
730 * IsIncrementalGCInProgress(cx) will always be false.
732 extern JS_PUBLIC_API void AbortIncrementalGC(JSContext* cx);
734 namespace dbg {
736 // The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the
737 // `js::gcstats::Statistics` data without the uber implementation-specific bits.
738 // It should generally be palatable for web developers.
739 class GarbageCollectionEvent {
740 // The major GC number of the GC cycle this data pertains to.
741 uint64_t majorGCNumber_;
743 // Reference to a non-owned, statically allocated C string. This is a very
744 // short reason explaining why a GC was triggered.
745 const char* reason;
747 // Reference to a nullable, non-owned, statically allocated C string. If the
748 // collection was forced to be non-incremental, this is a short reason of
749 // why the GC could not perform an incremental collection.
750 const char* nonincrementalReason;
752 // Represents a single slice of a possibly multi-slice incremental garbage
753 // collection.
754 struct Collection {
755 mozilla::TimeStamp startTimestamp;
756 mozilla::TimeStamp endTimestamp;
759 // The set of garbage collection slices that made up this GC cycle.
760 mozilla::Vector<Collection> collections;
762 GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete;
763 GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete;
765 public:
766 explicit GarbageCollectionEvent(uint64_t majorGCNum)
767 : majorGCNumber_(majorGCNum),
768 reason(nullptr),
769 nonincrementalReason(nullptr),
770 collections() {}
772 using Ptr = js::UniquePtr<GarbageCollectionEvent>;
773 static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats,
774 uint64_t majorGCNumber);
776 JSObject* toJSObject(JSContext* cx) const;
778 uint64_t majorGCNumber() const { return majorGCNumber_; }
781 } // namespace dbg
783 enum GCProgress {
785 * During GC, the GC is bracketed by GC_CYCLE_BEGIN/END callbacks. Each
786 * slice between those (whether an incremental or the sole non-incremental
787 * slice) is bracketed by GC_SLICE_BEGIN/GC_SLICE_END.
790 GC_CYCLE_BEGIN,
791 GC_SLICE_BEGIN,
792 GC_SLICE_END,
793 GC_CYCLE_END
796 struct JS_PUBLIC_API GCDescription {
797 bool isZone_;
798 bool isComplete_;
799 JS::GCOptions options_;
800 GCReason reason_;
802 GCDescription(bool isZone, bool isComplete, JS::GCOptions options,
803 GCReason reason)
804 : isZone_(isZone),
805 isComplete_(isComplete),
806 options_(options),
807 reason_(reason) {}
809 char16_t* formatSliceMessage(JSContext* cx) const;
810 char16_t* formatSummaryMessage(JSContext* cx) const;
812 mozilla::TimeStamp startTime(JSContext* cx) const;
813 mozilla::TimeStamp endTime(JSContext* cx) const;
814 mozilla::TimeStamp lastSliceStart(JSContext* cx) const;
815 mozilla::TimeStamp lastSliceEnd(JSContext* cx) const;
817 JS::UniqueChars sliceToJSONProfiler(JSContext* cx) const;
818 JS::UniqueChars formatJSONProfiler(JSContext* cx) const;
820 JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSContext* cx) const;
823 extern JS_PUBLIC_API UniqueChars MinorGcToJSON(JSContext* cx);
825 typedef void (*GCSliceCallback)(JSContext* cx, GCProgress progress,
826 const GCDescription& desc);
829 * The GC slice callback is called at the beginning and end of each slice. This
830 * callback may be used for GC notifications as well as to perform additional
831 * marking.
833 extern JS_PUBLIC_API GCSliceCallback
834 SetGCSliceCallback(JSContext* cx, GCSliceCallback callback);
837 * Describes the progress of an observed nursery collection.
839 enum class GCNurseryProgress {
841 * The nursery collection is starting.
843 GC_NURSERY_COLLECTION_START,
845 * The nursery collection is ending.
847 GC_NURSERY_COLLECTION_END
851 * A nursery collection callback receives the progress of the nursery collection
852 * and the reason for the collection.
854 using GCNurseryCollectionCallback = void (*)(JSContext* cx,
855 GCNurseryProgress progress,
856 GCReason reason);
859 * Set the nursery collection callback for the given runtime. When set, it will
860 * be called at the start and end of every nursery collection.
862 extern JS_PUBLIC_API GCNurseryCollectionCallback SetGCNurseryCollectionCallback(
863 JSContext* cx, GCNurseryCollectionCallback callback);
865 typedef void (*DoCycleCollectionCallback)(JSContext* cx);
868 * The purge gray callback is called after any COMPARTMENT_REVIVED GC in which
869 * the majority of compartments have been marked gray.
871 extern JS_PUBLIC_API DoCycleCollectionCallback
872 SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback);
875 * Incremental GC defaults to enabled, but may be disabled for testing or in
876 * embeddings that have not yet implemented barriers on their native classes.
877 * There is not currently a way to re-enable incremental GC once it has been
878 * disabled on the runtime.
880 extern JS_PUBLIC_API void DisableIncrementalGC(JSContext* cx);
883 * Returns true if incremental GC is enabled. Simply having incremental GC
884 * enabled is not sufficient to ensure incremental collections are happening.
885 * See the comment "Incremental GC" above for reasons why incremental GC may be
886 * suppressed. Inspection of the "nonincremental reason" field of the
887 * GCDescription returned by GCSliceCallback may help narrow down the cause if
888 * collections are not happening incrementally when expected.
890 extern JS_PUBLIC_API bool IsIncrementalGCEnabled(JSContext* cx);
893 * Returns true while an incremental GC is ongoing, both when actively
894 * collecting and between slices.
896 extern JS_PUBLIC_API bool IsIncrementalGCInProgress(JSContext* cx);
899 * Returns true while an incremental GC is ongoing, both when actively
900 * collecting and between slices.
902 extern JS_PUBLIC_API bool IsIncrementalGCInProgress(JSRuntime* rt);
905 * Returns true if the most recent GC ran incrementally.
907 extern JS_PUBLIC_API bool WasIncrementalGC(JSRuntime* rt);
910 * Generational GC:
912 * Note: Generational GC is not yet enabled by default. The following class
913 * is non-functional unless SpiderMonkey was configured with
914 * --enable-gcgenerational.
917 /** Ensure that generational GC is disabled within some scope. */
918 class JS_PUBLIC_API AutoDisableGenerationalGC {
919 JSContext* cx;
921 public:
922 explicit AutoDisableGenerationalGC(JSContext* cx);
923 ~AutoDisableGenerationalGC();
927 * Returns true if generational allocation and collection is currently enabled
928 * on the given runtime.
930 extern JS_PUBLIC_API bool IsGenerationalGCEnabled(JSRuntime* rt);
933 * Enable or disable support for pretenuring allocations based on their
934 * allocation site.
936 extern JS_PUBLIC_API void SetSiteBasedPretenuringEnabled(bool enable);
939 * Pass a subclass of this "abstract" class to callees to require that they
940 * never GC. Subclasses can use assertions or the hazard analysis to ensure no
941 * GC happens.
943 class JS_PUBLIC_API AutoRequireNoGC {
944 protected:
945 AutoRequireNoGC() = default;
946 ~AutoRequireNoGC() = default;
950 * Diagnostic assert (see MOZ_DIAGNOSTIC_ASSERT) that GC cannot occur while this
951 * class is live. This class does not disable the static rooting hazard
952 * analysis.
954 * This works by entering a GC unsafe region, which is checked on allocation and
955 * on GC.
957 class JS_PUBLIC_API AutoAssertNoGC : public AutoRequireNoGC {
958 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
959 JSContext* cx_;
961 public:
962 // This gets the context from TLS if it is not passed in.
963 explicit AutoAssertNoGC(JSContext* cx = nullptr);
964 ~AutoAssertNoGC();
965 #else
966 public:
967 explicit AutoAssertNoGC(JSContext* cx = nullptr) {}
968 ~AutoAssertNoGC() {}
969 #endif
973 * Disable the static rooting hazard analysis in the live region and assert in
974 * debug builds if any allocation that could potentially trigger a GC occurs
975 * while this guard object is live. This is most useful to help the exact
976 * rooting hazard analysis in complex regions, since it cannot understand
977 * dataflow.
979 * Note: GC behavior is unpredictable even when deterministic and is generally
980 * non-deterministic in practice. The fact that this guard has not
981 * asserted is not a guarantee that a GC cannot happen in the guarded
982 * region. As a rule, anyone performing a GC unsafe action should
983 * understand the GC properties of all code in that region and ensure
984 * that the hazard analysis is correct for that code, rather than relying
985 * on this class.
987 #ifdef DEBUG
988 class JS_PUBLIC_API AutoSuppressGCAnalysis : public AutoAssertNoGC {
989 public:
990 explicit AutoSuppressGCAnalysis(JSContext* cx = nullptr)
991 : AutoAssertNoGC(cx) {}
992 } JS_HAZ_GC_SUPPRESSED;
993 #else
994 class JS_PUBLIC_API AutoSuppressGCAnalysis : public AutoRequireNoGC {
995 public:
996 explicit AutoSuppressGCAnalysis(JSContext* cx = nullptr) {}
997 } JS_HAZ_GC_SUPPRESSED;
998 #endif
1001 * Assert that code is only ever called from a GC callback, disable the static
1002 * rooting hazard analysis and assert if any allocation that could potentially
1003 * trigger a GC occurs while this guard object is live.
1005 * This is useful to make the static analysis ignore code that runs in GC
1006 * callbacks.
1008 class JS_PUBLIC_API AutoAssertGCCallback : public AutoSuppressGCAnalysis {
1009 public:
1010 #ifdef DEBUG
1011 AutoAssertGCCallback();
1012 #else
1013 AutoAssertGCCallback() {}
1014 #endif
1018 * Place AutoCheckCannotGC in scopes that you believe can never GC. These
1019 * annotations will be verified both dynamically via AutoAssertNoGC, and
1020 * statically with the rooting hazard analysis (implemented by making the
1021 * analysis consider AutoCheckCannotGC to be a GC pointer, and therefore
1022 * complain if it is live across a GC call.) It is useful when dealing with
1023 * internal pointers to GC things where the GC thing itself may not be present
1024 * for the static analysis: e.g. acquiring inline chars from a JSString* on the
1025 * heap.
1027 * We only do the assertion checking in DEBUG builds.
1029 #ifdef DEBUG
1030 class JS_PUBLIC_API AutoCheckCannotGC : public AutoAssertNoGC {
1031 public:
1032 explicit AutoCheckCannotGC(JSContext* cx = nullptr) : AutoAssertNoGC(cx) {}
1033 } JS_HAZ_GC_INVALIDATED;
1034 #else
1035 class JS_PUBLIC_API AutoCheckCannotGC : public AutoRequireNoGC {
1036 public:
1037 explicit AutoCheckCannotGC(JSContext* cx = nullptr) {}
1038 } JS_HAZ_GC_INVALIDATED;
1039 #endif
1041 extern JS_PUBLIC_API void SetLowMemoryState(JSContext* cx, bool newState);
1044 * Internal to Firefox.
1046 extern JS_PUBLIC_API void NotifyGCRootsRemoved(JSContext* cx);
1048 } /* namespace JS */
1050 typedef void (*JSGCCallback)(JSContext* cx, JSGCStatus status,
1051 JS::GCReason reason, void* data);
1054 * Register externally maintained GC roots.
1056 * traceOp: the trace operation. For each root the implementation should call
1057 * JS::TraceEdge whenever the root contains a traceable thing.
1058 * data: the data argument to pass to each invocation of traceOp.
1060 extern JS_PUBLIC_API bool JS_AddExtraGCRootsTracer(JSContext* cx,
1061 JSTraceDataOp traceOp,
1062 void* data);
1064 /** Undo a call to JS_AddExtraGCRootsTracer. */
1065 extern JS_PUBLIC_API void JS_RemoveExtraGCRootsTracer(JSContext* cx,
1066 JSTraceDataOp traceOp,
1067 void* data);
1069 extern JS_PUBLIC_API void JS_GC(JSContext* cx,
1070 JS::GCReason reason = JS::GCReason::API);
1072 extern JS_PUBLIC_API void JS_MaybeGC(JSContext* cx);
1074 extern JS_PUBLIC_API void JS_SetGCCallback(JSContext* cx, JSGCCallback cb,
1075 void* data);
1077 extern JS_PUBLIC_API void JS_SetObjectsTenuredCallback(
1078 JSContext* cx, JSObjectsTenuredCallback cb, void* data);
1080 extern JS_PUBLIC_API bool JS_AddFinalizeCallback(JSContext* cx,
1081 JSFinalizeCallback cb,
1082 void* data);
1084 extern JS_PUBLIC_API void JS_RemoveFinalizeCallback(JSContext* cx,
1085 JSFinalizeCallback cb);
1088 * Weak pointers and garbage collection
1090 * Weak pointers are by their nature not marked as part of garbage collection,
1091 * but they may need to be updated in two cases after a GC:
1093 * 1) Their referent was found not to be live and is about to be finalized
1094 * 2) Their referent has been moved by a compacting GC
1096 * To handle this, any part of the system that maintain weak pointers to
1097 * JavaScript GC things must register a callback with
1098 * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
1099 * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
1100 * about.
1102 * Since sweeping is incremental, we have several callbacks to avoid repeatedly
1103 * having to visit all embedder structures. The WeakPointerZonesCallback is
1104 * called once for each strongly connected group of zones, whereas the
1105 * WeakPointerCompartmentCallback is called once for each compartment that is
1106 * visited while sweeping. Structures that cannot contain references in more
1107 * than one compartment should sweep the relevant per-compartment structures
1108 * using the latter callback to minimizer per-slice overhead.
1110 * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
1111 * referent is about to be finalized the pointer will be set to null. If the
1112 * referent has been moved then the pointer will be updated to point to the new
1113 * location.
1115 * Callers of this method are responsible for updating any state that is
1116 * dependent on the object's address. For example, if the object's address is
1117 * used as a key in a hashtable, then the object must be removed and
1118 * re-inserted with the correct hash.
1121 extern JS_PUBLIC_API bool JS_AddWeakPointerZonesCallback(
1122 JSContext* cx, JSWeakPointerZonesCallback cb, void* data);
1124 extern JS_PUBLIC_API void JS_RemoveWeakPointerZonesCallback(
1125 JSContext* cx, JSWeakPointerZonesCallback cb);
1127 extern JS_PUBLIC_API bool JS_AddWeakPointerCompartmentCallback(
1128 JSContext* cx, JSWeakPointerCompartmentCallback cb, void* data);
1130 extern JS_PUBLIC_API void JS_RemoveWeakPointerCompartmentCallback(
1131 JSContext* cx, JSWeakPointerCompartmentCallback cb);
1133 namespace JS {
1134 template <typename T>
1135 class Heap;
1138 extern JS_PUBLIC_API void JS_UpdateWeakPointerAfterGC(
1139 JS::Heap<JSObject*>* objp);
1141 extern JS_PUBLIC_API void JS_UpdateWeakPointerAfterGCUnbarriered(
1142 JSObject** objp);
1144 extern JS_PUBLIC_API void JS_SetGCParameter(JSContext* cx, JSGCParamKey key,
1145 uint32_t value);
1147 extern JS_PUBLIC_API void JS_ResetGCParameter(JSContext* cx, JSGCParamKey key);
1149 extern JS_PUBLIC_API uint32_t JS_GetGCParameter(JSContext* cx,
1150 JSGCParamKey key);
1152 extern JS_PUBLIC_API void JS_SetGCParametersBasedOnAvailableMemory(
1153 JSContext* cx, uint32_t availMem);
1156 * Create a new JSString whose chars member refers to external memory, i.e.,
1157 * memory requiring application-specific finalization.
1159 extern JS_PUBLIC_API JSString* JS_NewExternalString(
1160 JSContext* cx, const char16_t* chars, size_t length,
1161 const JSExternalStringCallbacks* callbacks);
1164 * Create a new JSString whose chars member may refer to external memory.
1165 * If a new external string is allocated, |*allocatedExternal| is set to true.
1166 * Otherwise the returned string is either not an external string or an
1167 * external string allocated by a previous call and |*allocatedExternal| is set
1168 * to false. If |*allocatedExternal| is false, |fin| won't be called.
1170 extern JS_PUBLIC_API JSString* JS_NewMaybeExternalString(
1171 JSContext* cx, const char16_t* chars, size_t length,
1172 const JSExternalStringCallbacks* callbacks, bool* allocatedExternal);
1175 * Return the 'callbacks' arg passed to JS_NewExternalString or
1176 * JS_NewMaybeExternalString.
1178 extern JS_PUBLIC_API const JSExternalStringCallbacks*
1179 JS_GetExternalStringCallbacks(JSString* str);
1181 namespace JS {
1183 extern JS_PUBLIC_API bool IsIdleGCTaskNeeded(JSRuntime* rt);
1185 extern JS_PUBLIC_API void RunIdleTimeGCTask(JSRuntime* rt);
1187 extern JS_PUBLIC_API void SetHostCleanupFinalizationRegistryCallback(
1188 JSContext* cx, JSHostCleanupFinalizationRegistryCallback cb, void* data);
1191 * Clear kept alive objects in JS WeakRef.
1192 * https://tc39.es/proposal-weakrefs/#sec-clear-kept-objects
1194 extern JS_PUBLIC_API void ClearKeptObjects(JSContext* cx);
1196 extern JS_PUBLIC_API bool ZoneIsCollecting(Zone* zone);
1197 extern JS_PUBLIC_API bool AtomsZoneIsCollecting(JSRuntime* runtime);
1198 extern JS_PUBLIC_API bool IsAtomsZone(Zone* zone);
1200 } // namespace JS
1202 namespace js {
1203 namespace gc {
1206 * Create an object providing access to the garbage collector's internal notion
1207 * of the current state of memory (both GC heap memory and GCthing-controlled
1208 * malloc memory.
1210 extern JS_PUBLIC_API JSObject* NewMemoryInfoObject(JSContext* cx);
1213 * Run the finalizer of a nursery-allocated JSObject that is known to be dead.
1215 * This is a dangerous operation - only use this if you know what you're doing!
1217 * This is used by the browser to implement nursery-allocated wrapper cached
1218 * wrappers.
1220 extern JS_PUBLIC_API void FinalizeDeadNurseryObject(JSContext* cx,
1221 JSObject* obj);
1223 } /* namespace gc */
1224 } /* namespace js */
1226 #ifdef JS_GC_ZEAL
1228 # define JS_DEFAULT_ZEAL_FREQ 100
1230 extern JS_PUBLIC_API void JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits,
1231 uint32_t* frequency,
1232 uint32_t* nextScheduled);
1234 extern JS_PUBLIC_API void JS_SetGCZeal(JSContext* cx, uint8_t zeal,
1235 uint32_t frequency);
1237 extern JS_PUBLIC_API void JS_UnsetGCZeal(JSContext* cx, uint8_t zeal);
1239 extern JS_PUBLIC_API void JS_ScheduleGC(JSContext* cx, uint32_t count);
1241 #endif
1243 #endif /* js_GCAPI_h */