Check (without regressing hot paths) where needed to avoid treating static JSStrings like gc-things in the heap (514819, r=gal).

This commit is contained in:
Brendan Eich
2009-09-05 21:48:30 -07:00
parent 17b148b4e5
commit b9b1ae41a2
6 changed files with 58 additions and 17 deletions

View File

@@ -671,12 +671,38 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
if (str->length() == 1) {
if (str->isAtomized())
return (JSAtom *) STRING_TO_JSVAL(str);
size_t length = str->length();
if (length == 1) {
jschar c = str->chars()[0];
if (c < UNIT_STRING_LIMIT)
return (JSAtom *) STRING_TO_JSVAL(JSString::unitString(c));
}
/*
* Here we know that JSString::intStringTable covers only 256 (or at least
* not 1000 or more) chars. We rely on order here to resolve the unit vs.
* int string atom identity issue by giving priority to unit strings for
* '0' through '9' (see JSString::intString in jsstrinlines.h).
*/
JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
if (2 <= length && length <= 3) {
const jschar *chars = str->chars();
if ('0' <= chars[0] && chars[0] <= '9' &&
'0' <= chars[1] && chars[1] <= '9' &&
(length == 2 || ('0' <= chars[2] && chars[2] <= '9'))) {
jsint i = (chars[0] - '0') * 10 + chars[1] - '0';
if (length == 3)
i = i * 10 + chars[2] - '0';
if (jsuint(i) < INT_STRING_LIMIT)
return (JSAtom *) STRING_TO_JSVAL(JSString::intString(i));
}
}
state = &cx->runtime->atomState;
table = &state->stringAtoms;