From f5c41293a59d294c23fc7df4668eb320b5a93970 Mon Sep 17 00:00:00 2001 From: Brendan Eich Date: Fri, 21 Aug 2009 17:28:05 -0700 Subject: [PATCH] Unit strings not in atom table means we must always mark them unless shutting down the runtime (511835, r=gal). --- js/src/jsatom.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index d8e689a26b2..ab6223d5d0f 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -559,15 +559,30 @@ js_pinned_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr, void js_TraceAtomState(JSTracer *trc, JSBool allAtoms) { - JSAtomState *state; + JSRuntime *rt = trc->context->runtime; + JSAtomState *state = &rt->atomState; - state = &trc->context->runtime->atomState; if (allAtoms) { JS_DHashTableEnumerate(&state->doubleAtoms, js_locked_atom_tracer, trc); JS_DHashTableEnumerate(&state->stringAtoms, js_locked_atom_tracer, trc); } else { JS_DHashTableEnumerate(&state->stringAtoms, js_pinned_atom_tracer, trc); } + + if (rt->state != JSRTS_LANDING) { + /* + * Unit strings aren't in state->stringAtoms, so we mark any that have + * been created on demand. This bloats more than strictly necessary but + * we can't help that without putting unit atoms in state->stringAtoms, + * which is too expensive. + */ + for (uintN i = 0; i < UNIT_STRING_LIMIT; i++) { + if (JSString *str = rt->unitStrings[i]) { + JS_SET_TRACING_INDEX(trc, "unit_string_atom", i); + JS_CallTracer(trc, str, JSTRACE_STRING); + } + } + } } static JSDHashOperator @@ -675,8 +690,10 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) if (str->length() == 1) { jschar c = str->chars()[0]; - if (c < UNIT_STRING_LIMIT) - return (JSAtom*) STRING_TO_JSVAL(js_GetUnitStringForChar(cx, c)); + if (c < UNIT_STRING_LIMIT) { + JSString *str = js_GetUnitStringForChar(cx, c); + return str ? (JSAtom *) STRING_TO_JSVAL(str) : NULL; + } } state = &cx->runtime->atomState;