Bug 378492: proper checks for null and jsval type when tracing, r=brendan

This commit is contained in:
igor@mir2.org 2007-04-24 16:11:02 -07:00
Родитель dc0d0eee84
Коммит cf9855cab4
5 изменённых файлов: 40 добавлений и 49 удалений

Просмотреть файл

@ -1877,10 +1877,8 @@ JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg)
#ifdef JS_THREADSAFE
JS_ASSERT(cx->runtime->gcThread == trc->context->thread);
#endif
if (thing) {
JS_SET_TRACING_NAME(trc, name ? name : "unknown");
js_CallGCThingTracer(trc, thing);
}
JS_SET_TRACING_NAME(trc, name ? name : "unknown");
js_CallValueTracerIfGCThing(trc, (jsval)thing);
}
extern JS_PUBLIC_API(JSBool)

Просмотреть файл

@ -816,15 +816,7 @@ js_TraceLocalRoots(JSTracer *trc, JSLocalRootStack *lrs)
v = lrc->roots[m];
JS_ASSERT(JSVAL_IS_GCTHING(v) && v != JSVAL_NULL);
JS_SET_TRACING_INDEX(trc, "local_root", n);
/*
* When v is tagged as an object, it can be in fact an arbitrary
* GC thing so we have to use js_CallGCThingTracer on it.
*/
if (JSVAL_IS_OBJECT(v))
js_CallGCThingTracer(trc, JSVAL_TO_GCTHING(v));
else
JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
js_CallValueTracerIfGCThing(trc, v);
if (m == 0)
lrc = lrc->down;
}

Просмотреть файл

@ -2467,6 +2467,7 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
uint8 *flagp;
jsval v;
JS_ASSERT(thing);
JS_ASSERT(JS_IS_VALID_TRACE_KIND(kind));
JS_ASSERT(trc->debugPrinter || trc->debugPrintArg);
@ -2572,17 +2573,24 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind)
}
void
js_CallGCThingTracer(JSTracer *trc, void *thing)
js_CallValueTracerIfGCThing(JSTracer *trc, jsval v)
{
uint32 traceKind;
void *thing;
uint32 kind;
JS_ASSERT(thing != NULL);
traceKind = GCTypeToTraceKindMap[*js_GetGCThingFlags(thing) & GCF_TYPEMASK];
JS_CallTracer(trc, thing, traceKind);
if (JSVAL_IS_DOUBLE(v) || JSVAL_IS_STRING(v)) {
thing = JSVAL_TO_TRACEABLE(v);
kind = JSVAL_TRACE_KIND(v);
} else if (JSVAL_IS_OBJECT(v) && v != JSVAL_NULL) {
/* v can be an arbitrary GC thing reinterpreted as an object. */
thing = JSVAL_TO_OBJECT(v);
kind = GCTypeToTraceKindMap[*js_GetGCThingFlags(thing) & GCF_TYPEMASK];
} else {
return;
}
JS_CallTracer(trc, thing, kind);
}
JS_STATIC_DLL_CALLBACK(JSDHashOperator)
gc_root_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
void *arg)
@ -2623,7 +2631,7 @@ gc_root_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num,
JS_ASSERT(root_points_to_gcArenaList);
#endif
JS_SET_TRACING_NAME(trc, rhe->name ? rhe->name : "root");
js_CallGCThingTracer(trc, JSVAL_TO_GCTHING(v));
js_CallValueTracerIfGCThing(trc, v);
}
return JS_DHASH_NEXT;
@ -2763,12 +2771,15 @@ TraceWeakRoots(JSTracer *trc, JSWeakRoots *wr)
for (i = 0; i < GCX_NTYPES; i++) {
thing = wr->newborn[i];
if (thing)
JS_CALL_TRACER(trc, thing, GCTypeToTraceKindMap[i], gc_typenames[i]);
if (thing) {
JS_CALL_TRACER(trc, thing, GCTypeToTraceKindMap[i],
gc_typenames[i]);
}
}
if (wr->lastAtom)
JS_CALL_TRACER(trc, wr->lastAtom, JSTRACE_ATOM, "lastAtom");
JS_CALL_VALUE_TRACER(trc, wr->lastInternalResult, "lastInternalResult");
JS_SET_TRACING_NAME(trc, "lastInternalResult");
js_CallValueTracerIfGCThing(trc, wr->lastInternalResult);
}
JS_FRIEND_API(void)
@ -2777,7 +2788,6 @@ js_TraceContext(JSTracer *trc, JSContext *acx)
JSStackFrame *chain, *fp;
JSStackHeader *sh;
JSTempValueRooter *tvr;
jsval v;
/*
* Iterate frame chain and dormant chains. Temporarily tack current
@ -2830,21 +2840,8 @@ js_TraceContext(JSTracer *trc, JSContext *acx)
for (tvr = acx->tempValueRooters; tvr; tvr = tvr->down) {
switch (tvr->count) {
case JSTVU_SINGLE:
v = tvr->u.value;
if (JSVAL_IS_GCTHING(v) && v != JSVAL_NULL) {
/*
* When v is tagged as an object, it can be in fact an
* arbitrary GC thing so we have to use js_CallGCThingTracer
* on it.
*/
JS_SET_TRACING_NAME(trc, "tvr->u.value");
if (JSVAL_IS_OBJECT(v)) {
js_CallGCThingTracer(trc, JSVAL_TO_GCTHING(v));
} else {
JS_CallTracer(trc, JSVAL_TO_TRACEABLE(v),
JSVAL_TRACE_KIND(v));
}
}
JS_SET_TRACING_NAME(trc, "tvr->u.value");
js_CallValueTracerIfGCThing(trc, tvr->u.value);
break;
case JSTVU_TRACE:
tvr->u.trace(trc, tvr);

Просмотреть файл

@ -232,8 +232,13 @@ JS_STATIC_ASSERT(JSTRACE_STRING == 2);
# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_ATOM)
#endif
/*
* Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as
* JSVAL_OBJECT and js_GetGCThingFlags has to be used to find the real type
* behind v.
*/
extern void
js_CallGCThingTracer(JSTracer *trc, void *thing);
js_CallValueTracerIfGCThing(JSTracer *trc, jsval v);
extern void
js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp);

Просмотреть файл

@ -212,7 +212,8 @@ namespace_trace(JSTracer *trc, JSObject *obj)
JSXMLNamespace *ns;
ns = (JSXMLNamespace *) JS_GetPrivate(trc->context, obj);
JS_CALL_TRACER(trc, ns, JSTRACE_NAMESPACE, "private");
if (ns)
JS_CALL_TRACER(trc, ns, JSTRACE_NAMESPACE, "private");
}
static JSBool
@ -407,7 +408,8 @@ qname_trace(JSTracer *trc, JSObject *obj)
JSXMLQName *qn;
qn = (JSXMLQName *) JS_GetPrivate(trc->context, obj);
JS_CALL_TRACER(trc, qn, JSTRACE_QNAME, "private");
if (qn)
JS_CALL_TRACER(trc, qn, JSTRACE_QNAME, "private");
}
static JSBool
@ -1045,13 +1047,10 @@ XMLArrayCursorTrace(JSTracer *trc, JSXMLArrayCursor *cursor)
size_t index = 0;
#endif
while (cursor) {
for (; cursor; cursor = cursor->next) {
root = cursor->root;
if (root) {
JS_SET_TRACING_INDEX(trc, "cursor_root", index++);
js_CallGCThingTracer(trc, root);
}
cursor = cursor->next;
JS_SET_TRACING_INDEX(trc, "cursor_root", index++);
js_CallValueTracerIfGCThing(trc, (jsval)root);
}
}