diff --git a/js/src/jsapi.c b/js/src/jsapi.c index 0bbcb1a780b..b93eced059a 100644 --- a/js/src/jsapi.c +++ b/js/src/jsapi.c @@ -1518,6 +1518,7 @@ JS_ClearNewbornRoots(JSContext *cx) for (i = 0; i < GCX_NTYPES; i++) cx->newborn[i] = NULL; + cx->lastAtom = NULL; } #include "jshash.h" /* Added by JSIFY */ diff --git a/js/src/jsatom.c b/js/src/jsatom.c index 0faecfc5262..8467e3d811a 100644 --- a/js/src/jsatom.c +++ b/js/src/jsatom.c @@ -459,6 +459,7 @@ js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags) atom = (JSAtom *)he; atom->flags |= flags; + cx->lastAtom = atom; out: JS_UNLOCK(&state->lock,cx); return atom; @@ -549,6 +550,7 @@ js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags) atom = (JSAtom *)he; atom->flags |= flags; + cx->lastAtom = atom; out: JS_UNLOCK(&state->lock,cx); return atom; @@ -611,6 +613,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) atom = (JSAtom *)he; atom->flags |= flags & (ATOM_PINNED | ATOM_INTERNED); + cx->lastAtom = atom; out: JS_UNLOCK(&state->lock,cx); return atom; diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index ea07ddd95ad..6be3cadfc28 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -317,6 +317,9 @@ struct JSContext { /* Most recently created things by type, members of the GC's root set. */ JSGCThing *newborn[GCX_NTYPES]; + /* Atom root for the last-looked-up atom on this context. */ + JSAtom *lastAtom; + /* Regular expression class statics (XXX not shared globally). */ JSRegExpStatics regExpStatics; diff --git a/js/src/jsgc.c b/js/src/jsgc.c index 5420f25f8bb..b034c6ba093 100644 --- a/js/src/jsgc.c +++ b/js/src/jsgc.c @@ -759,7 +759,7 @@ gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp) ? NULL : JSVAL_TO_PRIVATE(privateValue); const char *className = gc_object_class_name(thing); - fprintf(fp, "object %08p %s", privateThing, className); + fprintf(fp, "object %8p %s", privateThing, className); break; } case GCX_DOUBLE: @@ -989,6 +989,7 @@ js_ForceGC(JSContext *cx, uintN gcflags) for (i = 0; i < GCX_NTYPES; i++) cx->newborn[i] = NULL; + cx->lastAtom = NULL; cx->runtime->gcPoke = JS_TRUE; js_GC(cx, gcflags); JS_ArenaFinish(); @@ -1261,6 +1262,8 @@ restart: NULL); for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) GC_MARK(cx, acx->newborn[i], "newborn external string", NULL); + if (acx->lastAtom) + GC_MARK_ATOM(cx, acx->lastAtom, NULL); #if JS_HAS_EXCEPTIONS if (acx->throwing && JSVAL_IS_GCTHING(acx->exception)) GC_MARK(cx, JSVAL_TO_GCTHING(acx->exception), "exception", NULL);