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 returnstrue
, 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, aJSGC_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, aJSGC_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 callsJS_GC
while GC is already happening on another thread).
- In a
JS_THREADSAFE
build, aJSGC_BEGIN
callback can happen on one thread before or while aJSGC_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.