Specify a new callback function for the garbage collector.
JSGCCallback JS_SetGCCallback(JSContext *cx, JSGCCallback cb); JSGCCallback JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb);
| Name | Type | Description |
|---|---|---|
cx |
JSContext * |
(for JS_SetGCCallback) Any JSContext. The GC callback of the associated JSRuntime is set. |
rt |
JSRuntime * |
(for JS_SetGCCallbackRT) The JSRuntime for which to set the GC callback. |
cb |
JSGCCallback |
Pointer to the new callback function to use. |
typedef enum JSGCStatus {
JSGC_BEGIN, JSGC_END, JSGC_MARK_END, JSGC_FINALIZE_END
} JSGCStatus;
typedef JSBool (*JSGCCallback)(JSContext *cx, JSGCStatus status);
| 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. |
JS_SetGCCallback sets a callback function which the garbage collector calls at several points during garbage collection. cx is the context in which you specify the callback. cb is a pointer to the new callback function to use.
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
JS_FALSE. But even if the callback returns JS_TRUE, the garbage collector may determine that GC is not necessary, in which case the other three callbacks are skipped.
JSGC_MARK_END
JS_IsAboutToBeFinalized to clean up weak references to JS objects (that is, pointers that are not traced by the GC).
JSGC_FINALIZE_END
JSGC_END
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:
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.
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).
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.
Page last modified 20:05, 5 Sep 2008 by Jorend