SpiderMonkey API Futures
“I have altered the SpiderMonkey API. Pray I do not alter it further.”
It’s time for a new API.
Why. The immediate trigger is that we’re building a generational GC. We need generational GC in order to greatly reduce GC pauses for short-lived objects and make games, apps, and audio/video run more smoothly. Generational GC means objects (and all other “gcthings”) will move during GC, which in turn means object pointers can change. That means client code like this won’t work:
JSObject *obj = ...; // Define a property. This could trigger GC and move |*obj|. rc = JS_DefineProperty(cx, obj, "a", INT_TO_JSVAL(1), 0, 0, 0); rc = JS_DefineProperty(cx, obj, "b", INT_TO_JSVAL(2), 0, 0, 0);
In the current configuration, we use conservative stack scanning to get GC roots, so the above code is fine. Conservative stack scanning means we scan all words in the C stack and all registers, and if any word |w| has a value that could be an address within the GC heap, we assume that it is, and start marking using that as a root. In the code above, |obj| will be stored either on the C stack or in a register, so it’s a root.
The problem with conservative scanning is that we can never know whether |w| is really a gcthing pointer, or if it’s just an integer value that happens to be in that range. So with conservative scanning, we can’t update |w| to the new location. And that would mean no compacting GC and no generational GC.
So conservative scanning has to go. Without conservative scanning, we need to provide some kind of rooting or handle API, and require client code to use that API to tell the engine which pointers are gcthing pointers, so they can be properly updated.
Past experience is that C rooting APIs are miserable: the user needs to explicitly root and unroot each pointer used. In practice, it’s never right. Even if all our users could magically get it right, we probably couldn’t for SpiderMonkey itself and for Gecko.
It’s much easier with a C++ API. With a C++ API, we can define types like |Handle
The short story is: Generational GC => C++ API.
What. The strictly virtuous thing to do would be to take the time to have a lot of discussions and design a brand new C++ API that would remain stable for the future. But we are not in a position to do that this year: we need to ship a new compiler, two new GCs, ES6, and enhancements to the Debugger object. Designing and shipping an entirely new stable API would be way too much. Perhaps next year.
So instead, we’re going to:
- Change the API to C++, meaning that we are free to use C++ features in the API, and future API users will need to use C++ to use the API.
- Design a “pretty good, pretty stable” C++ rooting/handle API and incorporate it into JSAPI. This is bug 753609, so if you’re going to use the API, please go there, check out the current version, and give us your thoughts.
- Make gradual changes to the JSAPI as needed, primarily to support Gecko, as we do now. Some of these may be to add C++ inline functions or things like that, which we have already started doing for small things to boost performance.
[Addendum May 9 5:22pm] Users who need a C API can use any of the existing source releases, including the in-progress js-1.8.7/js-10 based on the Firefox ESR10 source, which includes JM+TI. We might also do a future source release off Firefox 13 or thereabouts. Once generational GC gets going, JSAPI will be C++.