JS_SetGCCallback

Specify a new callback function for the garbage collector.

Syntax

void
JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb, void *data);

JSGCCallback
JS_SetGCCallback(JSContext *cx, JSGCCallback cb); // Obsolete since JSAPI 13

JSGCCallback
JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); // Obsolete since JSAPI 13
Name Type Description
cx JSContext * (for the old JS_SetGCCallback) Any JSContext. The GC callback of the associated JSRuntime is set.
rt JSRuntime * The JSRuntime for which to set the GC callback.
cb JSGCCallback Pointer to the new callback function to use.

Callback syntax

typedef enum JSGCStatus {
    JSGC_BEGIN,
    JSGC_END,
    JSGC_MARK_END,    // Obsolete since JSAPI 13
    JSGC_FINALIZE_END // Obsolete since JSAPI 13
} JSGCStatus;

typedef void
(* JSGCCallback)(JSRuntime *rt, JSGCStatus status, void *data);
Name Type Description
cx JSContext * The context in which garbage collection is happening.
status JSGCStatus One of the JSGCStatus constants, described below, indicating the stage of GC.

Description

JS_SetGCCallback sets a callback function which the garbage collector calls at several points during garbage collection. rt is the runtime in which you specify the callback. cb is a pointer to the new callback function to use.

Callback related to finalization is separated to JS_SetFinalizeCallback in JSAPI 13.

Obsolete since JSAPI 13

JS_SetGCCallback returns a pointer to the previously used callback function upon completion. The application may store this return value in order to restore the original callback when the new callback is no longer needed. To restore the original callback, call JS_SetGCCallback a second time, and pass the old callback in as the cb argument.

During each complete garbage collection cycle, the current GC callback is called four times:

JSGC_BEGIN
Start of GC. The callback may prevent GC from starting by returning false. But even if the callback returns true, the garbage collector may determine that GC is not necessary, in which case the other three callbacks are skipped.
JSGC_MARK_END Obsolete since JSAPI 13
End of marking. The callback may use JS_IsAboutToBeFinalized to clean up weak references to JS objects (that is, pointers that are not traced by the GC).
JSGC_FINALIZE_END Obsolete since JSAPI 13
End of finalization.
JSGC_END
End of GC.

Sometimes these four callbacks happen once each, in the order listed. Sometimes JSGC_BEGIN happens and the rest of garbage collection does not happen, so the other three callbacks are not called. Sometimes several GC cycles happen in a row, so JSGC_BEGIN is followed by alternating JSGC_MARK_END and JSGC_FINALIZE_END callbacks, followed at last by JSGC_END.

The JSGC_BEGIN callback can occur very early when something triggers garbage collection—before the JavaScript engine has even determined whether GC should actually be done at the moment. Some quirky behavior follows from this:

  • The JavaScript engine can call the GC callback reentrantly on a single thread. For example, if the JSGC_MARK_END callback does something that triggers GC, a JSGC_BEGIN callback might happen. But the JavaScript engine will then detect that GC is already happening and will not actually do a nested GC cycle in this case.
  • In a JS_THREADSAFE build, a JSGC_BEGIN callback may happen on any thread, any time that thread triggers garbage collection (from almost any JSAPI call). The GC callback may be called on multiple threads at the same time (e.g. if a thread that is not in an active request calls JS_GC while GC is already happening on another thread).
  • In a JS_THREADSAFE build, a JSGC_BEGIN callback can happen on one thread before or while a JSGC_END callback for the previous GC cycle runs on another thread.

In a JS_THREADSAFE build, the JSGC_END callback is called after each stop-the-world rendezvous during which one or more garbage collection cycles finished. The callback executes on the same thread that performed GC, after the GC lock has been released. Other threads may be running in active requests.

See Also