/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * APIs for integration with the cycle collector. */ #ifndef js_friend_CycleCollector_h #define js_friend_CycleCollector_h #include "jstypes.h" #include "js/HeapAPI.h" // JS::GCCellPtr namespace JS { class CallbackTracer; } // namespace JS /* * Trace hook used to trace gray roots incrementally. * * This should return whether tracing is finished. It will be called repeatedly * in subsequent GC slices until it returns true. * * While tracing this should check the budget and return false if it has been * exceeded. When passed an unlimited budget it should always return true. */ using JSGrayRootsTracer = bool (*)(JSTracer* trc, JS::SliceBudget& budget, void* data); /* * Set a callback used to trace gray roots. * * The callback is called after the first slice of GC so the embedding must * implement appropriate barriers on its gray roots to ensure correctness. * * This callback may be called multiple times for different sets of zones. Use * JS::ZoneIsGrayMarking() to determine whether roots from a particular zone are * required. */ extern JS_PUBLIC_API void JS_SetGrayGCRootsTracer(JSContext* cx, JSGrayRootsTracer traceOp, void* data); using JSObjectsTenuredCallback = void (*)(JS::GCContext* gcx, void* data); extern JS_PUBLIC_API void JS_SetObjectsTenuredCallback( JSContext* cx, JSObjectsTenuredCallback cb, void* data); /* * Used by the cycle collector to trace through a shape and all * cycle-participating data it reaches, using bounded stack space. */ extern JS_PUBLIC_API void JS_TraceShapeCycleCollectorChildren( JS::CallbackTracer* trc, JS::GCCellPtr shape); namespace JS { class CallbackTracer; using DoCycleCollectionCallback = void (*)(JSContext* cx); /** * The cycle collection callback is called after any COMPARTMENT_REVIVED GC in * which the majority of compartments have been marked gray. */ extern JS_PUBLIC_API DoCycleCollectionCallback SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); inline JS_PUBLIC_API bool NeedGrayRootsForZone(Zone* zoneArg) { shadow::Zone* zone = shadow::Zone::from(zoneArg); return zone->isGCMarkingBlackAndGray() || zone->isGCCompacting(); } using ShouldClearWeakRefTargetCallback = bool (*)(GCCellPtr ptr, void* data); extern JS_PUBLIC_API void MaybeClearWeakRefTargets( JSRuntime* runtime, ShouldClearWeakRefTargetCallback callback, void* data); } // namespace JS namespace js { struct WeakMapTracer { JSRuntime* runtime; explicit WeakMapTracer(JSRuntime* rt) : runtime(rt) {} // Weak map tracer callback, called once for every binding of every // weak map that was live at the time of the last garbage collection. // // m will be nullptr if the weak map is not contained in a JS Object. // // The callback should not GC (and will assert in a debug build if it does // so.) virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0; }; extern JS_PUBLIC_API void TraceWeakMaps(WeakMapTracer* trc); extern JS_PUBLIC_API bool AreGCGrayBitsValid(JSRuntime* rt); extern JS_PUBLIC_API bool ZoneGlobalsAreAllGray(JS::Zone* zone); extern JS_PUBLIC_API void TraceGrayWrapperTargets(JSTracer* trc, JS::Zone* zone); using IterateGCThingCallback = void (*)(void*, JS::GCCellPtr, const JS::AutoRequireNoGC&); /** * Invoke cellCallback on every gray JSObject in the given zone. */ extern JS_PUBLIC_API void IterateGrayObjects( JS::Zone* zone, IterateGCThingCallback cellCallback, void* data); #if defined(JS_GC_ZEAL) || defined(DEBUG) // Trace the heap and check there are no black to gray edges. These are // not allowed since the cycle collector could throw away the gray thing and // leave a dangling pointer. // // This doesn't trace weak maps as these are handled separately. extern JS_PUBLIC_API bool CheckGrayMarkingState(JSRuntime* rt); #endif } // namespace js #endif // js_friend_CycleCollector_h