Source code

Revision control

Copy as Markdown

Other Tools

/* 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