зеркало из https://github.com/mozilla/gecko-dev.git
Related to bug 367779: fixin GC_MARK_DEBUG to work with xpcom cycle collector. r=brendan,peterv
This commit is contained in:
Родитель
ee0149b4ca
Коммит
2f32fe7f22
|
@ -1775,15 +1775,16 @@ JS_EXPORT_DATA(void *) js_LiveThingToFind;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GetObjSlotName(JSScope *scope, JSObject *obj, uint32 slot, char *buf,
|
GetObjSlotName(JSObject *obj, uint32 slot, char *buf, size_t bufsize)
|
||||||
size_t bufsize)
|
|
||||||
{
|
{
|
||||||
|
JSScope *scope;
|
||||||
jsval nval;
|
jsval nval;
|
||||||
JSScopeProperty *sprop;
|
JSScopeProperty *sprop;
|
||||||
JSClass *clasp;
|
JSClass *clasp;
|
||||||
uint32 key;
|
uint32 key;
|
||||||
const char *slotname;
|
const char *slotname;
|
||||||
|
|
||||||
|
scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL;
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
JS_snprintf(buf, bufsize, "**UNKNOWN OBJECT MAP ENTRY**");
|
JS_snprintf(buf, bufsize, "**UNKNOWN OBJECT MAP ENTRY**");
|
||||||
return;
|
return;
|
||||||
|
@ -2038,16 +2039,14 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
jsval v;
|
jsval v;
|
||||||
uint32 i, end;
|
uint32 i, end;
|
||||||
|
#ifndef GC_MARK_DEBUG
|
||||||
void *next_thing;
|
void *next_thing;
|
||||||
uint8 *next_flagp;
|
uint8 *next_flagp;
|
||||||
|
#endif
|
||||||
JSString *str;
|
JSString *str;
|
||||||
#ifdef JS_GCMETER
|
#ifdef JS_GCMETER
|
||||||
uint32 tailCallNesting;
|
uint32 tailCallNesting;
|
||||||
#endif
|
#endif
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
JSScope *scope;
|
|
||||||
char name[32];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* With JS_GC_ASSUME_LOW_C_STACK defined the mark phase of GC always
|
* With JS_GC_ASSUME_LOW_C_STACK defined the mark phase of GC always
|
||||||
|
@ -2095,13 +2094,22 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
: LOCKED_OBJ_NSLOTS(obj);
|
: LOCKED_OBJ_NSLOTS(obj);
|
||||||
thing = NULL;
|
thing = NULL;
|
||||||
flagp = NULL;
|
flagp = NULL;
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL;
|
|
||||||
#endif
|
|
||||||
for (i = 0; i != end; ++i) {
|
for (i = 0; i != end; ++i) {
|
||||||
v = STOBJ_GET_SLOT(obj, i);
|
v = STOBJ_GET_SLOT(obj, i);
|
||||||
if (!JSVAL_IS_GCTHING(v) || v == JSVAL_NULL)
|
if (!JSVAL_IS_GCTHING(v) || v == JSVAL_NULL)
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef GC_MARK_DEBUG
|
||||||
|
/*
|
||||||
|
* Do not inline GC_MARK or eliminate tail recursion when
|
||||||
|
* debugging to allow js_MarkNamedGCThing to build a full
|
||||||
|
* dump of live GC things.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char name[32];
|
||||||
|
GetObjSlotName(obj, i, name, sizeof name);
|
||||||
|
GC_MARK(cx, JSVAL_TO_GCTHING(v), name);
|
||||||
|
}
|
||||||
|
#else
|
||||||
next_thing = JSVAL_TO_GCTHING(v);
|
next_thing = JSVAL_TO_GCTHING(v);
|
||||||
next_flagp = js_GetGCThingFlags(next_thing);
|
next_flagp = js_GetGCThingFlags(next_thing);
|
||||||
if (rt->gcThingCallback) {
|
if (rt->gcThingCallback) {
|
||||||
|
@ -2114,12 +2122,8 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
continue;
|
continue;
|
||||||
JS_ASSERT(*next_flagp != GCF_FINAL);
|
JS_ASSERT(*next_flagp != GCF_FINAL);
|
||||||
if (thing) {
|
if (thing) {
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
GC_MARK(cx, thing, name);
|
|
||||||
#else
|
|
||||||
*flagp |= GCF_MARK;
|
*flagp |= GCF_MARK;
|
||||||
MarkGCThingChildren(cx, thing, flagp, JS_TRUE);
|
MarkGCThingChildren(cx, thing, flagp, JS_TRUE);
|
||||||
#endif
|
|
||||||
if (*next_flagp & GCF_MARK) {
|
if (*next_flagp & GCF_MARK) {
|
||||||
/*
|
/*
|
||||||
* This happens when recursive MarkGCThingChildren marks
|
* This happens when recursive MarkGCThingChildren marks
|
||||||
|
@ -2129,9 +2133,6 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
GetObjSlotName(scope, obj, i, name, sizeof name);
|
|
||||||
#endif
|
|
||||||
thing = next_thing;
|
thing = next_thing;
|
||||||
flagp = next_flagp;
|
flagp = next_flagp;
|
||||||
}
|
}
|
||||||
|
@ -2146,6 +2147,7 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
*/
|
*/
|
||||||
shouldCheckRecursion = JS_FALSE;
|
shouldCheckRecursion = JS_FALSE;
|
||||||
goto on_tail_recursion;
|
goto on_tail_recursion;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2161,6 +2163,10 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
if (!JSSTRING_IS_DEPENDENT(str))
|
if (!JSSTRING_IS_DEPENDENT(str))
|
||||||
break;
|
break;
|
||||||
thing = JSSTRDEP_BASE(str);
|
thing = JSSTRDEP_BASE(str);
|
||||||
|
#ifdef GC_MARK_DEBUG
|
||||||
|
GC_MARK(cx, thing, "base");
|
||||||
|
break;
|
||||||
|
#else
|
||||||
flagp = js_GetGCThingFlags(thing);
|
flagp = js_GetGCThingFlags(thing);
|
||||||
if (rt->gcThingCallback) {
|
if (rt->gcThingCallback) {
|
||||||
rt->gcThingCallback(thing, *flagp,
|
rt->gcThingCallback(thing, *flagp,
|
||||||
|
@ -2168,21 +2174,10 @@ MarkGCThingChildren(JSContext *cx, void *thing, uint8 *flagp,
|
||||||
}
|
}
|
||||||
if (*flagp & GCF_MARK)
|
if (*flagp & GCF_MARK)
|
||||||
break;
|
break;
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
strcpy(name, "base");
|
|
||||||
#endif
|
|
||||||
/* Fallthrough to code to deal with the tail recursion. */
|
/* Fallthrough to code to deal with the tail recursion. */
|
||||||
|
|
||||||
on_tail_recursion:
|
on_tail_recursion:
|
||||||
#ifdef GC_MARK_DEBUG
|
|
||||||
/*
|
|
||||||
* Do not eliminate C recursion when debugging to allow
|
|
||||||
* js_MarkNamedGCThing to build a full dump of live GC
|
|
||||||
* things.
|
|
||||||
*/
|
|
||||||
GC_MARK(cx, thing, name);
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
/* Eliminate tail recursion for the last unmarked child. */
|
/* Eliminate tail recursion for the last unmarked child. */
|
||||||
JS_ASSERT(*flagp != GCF_FINAL);
|
JS_ASSERT(*flagp != GCF_FINAL);
|
||||||
METER(++tailCallNesting);
|
METER(++tailCallNesting);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче