Add JS_MapGCRoots for complete enumeration of GC roots (72465, r/sr={shaver,jband}).

This commit is contained in:
brendan%mozilla.org 2001-03-21 01:33:39 +00:00
parent 87dac46193
commit d97301d838
2 changed files with 76 additions and 6 deletions

View File

@ -18,7 +18,7 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
@ -1515,10 +1515,10 @@ JS_AddNamedRoot(JSContext *cx, void *rp, const char *name)
return js_AddRoot(cx, rp, name);
}
#ifdef DEBUG
#include "jshash.h" /* Added by JSIFY */
#ifdef DEBUG
typedef struct NamedRootDumpArgs {
void (*dump)(const char *name, void *rp, void *data);
void *data;
@ -1530,7 +1530,7 @@ js_named_root_dumper(JSHashEntry *he, intN i, void *arg)
NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg;
if (he->value)
args->dump((char *) he->value, (void *)he->key, args->data);
args->dump((char *)he->value, (void *)he->key, args->data);
return HT_ENUMERATE_NEXT;
}
@ -1548,6 +1548,48 @@ JS_DumpNamedRoots(JSRuntime *rt,
#endif /* DEBUG */
typedef struct GCRootMapArgs {
JSGCRootMapFun map;
void *data;
} GCRootMapArgs;
JS_STATIC_DLL_CALLBACK(intN)
js_gcroot_mapper(JSHashEntry *he, intN i, void *arg)
{
GCRootMapArgs *args = (GCRootMapArgs *) arg;
intN mapflags, htflags;
mapflags = args->map((void *)he->key, (char *)he->value, args->data);
#if JS_MAP_GCROOT_NEXT == HT_ENUMERATE_NEXT && \
JS_MAP_GCROOT_STOP == HT_ENUMERATE_STOP && \
JS_MAP_GCROOT_REMOVE == HT_ENUMERATE_REMOVE
htflags = mapflags;
#else
htflags = HT_ENUMERATE_NEXT;
if (mapflags & JS_MAP_GCROOT_STOP)
htflags |= HT_ENUMERATE_STOP;
if (mapflags & JS_MAP_GCROOT_REMOVE)
htflags |= HT_ENUMERATE_REMOVE;
#endif
return htflags;
}
JS_PUBLIC_API(intN)
JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data)
{
GCRootMapArgs args;
intN rv;
args.map = map;
args.data = data;
JS_LOCK_GC(rt);
rv = JS_HashTableEnumerateEntries(rt->gcRootsHash, js_gcroot_mapper, &args);
JS_UNLOCK_GC(rt);
return rv;
}
JS_PUBLIC_API(JSBool)
JS_LockGCThing(JSContext *cx, void *thing)
{
@ -3131,7 +3173,7 @@ JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
JSScript tmp;
JSRuntime *rt;
JSBool ok;
/* Make a temporary copy of the JSScript structure and farble it a bit. */
tmp = *script;
if (part == JSEXEC_PROLOG) {
@ -3649,7 +3691,7 @@ JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks)
cx->localeCallbacks = callbacks;
}
JS_PUBLIC_API(JSLocaleCallbacks *)
JS_PUBLIC_API(JSLocaleCallbacks *)
JS_GetLocaleCallbacks(JSContext *cx)
{
return cx->localeCallbacks;

View File

@ -528,6 +528,34 @@ JS_DumpNamedRoots(JSRuntime *rt,
void *data);
#endif
/*
* Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data).
* The root is pointed at by rp; if the root is unnamed, name is null; data is
* supplied from the third parameter to JS_MapGCRoots.
*
* The map function should return JS_MAP_GCROOT_REMOVE to cause the currently
* enumerated root to be removed. To stop enumeration, set JS_MAP_GCROOT_STOP
* in the return value. To keep on mapping, return JS_MAP_GCROOT_NEXT. These
* constants are flags; you can OR them together.
*
* This function acquires and releases rt's GC lock around the mapping of the
* roots table, so the map function should run to completion in as few cycles
* as possible. Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest,
* or any JS API entry point that acquires locks, without double-tripping or
* deadlocking on the GC lock.
*
* JS_MapGCRoots returns the count of roots that were successfully mapped.
*/
#define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */
#define JS_MAP_GCROOT_STOP 1 /* stop mapping entries */
#define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */
typedef intN
(* CRT_CALL JSGCRootMapFun)(void *rp, const char *name, void *data);
extern JS_PUBLIC_API(intN)
JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
extern JS_PUBLIC_API(JSBool)
JS_LockGCThing(JSContext *cx, void *thing);