JavaScript:ActionMonkey:Stage 0 Whiteboard
.plan
- Get at least sketchy answers to most of the questions below.
- Do a sprint with Mardak and Brendan (if he's available) to reimplement jsgc.c using MMgc. Call it jsgc.cpp.
- Debug and grow wise.
General issues
If there's anywhere a GCThing has pointers to non-GC-managed memory that contains pointers back into GC-managed memory, we have a problem. Exact GC lets you do that (you know how to traverse the non-GC-managed memory). MMgc doesn't.
I don't know that SpiderMonkey does this anywhere. If it does, one fix is to change those data structures to live in GC-managed memory. So the fix itself is easy: finding the offenders is the interesting bit.
Prep work
Things that should probably happen pre-sprint:
- A few places are poking the
runtime->gcPokefield directly. I think these should be changed to use the GC_POKE macro.
- Administrivia: merge latest CVS into mozilla-central, then into actionmonkey; prepare Makefile and a dummy jsgc.cpp for the festivities.
Specific jsgc.h APIs
What follows is a dump of everything exposed through jsgc.h. Each item is rated * (one star, an easy exercise); ** (two stars, fun little puzzle); *** (three stars, hmmmm, that's interesting). The ratings are jorendorff's guesses though. The wildest, least-educated guesses are marked with ?.
GCX_OBJECT ... GCF_MUTABLE,
js_GetGCThingFlags - ** - Where do we put these
flags? They are no longer needed for the GC itself, but
non-GC-related functionality has been piggybacked on these flags, so
we can't just get rid of them. GCF_MARK is not used
outside the garbage collector, but
GCF_MUTABLE, GCF_LOCK, and
GCF_SYSTEM (and maybe the type bits) are used (and not just read access--there's
code outside jsgc.c that actually twiddles these bits).
We can overallocate by a byte and put the flags bits alongside the object itself. That single byte costs us 8 bytes... but actually I'm leaning toward doing this, for now, silly as it is. It lets us leave the existing API alone, macros and all. We'll worry about all sorts of speed/space concerns in the next round.
js_GetGCStringRuntime - * - GC::GetGC(const void *), then (a) decrement by some offset; or (b) just give the GC a pointer back to the context or runtime (that is, make a subclass of MMgc::GC that contains a pointer back to the JSContext, and use that).
GC_POKE - ** ? - Not sure about this yet. Best-case, we can maybe make it a no-op, but I have some reading to do before I can say.
js_ChangeExternalStringFinalizer - * - External strings can be implemented by a JSExternalString class with a destructor that consults the table of string finalizers.
js_InitGC ... js_MapGCRoots - * - Core features of MMgc. There's no API in MMgc for enumerating roots, but we can either cheat (via #define private protected) or keep our own list outside of MMgc. Anyway--not hard.
JSPtrTable, js_RegisterCloseableIterator,
JSGCCloseState, js_RegisterGenerator,
js_RunCloseHooks - *** ? - All this has to do with
iterator and generator cleanup. I'm still weak on finalization. Need to
come back to it. (Related bug explaining why what JSGC does now is safe: https://bugzilla.mozilla.org/show_bug.cgi?id=349272 ...need to read this, see if the same logic applies to MMgc.)
JSGCThing - ** - This can probably go away. It's
mentioned outside jsgc.c in two places: (a) in the context of
weakRoots.newborn, which I assume we'll keep, since the
newborn guarantee is JSAPI-visible; and (b) in the declaration of
JSContext, where they won't be needed anymore.
GC_NBYTES_MAX, GC_NUM_FREELISTS,
GC_FREELIST_NBYTES, GC_FREELIST_INDEX -
* - These can just go away.
js_NewGCThing - * - The only thing to worry about
is the flags.
js_LockGCThing, js_LockGCThingRT,
js_UnlockGCThingRT - ** ? - I need to read this code.
js_IsAboutToBeFinalized - * - We'll have to lay the hack
on pretty thick to get this without modifying MMgc source code, but
it can be done.
IS_GC_MARKING_TRACER - * ? - This isn't documented
anywhere, but it can probably just always return false.
JSTRACE_FUNCTION ... JSTRACE_XML - * ? - The
tracing API uses these. I think this will be unaffected; not positive.
JS_IS_VALID_TRACE_KIND - * - Unaffected.
js_CallValueTracerIfGCThing - * - Likely unaffected.
js_TraceStackFrame, js_TraceRuntime, js_TraceContext - * - Probably unaffected.
JSGCInvocationKind, GC_NORMAL,
GC_LAST_CONTEXT, GC_LAST_DITCH, js_GC - ** ? - The GC "invocation kinds" need to be maintained somehow. That will require some study.
js_UpdateMallocCounter - * ? - I would say
"unaffected" except that our use of JS_malloc() might end
up decreasing so much as to defeat the purpose of this. So maybe we
need a new heuristic for JS_MaybeGC(). The only other place gcMallocBytes is directly used is for jsscope.c for changing scope (it allocates space with calloc but treats it as a malloc). Ask Brendan.
JS_GCMETER, JSGCStats, js_DumpGCStats - * - Gone.
JSGCArenaList - * - Gone.
JSWeakRoots, JS_CLEAR_WEAK_ROOTS - * - Unaffected.