Your Search Results

    GC Rooting Guide


    This guide explains the basics of interacting with SpiderMonkey's GC as a SpiderMonkey API user.  Since SpiderMonkey has a moving GC, it is very important that it knows about each and every pointer to a GC thing in the system.  SpiderMonkey's rooting API tries to make this task as simple as possible.

    What is a GC thing pointer?

    "GC thing" is the term used to refer to memory allocated and managed by the SpiderMonkey garbage collector.  The main types of GC thing pointer are:

    • JS::Value
    • JSObject*
    • JSString*
    • JSScript*
    • jsid

    Note that JS::Value and jsid can contain pointers internally even though they are not a normal pointer type, hence their inclusion in this list.

    If you use these types directly, or create classes, structs or arrays that contain them, you must follow the rules set out in this guide.  If you do not your program will not work correctly - if it works at all.

    GC things on the stack


    All GC thing pointers stored on the stack (i.e., local variables and parameters to functions) must use the JS::Rooted<T> class.  This is a template class where the template parameter is the type of the GC thing it contains.  From the user perspective, a JS::Rooted<T> instance behaves exactly as if it were the underlying pointer.

    JS::Rooted must be constructed with a JSContext*, and optionally an inital value.

    There are typedefs available for the main types, and it is suggested that these are used in preference to the template class:

    Template class Typedef
    JS::Rooted<JS::Value> JS::RootedValue
    JS::Rooted<JSObject*> JS::RootedObject
    JS::Rooted<JSString*> JS::RootedString
    JS::Rooted<JSScript*> JS::RootedScript
    JS::Rooted<jsid> JS::RootedId

    For example, instead of this:

    JSObject* localObj = JS_GetObjectOfSomeSort(cx);

    You would write this:

    JS::RootedObject localObj(cx, JS_GetObjectOfSomeSort(cx));

    SpiderMonkey makes it easy to remember to use JS::Rooted<T> types instead of a raw pointer because all of the API methods that may GC take a JS::Handle<T>, as described below.


    All GC thing pointers that are parameters to a function must be wrapped in JS::Handle<T>. A JS::Handle<T> is a reference to a JS::Rooted<T>. All JS::Handle<T> are created implicitly by referencing a JS::Rooted<T>: It is not valid to create a JS::Handle<T> manually. Like JS::Rooted<T>, a JS::Handle<T> can be used as if it were the underlying pointer.

    Since only a JS::Rooted<T> will cast to a JS::Handle<T>, the compiler will enforce correct rooting of any parameters passed to a function that may trigger GC. JS::Handle<T> exists because creating and destroying a JS::Rooted<T> is not free (though it only costs a few cycles). Thus, it makes more sense to only root the GC thing once and reuse it through an indirect reference. Like a reference, a JS::Handle is immutable: it can only ever refer to the JS::Rooted<T> that it was created for.

    Similarly to JS::Rooted<T>, there are typedefs available for the main types:

    Template class Typedef
    JS::Handle<JS::Value> JS::HandleValue
    JS::Handle<JSObject*> JS::HandleObject
    JS::Handle<JSString*> JS::HandleString
    JS::Handle<JSScript*> JS::HandleScript
    JS::Handle<jsid> JS::HandleId

    You should use JS::Handle<T> for all function parameters taking GC thing pointers (except out-parameters, which are described below).  For example, instead of:

    JSObject *
    someFunction(JSContext *cx, JSObject* obj) {
        // ...

    You should write:

    JSObject *
    someFunction(JSContext *cx, JS::HandleObject obj) {
        // ...


    All GC thing pointers which are used as an out-parameter must be wrapped in a JS::MutableHandle<T>. A JS::MutableHandle<T> is a reference to a JS::Rooted<T> that, unlike a normal handle, may modify the underlying JS::Rooted<T>. All JS::MutableHandle<T>s are created through an explicit "&" - address of operator - on a JS::Rooted<T> instance. JS::MutableHandle<T> is exactly like a JS::Handle<T> except that it adds a |.set(T &t)| method and must be created from a JS::Rooted<T> explicitly.

    There are typedefs for JS::MutableHandle<T>, the same as for the other templates:

    Template class Typedef
    JS::MutableHandle<JS::Value> JS::MutableHandleValue
    JS::MutableHandle<JSObject*> JS::MutableHandleObject
    JS::MutableHandle<JSString*> JS::MutableHandleString
    JS::MutableHandle<JSScript*> JS::MutableHandleScript
    JS::MutableHandle<jsid> JS::MutableHandleId

    JS::MutableHandle<T> should be used for all out-parameters, for example instead of:

    maybeGetValue(JSContext *cx, JS::Value* valueOut) {
        // ...
        if (!wasError)
            *valueOut = resultValue;
        return wasError;
    otherFunction(JSContext *cx) {
        JS::Value value;
        bool success = maybeGetValue(cx, &value);
        // ...

    You should write:

    maybeGetValue(JSContext *cx, JS::MutableHandleValue valueOut) {
        // ...
        if (!wasError)
        return wasError;
    otherFunction(JSContext *cx) {
        JS::RootedValue value(cx);
        bool success = maybeGetValue(cx, &value);
        // ...

    Return values

    It's ok to return raw pointers!  These do not need to be wrapped in any of rooting classes, but they must always be used to initialize a JS::Rooted<T>, never stored as a raw pointer on the stack.


    GC thing pointers that appear as part of a stack-allocated aggregates (array, structure, class, union) should use a JS::Rooted<T> when possible.

    There are some situations when using JS::Rooted<T> is not possible, or is undesirable for performance reasons.  To cover these cases, there are various AutoRooter classes that can be used.

    Here are the main AutoRooters defined:

    Type AutoRooter class
    JS::Value[] AutoArrayRooter
    js::Vector<JS::Value> AutoValueVector
    js::Vector<jsid> AutoIdVector
    js::Vector<JSObject*> AutoObjectVector
    js::Vector<JSScript*> AutoScriptVector

    If your case is not covered by one of these, it is possible to write your own by deriving from JS::CustomAutoRooter and overriding the virtual trace() method.  The implementation should trace all the GC things contained in the object by calling the JS_CallTracer() functions.

    GC things on the heap

    GC thing pointers on the heap must be wrapped in a JS::Heap<T>. The only exception to this is if they are added as roots with the JS_Add<T>Root() functions or JS::PersistentRooted class, but don't do this unless it's really necessary.  JS::Heap<T> pointers must also continue to be traced in the normal way, which is not covered here.

    JS::Heap<T> doesn't require a JSContext*, and can be constructed with or without an initial value parameter.  Like the other template classes, it functions as if it were the GC thing pointer itself.

    One consequence of having different rooting requirements for heap and stack data is that a single structure containing GC thing pointers cannot be used on both the stack and the heap.  In this case, separate structures must be created for the stack and the heap.

    There are currently no convenience typedefs for JS::Heap<T>.

    For example, instead of this:

    struct HeapStruct
        JSObject*  mSomeObject;
        JS::Value  mSomeValue;

    You should write:

    struct HeapStruct
        JS::Heap<JSObject*>  mSomeObject;
        JS::Heap<JS::Value>  mSomeValue;  


    • Use JS::Rooted<T> typedefs for local variables on the stack.
    • Use JS::Handle<T> typedefs for function parameters.
    • Use JS::MutableHandle<T> typedefs for function out-parameters.
    • Use an implicit cast from JS::Rooted<T> to get a JS::Handle<T>.
    • Use an explicit address-of-operator on JS::Rooted<T> to get a JS::MutableHandle<T>.
    • Return raw pointers from functions.
    • Use JS::Rooted<T> fields when possible for aggregates, otherwise use an AutoRooter.
    • Use JS::Heap<T> members for heap data. Note: Heap<T> are not "rooted": they must be traced!
    • Do not use JS::Rooted<T>, JS::Handle<T> or JS::MutableHandle<T> on the heap.
    • Do not use JS::Rooted<T> for function parameters.
    • Use JS::PersistentRooted<T> for things that are alive until the process exits.

    Document Tags and Contributors

    Contributors to this page: fscholz, sfink, terrence, JonCoppeard, tp21sQkv
    Last updated by: fscholz,
    Hide Sidebar