Back out bug 654301 to run again on try.

This commit is contained in:
Chris Leary 2011-05-16 19:03:20 -07:00
Родитель 3eeecbe192
Коммит 441defa1f8
39 изменённых файлов: 290 добавлений и 401 удалений

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

@ -3427,7 +3427,7 @@ nsresult nsScriptSecurityManager::Init()
::JS_BeginRequest(cx); ::JS_BeginRequest(cx);
if (sEnabledID == JSID_VOID) if (sEnabledID == JSID_VOID)
sEnabledID = INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "enabled")); sEnabledID = INTERNED_STRING_TO_JSID(::JS_InternString(cx, "enabled"));
::JS_EndRequest(cx); ::JS_EndRequest(cx);
InitPrefs(); InitPrefs();

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

@ -908,7 +908,7 @@ nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *aContext,
if (sAddListenerID == JSID_VOID) { if (sAddListenerID == JSID_VOID) {
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
sAddListenerID = sAddListenerID =
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "addEventListener")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "addEventListener"));
} }
if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) { if (aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) {

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

@ -3322,7 +3322,7 @@ nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
if (aPaste) { if (aPaste) {
if (nsHTMLDocument::sPasteInternal_id == JSID_VOID) { if (nsHTMLDocument::sPasteInternal_id == JSID_VOID) {
nsHTMLDocument::sPasteInternal_id = nsHTMLDocument::sPasteInternal_id =
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "paste")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "paste"));
} }
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(), rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
nsHTMLDocument::sPasteInternal_id, nsHTMLDocument::sPasteInternal_id,
@ -3330,7 +3330,7 @@ nsHTMLDocument::DoClipboardSecurityCheck(PRBool aPaste)
} else { } else {
if (nsHTMLDocument::sCutCopyInternal_id == JSID_VOID) { if (nsHTMLDocument::sCutCopyInternal_id == JSID_VOID) {
nsHTMLDocument::sCutCopyInternal_id = nsHTMLDocument::sCutCopyInternal_id =
INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "cutcopy")); INTERNED_STRING_TO_JSID(::JS_InternString(cx, "cutcopy"));
} }
rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(), rv = secMan->CheckPropertyAccess(cx, nsnull, classNameStr.get(),
nsHTMLDocument::sCutCopyInternal_id, nsHTMLDocument::sCutCopyInternal_id,

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

@ -985,7 +985,7 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
return PR_FALSE; return PR_FALSE;
} }
id = StringToNPIdentifier(cx, str); id = StringToNPIdentifier(str);
} else { } else {
NS_ASSERTION(JSVAL_IS_INT(v), NS_ASSERTION(JSVAL_IS_INT(v),
"The element in ida must be either string or int!\n"); "The element in ida must be either string or int!\n");
@ -1473,8 +1473,8 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
if (npobj->_class->invoke) { if (npobj->_class->invoke) {
JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj); JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
JSString *name = ::JS_InternJSString(cx, ::JS_GetFunctionId(fun)); JSString *name = ::JS_GetFunctionId(fun);
NPIdentifier id = StringToNPIdentifier(cx, name); NPIdentifier id = StringToNPIdentifier(name);
ok = npobj->_class->invoke(npobj, id, npargs, argc, &v); ok = npobj->_class->invoke(npobj, id, npargs, argc, &v);
} else { } else {

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

@ -144,9 +144,9 @@ NPIdentifierToString(NPIdentifier id)
} }
static inline NPIdentifier static inline NPIdentifier
StringToNPIdentifier(JSContext *cx, JSString *str) StringToNPIdentifier(JSString *str)
{ {
return JSIdToNPIdentifier(INTERNED_STRING_TO_JSID(cx, str)); return JSIdToNPIdentifier(INTERNED_STRING_TO_JSID(str));
} }
static inline bool static inline bool

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

@ -63,7 +63,6 @@ CPPSRCS = \
testGCChunkAlloc.cpp \ testGCChunkAlloc.cpp \
testGetPropertyDefault.cpp \ testGetPropertyDefault.cpp \
testIntString.cpp \ testIntString.cpp \
testIntern.cpp \
testLookup.cpp \ testLookup.cpp \
testLooselyEqual.cpp \ testLooselyEqual.cpp \
testNewObject.cpp \ testNewObject.cpp \

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

@ -1,40 +0,0 @@
#include "tests.h"
#include "jsatom.h"
BEGIN_TEST(testAtomizedIsNotInterned)
{
/* Try to pick a string that won't be interned by other tests in this runtime. */
static const char someChars[] = "blah blah blah? blah blah blah";
JSAtom *atom = js_Atomize(cx, someChars, JS_ARRAY_LENGTH(someChars));
CHECK(!JS_StringHasBeenInterned(cx, atom));
CHECK(JS_InternJSString(cx, atom));
CHECK(JS_StringHasBeenInterned(cx, atom));
return true;
}
END_TEST(testAtomizedIsNotInterned)
struct StringWrapper
{
JSString *str;
bool strOk;
} sw;
JSBool
GCCallback(JSContext *cx, JSGCStatus status)
{
if (status == JSGC_MARK_END)
sw.strOk = !JS_IsAboutToBeFinalized(cx, sw.str);
return true;
}
BEGIN_TEST(testInternAcrossGC)
{
sw.str = JS_InternString(cx, "wrapped chars that another test shouldn't be using");
sw.strOk = false;
CHECK(sw.str);
JS_SetGCCallback(cx, GCCallback);
JS_GC(cx);
CHECK(sw.strOk);
return true;
}
END_TEST(testInternAcrossGC)

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

@ -14,7 +14,7 @@ BEGIN_TEST(testStringBuffer_finishString)
JSString *str = JS_NewStringCopyZ(cx, "foopy"); JSString *str = JS_NewStringCopyZ(cx, "foopy");
CHECK(str); CHECK(str);
JSAtom *atom = js_AtomizeString(cx, str); JSAtom *atom = js_AtomizeString(cx, str, 0);
CHECK(atom); CHECK(atom);
js::StringBuffer buffer(cx); js::StringBuffer buffer(cx);

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

@ -1574,7 +1574,7 @@ StdNameToAtom(JSContext *cx, JSStdName *stdn)
if (!atom) { if (!atom) {
name = stdn->name; name = stdn->name;
if (name) { if (name) {
atom = js_Atomize(cx, name, strlen(name), InternAtom); atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED);
OFFSET_TO_ATOM(cx->runtime, offset) = atom; OFFSET_TO_ATOM(cx->runtime, offset) = atom;
} }
} }
@ -3236,14 +3236,14 @@ JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_LookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp) JS_LookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
@ -3266,7 +3266,7 @@ JS_PUBLIC_API(JSBool)
JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, uintN flags, jsval *vp) JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, uintN flags, jsval *vp)
{ {
JSObject *obj2; JSObject *obj2;
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_LookupPropertyWithFlagsById(cx, obj, ATOM_TO_JSID(atom), flags, &obj2, vp); return atom && JS_LookupPropertyWithFlagsById(cx, obj, ATOM_TO_JSID(atom), flags, &obj2, vp);
} }
@ -3290,14 +3290,14 @@ JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp) JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp); return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_HasUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSBool *foundp) JS_HasUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSBool *foundp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp); return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
} }
@ -3332,7 +3332,7 @@ JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, JSBool *found
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp) JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp); return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
} }
@ -3340,7 +3340,7 @@ JS_PUBLIC_API(JSBool)
JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
JSBool *foundp) JSBool *foundp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp); return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
} }
@ -3395,7 +3395,7 @@ DefineProperty(JSContext *cx, JSObject *obj, const char *name, const Value &valu
atom = NULL; atom = NULL;
attrs &= ~JSPROP_INDEX; attrs &= ~JSPROP_INDEX;
} else { } else {
atom = js_Atomize(cx, name, strlen(name)); atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
id = ATOM_TO_JSID(atom); id = ATOM_TO_JSID(atom);
@ -3424,7 +3424,7 @@ DefineUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namele
const Value &value, PropertyOp getter, StrictPropertyOp setter, uintN attrs, const Value &value, PropertyOp getter, StrictPropertyOp setter, uintN attrs,
uintN flags, intN tinyid) uintN flags, intN tinyid)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && DefinePropertyById(cx, obj, ATOM_TO_JSID(atom), value, getter, setter, attrs, return atom && DefinePropertyById(cx, obj, ATOM_TO_JSID(atom), value, getter, setter, attrs,
flags, tinyid); flags, tinyid);
} }
@ -3522,7 +3522,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, const char *ali
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); assertSameCompartment(cx, obj);
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop)) if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop))
@ -3536,7 +3536,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, const char *ali
alias, name, obj2->getClass()->name); alias, name, obj2->getClass()->name);
return JS_FALSE; return JS_FALSE;
} }
atom = js_Atomize(cx, alias, strlen(alias)); atom = js_Atomize(cx, alias, strlen(alias), 0);
if (!atom) { if (!atom) {
ok = JS_FALSE; ok = JS_FALSE;
} else { } else {
@ -3560,7 +3560,7 @@ JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); assertSameCompartment(cx, obj);
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop)) if (!LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), JSRESOLVE_QUALIFIED, &obj2, &prop))
@ -3665,7 +3665,7 @@ JS_PUBLIC_API(JSBool)
JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
uintN *attrsp, JSBool *foundp) uintN *attrsp, JSBool *foundp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom), return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
attrsp, foundp, NULL, NULL); attrsp, foundp, NULL, NULL);
} }
@ -3674,7 +3674,7 @@ JS_PUBLIC_API(JSBool)
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
uintN *attrsp, JSBool *foundp) uintN *attrsp, JSBool *foundp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom), return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
attrsp, foundp, NULL, NULL); attrsp, foundp, NULL, NULL);
} }
@ -3684,7 +3684,7 @@ JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, const char *nam
uintN *attrsp, JSBool *foundp, uintN *attrsp, JSBool *foundp,
JSPropertyOp *getterp, JSStrictPropertyOp *setterp) JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom), return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
attrsp, foundp, getterp, setterp); attrsp, foundp, getterp, setterp);
} }
@ -3695,7 +3695,7 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
uintN *attrsp, JSBool *foundp, uintN *attrsp, JSBool *foundp,
JSPropertyOp *getterp, JSStrictPropertyOp *setterp) JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom), return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
attrsp, foundp, getterp, setterp); attrsp, foundp, getterp, setterp);
} }
@ -3731,7 +3731,7 @@ JS_PUBLIC_API(JSBool)
JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
uintN attrs, JSBool *foundp) uintN attrs, JSBool *foundp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp); return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
} }
@ -3739,7 +3739,7 @@ JS_PUBLIC_API(JSBool)
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
uintN attrs, JSBool *foundp) uintN attrs, JSBool *foundp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp); return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
} }
@ -3767,21 +3767,21 @@ JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp) JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp); return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_GetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp) JS_GetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
@ -3800,7 +3800,7 @@ JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, jsval *
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp) JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp); return atom && JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp);
} }
@ -3822,14 +3822,14 @@ JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_SetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp) JS_SetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp); return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
} }
@ -3851,14 +3851,14 @@ JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, jsval *rval) JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, jsval *rval)
{ {
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval); return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *rval) JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *rval)
{ {
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval); return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
} }
@ -4188,7 +4188,7 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
if (!name) { if (!name) {
atom = NULL; atom = NULL;
} else { } else {
atom = js_Atomize(cx, name, strlen(name)); atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return NULL; return NULL;
} }
@ -4397,7 +4397,7 @@ JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); assertSameCompartment(cx, obj);
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return NULL; return NULL;
return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs); return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs);
@ -4411,7 +4411,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj,
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); assertSameCompartment(cx, obj);
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
if (!atom) if (!atom)
return NULL; return NULL;
return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs); return js_DefineFunction(cx, obj, ATOM_TO_JSID(atom), Valueify(call), nargs, attrs);
@ -4737,7 +4737,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
if (!name) { if (!name) {
funAtom = NULL; funAtom = NULL;
} else { } else {
funAtom = js_Atomize(cx, name, strlen(name)); funAtom = js_Atomize(cx, name, strlen(name), 0);
if (!funAtom) { if (!funAtom) {
fun = NULL; fun = NULL;
goto out2; goto out2;
@ -4762,7 +4762,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
Bindings bindings(cx, emptyCallShape); Bindings bindings(cx, emptyCallShape);
AutoBindingsRooter root(cx, bindings); AutoBindingsRooter root(cx, bindings);
for (i = 0; i < nargs; i++) { for (i = 0; i < nargs; i++) {
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i])); argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
if (!argAtom) { if (!argAtom) {
fun = NULL; fun = NULL;
goto out2; goto out2;
@ -5059,7 +5059,7 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
assertSameCompartment(cx, obj, JSValueArray(argv, argc)); assertSameCompartment(cx, obj, JSValueArray(argv, argc));
AutoValueRooter tvr(cx); AutoValueRooter tvr(cx);
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
JSBool ok = JSBool ok =
atom && atom &&
js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) && js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) &&
@ -5245,32 +5245,23 @@ JS_NewStringCopyZ(JSContext *cx, const char *s)
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_StringHasBeenInterned(JSContext *cx, JSString *str) JS_StringHasBeenInterned(JSString *str)
{ {
CHECK_REQUEST(cx); return str->isAtom();
if (!str->isAtom())
return false;
return AtomIsInterned(cx, &str->asAtom());
} }
JS_PUBLIC_API(JSString *) JS_PUBLIC_API(JSString *)
JS_InternJSString(JSContext *cx, JSString *str) JS_InternJSString(JSContext *cx, JSString *str)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
JSAtom *atom = js_AtomizeString(cx, str, InternAtom); return js_AtomizeString(cx, str, 0);
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
return atom;
} }
JS_PUBLIC_API(JSString *) JS_PUBLIC_API(JSString *)
JS_InternString(JSContext *cx, const char *s) JS_InternString(JSContext *cx, const char *s)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
JSAtom *atom = js_Atomize(cx, s, strlen(s), InternAtom); return js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
return atom;
} }
JS_PUBLIC_API(JSString *) JS_PUBLIC_API(JSString *)
@ -5300,9 +5291,7 @@ JS_PUBLIC_API(JSString *)
JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length) JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
{ {
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
JSAtom *atom = js_AtomizeChars(cx, s, length, InternAtom); return js_AtomizeChars(cx, s, length, ATOM_INTERNED);
JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
return atom;
} }
JS_PUBLIC_API(JSString *) JS_PUBLIC_API(JSString *)

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

@ -333,22 +333,16 @@ JSID_IS_ZERO(jsid id)
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_StringHasBeenInterned(JSContext *cx, JSString *str); JS_StringHasBeenInterned(JSString *str);
/* /* A jsid may only hold an interned JSString. */
* Only JSStrings that have been interned via the JSAPI can be turned into
* jsids by API clients.
*
* N.B. if a jsid is backed by a string which has not been interned, that
* string must be appropriately rooted to avoid being collected by the GC.
*/
static JS_ALWAYS_INLINE jsid static JS_ALWAYS_INLINE jsid
INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str) INTERNED_STRING_TO_JSID(JSString *str)
{ {
jsid id; jsid id;
JS_ASSERT(str); JS_ASSERT(str);
JS_ASSERT(JS_StringHasBeenInterned(str));
JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0); JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
JS_ASSERT(JS_StringHasBeenInterned(cx, str));
JSID_BITS(id) = (size_t)str; JSID_BITS(id) = (size_t)str;
return id; return id;
} }

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

@ -164,6 +164,7 @@ struct JSArenaPool {
(JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base)) (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
#ifdef DEBUG #ifdef DEBUG
#define JS_FREE_PATTERN 0xDA
#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ #define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
memset((void*)(a)->avail, JS_FREE_PATTERN, \ memset((void*)(a)->avail, JS_FREE_PATTERN, \
(a)->limit - (a)->avail)) (a)->limit - (a)->avail))

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

@ -278,7 +278,7 @@ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
return JS_TRUE; return JS_TRUE;
} }
} else { } else {
atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start); atom = js_AtomizeChars(cx, start, JS_ARRAY_END(buf) - start, 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
} }

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

@ -67,15 +67,28 @@
using namespace js; using namespace js;
using namespace js::gc; using namespace js::gc;
const size_t JSAtomState::commonAtomsOffset = offsetof(JSAtomState, emptyAtom);
const size_t JSAtomState::lazyAtomsOffset = offsetof(JSAtomState, lazy);
/* /*
* ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems. * ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.
*/ */
JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4); JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD); JS_STATIC_ASSERT(sizeof(JSAtom *) == JS_BYTES_PER_WORD);
/*
* Start and limit offsets for atom pointers in JSAtomState must be aligned
* on the word boundary.
*/
JS_STATIC_ASSERT(ATOM_OFFSET_START % sizeof(JSAtom *) == 0);
JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT % sizeof(JSAtom *) == 0);
/*
* JS_BOOLEAN_STR and JS_TYPE_STR assume that boolean names starts from the
* index 1 and type name starts from the index 1+2 atoms in JSAtomState.
*/
JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
offsetof(JSAtomState, booleanAtoms) - ATOM_OFFSET_START);
JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
offsetof(JSAtomState, typeAtoms) - ATOM_OFFSET_START);
const char * const char *
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes) js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
{ {
@ -204,28 +217,8 @@ const char *const js_common_atom_names[] = {
"WeakMap" /* WeakMapAtom */ "WeakMap" /* WeakMapAtom */
}; };
void JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
JSAtomState::checkStaticInvariants() LAZY_ATOM_OFFSET_START - ATOM_OFFSET_START);
{
/*
* Start and limit offsets for atom pointers in JSAtomState must be aligned
* on the word boundary.
*/
JS_STATIC_ASSERT(commonAtomsOffset % sizeof(JSAtom *) == 0);
JS_STATIC_ASSERT(sizeof(*this) % sizeof(JSAtom *) == 0);
/*
* JS_BOOLEAN_STR and JS_TYPE_STR assume that boolean names starts from the
* index 1 and type name starts from the index 1+2 atoms in JSAtomState.
*/
JS_STATIC_ASSERT(1 * sizeof(JSAtom *) ==
offsetof(JSAtomState, booleanAtoms) - commonAtomsOffset);
JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
offsetof(JSAtomState, typeAtoms) - commonAtomsOffset);
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
lazyAtomsOffset - commonAtomsOffset);
}
/* /*
* Interpreter macros called by the trace recorder assume common atom indexes * Interpreter macros called by the trace recorder assume common atom indexes
@ -302,6 +295,40 @@ const char js_close_str[] = "close";
const char js_send_str[] = "send"; const char js_send_str[] = "send";
#endif #endif
/*
* Helper macros to access and modify JSAtomHashEntry.
*/
inline AtomEntryType
StringToInitialAtomEntry(JSString *str)
{
return (AtomEntryType) str;
}
inline uintN
AtomEntryFlags(AtomEntryType entry)
{
return (uintN) (entry & ATOM_ENTRY_FLAG_MASK);
}
/*
* Conceptually, we have compressed a HashMap<JSAtom *, uint> into a
* HashMap<size_t>. Here, we promise that we are only changing the "value" of
* the HashMap entry, so the const_cast is safe.
*/
inline void
AddAtomEntryFlags(const AtomEntryType &entry, uintN flags)
{
const_cast<AtomEntryType &>(entry) |= AtomEntryType(flags);
}
inline void
ClearAtomEntryFlags(const AtomEntryType &entry, uintN flags)
{
const_cast<AtomEntryType &>(entry) &= ~AtomEntryType(flags);
}
/* /*
* For a browser build from 2007-08-09 after the browser starts up there are * For a browser build from 2007-08-09 after the browser starts up there are
* just 55 double atoms, but over 15000 string atoms. Not to penalize more * just 55 double atoms, but over 15000 string atoms. Not to penalize more
@ -340,35 +367,47 @@ js_FinishAtomState(JSRuntime *rt)
} }
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
r.front().toAtom()->finalize(rt); AtomEntryToKey(r.front())->finalize(rt);
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
js_FinishLock(&state->lock); js_FinishLock(&state->lock);
#endif #endif
} }
bool JSBool
js_InitCommonAtoms(JSContext *cx) js_InitCommonAtoms(JSContext *cx)
{ {
JSAtomState *state = &cx->runtime->atomState; JSAtomState *state = &cx->runtime->atomState;
JSAtom **atoms = state->commonAtomsStart(); uintN i;
for (size_t i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) { JSAtom **atoms;
*atoms = js_Atomize(cx, js_common_atom_names[i], strlen(js_common_atom_names[i]),
InternAtom); atoms = COMMON_ATOMS_START(state);
if (!*atoms) for (i = 0; i < JS_ARRAY_LENGTH(js_common_atom_names); i++, atoms++) {
return false; *atoms = js_Atomize(cx, js_common_atom_names[i],
} strlen(js_common_atom_names[i]), ATOM_PINNED);
if (!*atoms)
return JS_FALSE;
}
JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
memset(atoms, 0, ATOM_OFFSET_LIMIT - LAZY_ATOM_OFFSET_START);
state->clearLazyAtoms();
cx->runtime->emptyString = state->emptyAtom; cx->runtime->emptyString = state->emptyAtom;
return true; return JS_TRUE;
} }
void void
js_FinishCommonAtoms(JSContext *cx) js_FinishCommonAtoms(JSContext *cx)
{ {
cx->runtime->emptyString = NULL; cx->runtime->emptyString = NULL;
cx->runtime->atomState.junkAtoms(); JSAtomState *state = &cx->runtime->atomState;
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
ClearAtomEntryFlags(r.front(), ATOM_PINNED);
#ifdef DEBUG
memset(COMMON_ATOMS_START(state), JS_FREE_PATTERN,
ATOM_OFFSET_LIMIT - ATOM_OFFSET_START);
#endif
} }
void void
@ -384,16 +423,20 @@ js_TraceAtomState(JSTracer *trc)
if (rt->gcKeepAtoms) { if (rt->gcKeepAtoms) {
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) { for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
JS_SET_TRACING_INDEX(trc, "locked_atom", number++); JS_SET_TRACING_INDEX(trc, "locked_atom", number++);
MarkString(trc, r.front().toAtom()); MarkString(trc, AtomEntryToKey(r.front()));
} }
} else { } else {
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) { for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
AtomStateEntry entry = r.front(); AtomEntryType entry = r.front();
if (!entry.isInterned()) uintN flags = AtomEntryFlags(entry);
continue; if (flags & (ATOM_PINNED | ATOM_INTERNED)) {
JS_SET_TRACING_INDEX(trc,
JS_SET_TRACING_INDEX(trc, "interned_atom", number++); flags & ATOM_PINNED
MarkString(trc, entry.toAtom()); ? "pinned_atom"
: "interned_atom",
number++);
MarkString(trc, AtomEntryToKey(entry));
}
} }
} }
} }
@ -404,66 +447,26 @@ js_SweepAtomState(JSContext *cx)
JSAtomState *state = &cx->runtime->atomState; JSAtomState *state = &cx->runtime->atomState;
for (AtomSet::Enum e(state->atoms); !e.empty(); e.popFront()) { for (AtomSet::Enum e(state->atoms); !e.empty(); e.popFront()) {
AtomStateEntry entry = e.front(); AtomEntryType entry = e.front();
if (AtomEntryFlags(entry) & (ATOM_PINNED | ATOM_INTERNED)) {
if (entry.isInterned()) {
/* Pinned or interned key cannot be finalized. */ /* Pinned or interned key cannot be finalized. */
JS_ASSERT(!IsAboutToBeFinalized(cx, entry.toAtom())); JS_ASSERT(!IsAboutToBeFinalized(cx, AtomEntryToKey(entry)));
continue; } else if (IsAboutToBeFinalized(cx, AtomEntryToKey(entry))) {
}
if (IsAboutToBeFinalized(cx, entry.toAtom()))
e.removeFront(); e.removeFront();
}
} }
} }
bool
AtomIsInterned(JSContext *cx, JSAtom *atom)
{
if (atom->isStaticAtom())
return true;
AutoLockAtomsCompartment lock(cx);
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(atom);
if (!p)
return false;
return p->isInterned();
}
/* /*
* This call takes ownership of 'chars' if ATOM_NOCOPY is set. * Callers passing ATOM_NOCOPY have freshly allocated *pchars and thus this
* Non-branching code sequence to put the intern flag on |entryRef| if
* |intern| is true.
*
* Conceptually, we have compressed a HashMap<JSAtom *, uint> into a
* HashMap<size_t>. Here, we promise that we are only changing the "value" of
* the HashMap entry, so the const_cast is safe.
*/
static void
MakeInterned(const AutoLockAtomsCompartment &, const AtomStateEntry &entryRef, InternBehavior ib)
{
AtomStateEntry *entry = const_cast<AtomStateEntry *>(&entryRef);
AtomStateEntry::makeInterned(entry, ib);
JS_ASSERT(entryRef.isInterned() >= ib);
}
enum OwnCharsBehavior
{
CopyChars, /* in other words, do not take ownership */
TakeCharOwnership
};
/*
* Callers passing OwnChars have freshly allocated *pchars and thus this
* memory can be used as a new JSAtom's buffer without copying. When this flag * memory can be used as a new JSAtom's buffer without copying. When this flag
* is set, the contract is that callers will free *pchars iff *pchars == NULL. * is set, the contract is that callers will free *pchars iff *pchars == NULL.
*/ */
static JSAtom * static JSAtom *
Atomize(JSContext *cx, const jschar **pchars, size_t length, Atomize(JSContext *cx, const jschar **pchars, size_t length, uintN flags)
InternBehavior ib, OwnCharsBehavior ocb = CopyChars)
{ {
const jschar *chars = *pchars; const jschar *chars = *pchars;
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_NOCOPY)));
if (JSAtom *s = JSAtom::lookupStatic(chars, length)) if (JSAtom *s = JSAtom::lookupStatic(chars, length))
return s; return s;
@ -473,65 +476,45 @@ Atomize(JSContext *cx, const jschar **pchars, size_t length,
AtomSet &atoms = cx->runtime->atomState.atoms; AtomSet &atoms = cx->runtime->atomState.atoms;
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(chars, length)); AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(chars, length));
JSAtom *atom;
if (p) { if (p) {
JSAtom *atom = p->toAtom(); atom = AtomEntryToKey(*p);
MakeInterned(lock, *p, ib);
return atom;
}
SwitchToCompartment sc(cx, cx->runtime->atomsCompartment);
JSFixedString *key;
if (ocb == TakeCharOwnership) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key)
return NULL;
*pchars = NULL; /* Called should not free *pchars. */
} else { } else {
JS_ASSERT(ocb == CopyChars); SwitchToCompartment sc(cx, cx->runtime->atomsCompartment);
key = js_NewStringCopyN(cx, chars, length);
if (!key) JSFixedString *key;
if (flags & ATOM_NOCOPY) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key)
return NULL;
*pchars = NULL; /* Caller should not free *pchars. */
} else {
key = js_NewStringCopyN(cx, chars, length);
if (!key)
return NULL;
}
/*
* We have to relookup the key as the last ditch GC invoked from the
* string allocation or OOM handling may unlock the atomsCompartment.
*/
AtomHasher::Lookup lookup(chars, length);
if (!atoms.relookupOrAdd(p, lookup, StringToInitialAtomEntry(key))) {
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
return NULL; return NULL;
}
atom = key->morphInternedStringIntoAtom();
} }
/* AddAtomEntryFlags(*p, flags & (ATOM_PINNED | ATOM_INTERNED));
* We have to relookup the key as the last ditch GC invoked from the return atom;
* string allocation or OOM handling may unlock the atomsCompartment.
*
* N.B. this avoids recomputing the hash but still has a potential
* (# collisions * # chars) comparison cost in the case of a hash
* collision!
*/
AtomHasher::Lookup lookup(chars, length);
if (!atoms.relookupOrAdd(p, lookup, AtomStateEntry(key, ib))) {
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
return NULL;
}
return key->morphAtomizedStringIntoAtom();
} }
JSAtom * JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, InternBehavior ib) js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
{ {
if (str->isAtom()) { JS_ASSERT(!(flags & ATOM_NOCOPY));
JSAtom &atom = str->asAtom();
/* N.B. static atoms are effectively always interned. */
if (ib != InternAtom || atom.isStaticAtom())
return &atom;
/* Here we have to check whether the atom is already interned. */
AutoLockAtomsCompartment lock(cx);
AtomSet &atoms = cx->runtime->atomState.atoms;
AtomSet::Ptr p = atoms.lookup(AtomHasher::Lookup(&atom));
JS_ASSERT(p); /* Non-static atom must exist in atom state set. */
JS_ASSERT(p->toAtom() == &atom);
JS_ASSERT(ib == InternAtom);
MakeInterned(lock, *p, ib);
return &atom;
}
if (str->isAtom()) if (str->isAtom())
return &str->asAtom(); return &str->asAtom();
@ -542,12 +525,13 @@ js_AtomizeString(JSContext *cx, JSString *str, InternBehavior ib)
return NULL; return NULL;
JS_ASSERT(length <= JSString::MAX_LENGTH); JS_ASSERT(length <= JSString::MAX_LENGTH);
return Atomize(cx, &chars, length, ib); return Atomize(cx, &chars, length, flags);
} }
JSAtom * JSAtom *
js_Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib, bool useCESU8) js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8)
{ {
JS_ASSERT(!(flags & ATOM_NOCOPY));
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
if (!CheckStringLength(cx, length)) if (!CheckStringLength(cx, length))
@ -565,7 +549,6 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib, b
size_t inflatedLength = ATOMIZE_BUF_MAX - 1; size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
const jschar *chars; const jschar *chars;
OwnCharsBehavior ocb = CopyChars;
if (length < ATOMIZE_BUF_MAX) { if (length < ATOMIZE_BUF_MAX) {
if (useCESU8) if (useCESU8)
js_InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, true); js_InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, true);
@ -578,24 +561,25 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib, b
chars = js_InflateString(cx, bytes, &inflatedLength, useCESU8); chars = js_InflateString(cx, bytes, &inflatedLength, useCESU8);
if (!chars) if (!chars)
return NULL; return NULL;
ocb = TakeCharOwnership; flags |= ATOM_NOCOPY;
} }
JSAtom *atom = Atomize(cx, &chars, inflatedLength, ib, ocb); JSAtom *atom = Atomize(cx, &chars, inflatedLength, flags);
if (ocb == TakeCharOwnership && chars) if ((flags & ATOM_NOCOPY) && chars)
cx->free_((void *)chars); cx->free_((void *)chars);
return atom; return atom;
} }
JSAtom * JSAtom *
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib) js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
{ {
JS_ASSERT(!(flags & ATOM_NOCOPY));
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
if (!CheckStringLength(cx, length)) if (!CheckStringLength(cx, length))
return NULL; return NULL;
return Atomize(cx, &chars, length, ib); return Atomize(cx, &chars, length, flags);
} }
JSAtom * JSAtom *
@ -605,7 +589,7 @@ js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
return atom; return atom;
AutoLockAtomsCompartment lock(cx); AutoLockAtomsCompartment lock(cx);
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(AtomHasher::Lookup(chars, length)); AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(AtomHasher::Lookup(chars, length));
return p ? p->toAtom() : NULL; return p ? AtomEntryToKey(*p) : NULL;
} }
#ifdef DEBUG #ifdef DEBUG
@ -617,12 +601,21 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
fprintf(fp, "atoms table contents:\n"); fprintf(fp, "atoms table contents:\n");
unsigned number = 0; unsigned number = 0;
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) { for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront()) {
AtomStateEntry entry = r.front(); AtomEntryType entry = r.front();
fprintf(fp, "%3u ", number++); fprintf(fp, "%3u ", number++);
JSAtom *key = entry.toAtom(); if (entry == 0) {
FileEscapedString(fp, key, '"'); fputs("<uninitialized>", fp);
if (entry.isInterned()) } else {
fputs(" interned", fp); JSAtom *key = AtomEntryToKey(entry);
FileEscapedString(fp, key, '"');
uintN flags = AtomEntryFlags(entry);
if (flags != 0) {
fputs((flags & (ATOM_PINNED | ATOM_INTERNED))
? " pinned | interned"
: (flags & ATOM_PINNED) ? " pinned" : " interned",
fp);
}
}
putc('\n', fp); putc('\n', fp);
} }
putc('\n', fp); putc('\n', fp);

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

@ -54,6 +54,10 @@
#include "jslock.h" #include "jslock.h"
#include "jsvalue.h" #include "jsvalue.h"
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
/* Engine-internal extensions of jsid */ /* Engine-internal extensions of jsid */
static JS_ALWAYS_INLINE jsid static JS_ALWAYS_INLINE jsid
@ -274,76 +278,42 @@ struct JSAtomMap {
namespace js { namespace js {
enum InternBehavior #define ATOM_ENTRY_FLAG_MASK ((size_t)(ATOM_PINNED | ATOM_INTERNED))
JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JS_GCTHING_ALIGN);
typedef uintptr_t AtomEntryType;
static JS_ALWAYS_INLINE JSAtom *
AtomEntryToKey(AtomEntryType entry)
{ {
DoNotInternAtom = 0, JS_ASSERT(entry != 0);
InternAtom = 1 return (JSAtom *)(entry & ~ATOM_ENTRY_FLAG_MASK);
}; }
/*
* Atom pointer with low bit stolen to indicate whether the atom is interned.
* Interned atoms are ignored by the GC, and thus live for the lifetime of the
* runtime.
*/
struct AtomStateEntry {
uintptr_t bits;
static const uintptr_t INTERNED_FLAG = 0x1;
AtomStateEntry() : bits(0) {}
AtomStateEntry(const AtomStateEntry &other) : bits(other.bits) {}
AtomStateEntry(JSFixedString *futureAtom, bool intern)
: bits(uintptr_t(futureAtom) | intern)
{}
bool isInterned() const {
return bits & INTERNED_FLAG;
}
/* In static form to avoid accidentally mutating a copy of a hash set value. */
static void makeInterned(AtomStateEntry *self, InternBehavior ib) {
JS_STATIC_ASSERT(DoNotInternAtom == 0 && InternAtom == 1);
JS_ASSERT(ib <= InternAtom);
self->bits |= uintptr_t(ib);
}
JS_ALWAYS_INLINE
JSAtom *toAtom() const {
JS_ASSERT(bits != 0); /* No NULL values should exist in the atom state. */
JS_ASSERT(((JSString *) (bits & ~INTERNED_FLAG))->isAtom());
return (JSAtom *) (bits & ~INTERNED_FLAG);
}
};
struct AtomHasher struct AtomHasher
{ {
struct Lookup struct Lookup
{ {
const jschar *chars; const jschar *chars;
size_t length; size_t length;
const JSAtom *atom; /* Optional. */ Lookup(const jschar *chars, size_t length) : chars(chars), length(length) {}
Lookup(const jschar *chars, size_t length) : chars(chars), length(length), atom(NULL) {}
Lookup(const JSAtom *atom) : chars(atom->chars()), length(atom->length()), atom(atom) {}
}; };
static HashNumber hash(const Lookup &l) { static HashNumber hash(const Lookup &l) {
return HashChars(l.chars, l.length); return HashChars(l.chars, l.length);
} }
static bool match(AtomStateEntry entry, const Lookup &lookup) { static bool match(AtomEntryType entry, const Lookup &lookup) {
JSAtom *key = entry.toAtom(); JS_ASSERT(entry);
JSAtom *key = AtomEntryToKey(entry);
if (lookup.atom)
return lookup.atom == key;
if (key->length() != lookup.length) if (key->length() != lookup.length)
return false; return false;
return PodEqual(key->chars(), lookup.chars, lookup.length); return PodEqual(key->chars(), lookup.chars, lookup.length);
} }
}; };
typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet; typedef HashSet<AtomEntryType, AtomHasher, SystemAllocPolicy> AtomSet;
} /* namespace js */ } /* namespace js */
@ -493,43 +463,29 @@ struct JSAtomState
JSAtom *unwatchAtom; JSAtom *unwatchAtom;
JSAtom *watchAtom; JSAtom *watchAtom;
} lazy; } lazy;
static const size_t commonAtomsOffset;
static const size_t lazyAtomsOffset;
void clearLazyAtoms() {
memset(&lazy, 0, sizeof(lazy));
}
void junkAtoms() {
#ifdef DEBUG
memset(commonAtomsStart(), JS_FREE_PATTERN, sizeof(*this) - commonAtomsOffset);
#endif
}
JSAtom **commonAtomsStart() {
return &emptyAtom;
}
void checkStaticInvariants();
}; };
extern bool
AtomIsInterned(JSContext *cx, JSAtom *atom);
#define ATOM(name) cx->runtime->atomState.name##Atom #define ATOM(name) cx->runtime->atomState.name##Atom
#define ATOM_OFFSET_START offsetof(JSAtomState, emptyAtom)
#define LAZY_ATOM_OFFSET_START offsetof(JSAtomState, lazy)
#define ATOM_OFFSET_LIMIT (sizeof(JSAtomState))
#define COMMON_ATOMS_START(state) \
((JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START))
#define COMMON_ATOM_INDEX(name) \ #define COMMON_ATOM_INDEX(name) \
((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset) \ ((offsetof(JSAtomState, name##Atom) - ATOM_OFFSET_START) \
/ sizeof(JSAtom*)) / sizeof(JSAtom*))
#define COMMON_TYPE_ATOM_INDEX(type) \ #define COMMON_TYPE_ATOM_INDEX(type) \
((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\ ((offsetof(JSAtomState, typeAtoms[type]) - ATOM_OFFSET_START) \
/ sizeof(JSAtom*)) / sizeof(JSAtom*))
#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom) #define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off))) #define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name]) #define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name])
#define CLASS_ATOM(cx,name) ((cx)->runtime->atomState.classAtoms[JSProto_##name])
#define CLASS_ATOM(cx,name) \
((cx)->runtime->atomState.classAtoms[JSProto_##name])
extern const char *const js_common_atom_names[]; extern const char *const js_common_atom_names[];
extern const size_t js_common_atom_count; extern const size_t js_common_atom_count;
@ -632,7 +588,7 @@ js_TraceAtomState(JSTracer *trc);
extern void extern void
js_SweepAtomState(JSContext *cx); js_SweepAtomState(JSContext *cx);
extern bool extern JSBool
js_InitCommonAtoms(JSContext *cx); js_InitCommonAtoms(JSContext *cx);
extern void extern void
@ -643,15 +599,13 @@ js_FinishCommonAtoms(JSContext *cx);
* memory. * memory.
*/ */
extern JSAtom * extern JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom); js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
extern JSAtom * extern JSAtom *
js_Atomize(JSContext *cx, const char *bytes, size_t length, js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8 = false);
js::InternBehavior ib = js::DoNotInternAtom, bool useCESU8 = false);
extern JSAtom * extern JSAtom *
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
js::InternBehavior ib = js::DoNotInternAtom);
/* /*
* Return an existing atom for the given char array or null if the char * Return an existing atom for the given char array or null if the char

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

@ -51,7 +51,7 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
if (!str) if (!str)
return false; return false;
JS::Anchor<JSString *> anchor(str); JS::Anchor<JSString *> anchor(str);
*atomp = js_AtomizeString(cx, str); *atomp = js_AtomizeString(cx, str, 0);
return !!*atomp; return !!*atomp;
} }
@ -61,7 +61,7 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
return true; return true;
} }
*atomp = js_AtomizeString(cx, str); *atomp = js_AtomizeString(cx, str, 0);
return !!*atomp; return !!*atomp;
} }
@ -144,7 +144,7 @@ IndexToId(JSContext *cx, uint32 index, jsid *idp)
if (!str) if (!str)
return false; return false;
JSAtom *atom = js_AtomizeString(cx, str); JSAtom *atom = js_AtomizeString(cx, str, 0);
if (!atom) if (!atom)
return false; return false;
*idp = ATOM_TO_JSID(atom); *idp = ATOM_TO_JSID(atom);

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

@ -260,7 +260,7 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
JSBool FASTCALL JSBool FASTCALL
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr) js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
{ {
JSAtom *atom = js_AtomizeString(cx, idstr); JSAtom *atom = js_AtomizeString(cx, idstr, 0);
if (!atom) if (!atom)
return JS_NEITHER; return JS_NEITHER;

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

@ -822,7 +822,7 @@ JSStructuredCloneReader::readId(jsid *idp)
JSString *str = readString(data); JSString *str = readString(data);
if (!str) if (!str)
return false; return false;
JSAtom *atom = js_AtomizeString(context(), str); JSAtom *atom = js_AtomizeString(context(), str, 0);
if (!atom) if (!atom)
return false; return false;
*idp = ATOM_TO_JSID(atom); *idp = ATOM_TO_JSID(atom);

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

@ -1389,7 +1389,7 @@ static inline JSAtom **
FrameAtomBase(JSContext *cx, js::StackFrame *fp) FrameAtomBase(JSContext *cx, js::StackFrame *fp)
{ {
return fp->hasImacropc() return fp->hasImacropc()
? cx->runtime->atomState.commonAtomsStart() ? COMMON_ATOMS_START(&cx->runtime->atomState)
: fp->script()->atomMap.vector; : fp->script()->atomMap.vector;
} }
@ -1875,7 +1875,7 @@ class AutoLockAtomsCompartment {
public: public:
AutoLockAtomsCompartment(JSContext *cx AutoLockAtomsCompartment(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: cx(cx) : cx(cx)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;

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

@ -1323,8 +1323,8 @@ JSTreeContext::ensureSharpSlots()
JS_ASSERT(!(flags & TCF_HAS_SHARPS)); JS_ASSERT(!(flags & TCF_HAS_SHARPS));
if (inFunction()) { if (inFunction()) {
JSContext *cx = parser->context; JSContext *cx = parser->context;
JSAtom *sharpArrayAtom = js_Atomize(cx, "#array", 6); JSAtom *sharpArrayAtom = js_Atomize(cx, "#array", 6, 0);
JSAtom *sharpDepthAtom = js_Atomize(cx, "#depth", 6); JSAtom *sharpDepthAtom = js_Atomize(cx, "#depth", 6, 0);
if (!sharpArrayAtom || !sharpDepthAtom) if (!sharpArrayAtom || !sharpDepthAtom)
return false; return false;

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

@ -404,6 +404,9 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj);
extern JSObject * extern JSObject *
js_InitArgumentsClass(JSContext *cx, JSObject *obj); js_InitArgumentsClass(JSContext *cx, JSObject *obj);
extern void
js_TraceFunction(JSTracer *trc, JSFunction *fun);
extern void extern void
js_FinalizeFunction(JSContext *cx, JSFunction *fun); js_FinalizeFunction(JSContext *cx, JSFunction *fun);

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

@ -2259,7 +2259,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
#define LOAD_ATOM(PCOFF, atom) \ #define LOAD_ATOM(PCOFF, atom) \
JS_BEGIN_MACRO \ JS_BEGIN_MACRO \
JS_ASSERT(regs.fp()->hasImacropc() \ JS_ASSERT(regs.fp()->hasImacropc() \
? atoms == rt->atomState.commonAtomsStart() && \ ? atoms == COMMON_ATOMS_START(&rt->atomState) && \
GET_INDEX(regs.pc + PCOFF) < js_common_atom_count \ GET_INDEX(regs.pc + PCOFF) < js_common_atom_count \
: (size_t)(atoms - script->atomMap.vector) < \ : (size_t)(atoms - script->atomMap.vector) < \
(size_t)(script->atomMap.length - \ (size_t)(script->atomMap.length - \
@ -2508,7 +2508,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
} }
if (regs.fp()->hasImacropc()) if (regs.fp()->hasImacropc())
atoms = rt->atomState.commonAtomsStart(); atoms = COMMON_ATOMS_START(&rt->atomState);
#endif #endif
/* Don't call the script prologue if executing between Method and Trace JIT. */ /* Don't call the script prologue if executing between Method and Trace JIT. */
@ -2674,7 +2674,7 @@ Interpret(JSContext *cx, StackFrame *entryFrame, uintN inlineCallCount, InterpMo
break; break;
case ARECORD_IMACRO: case ARECORD_IMACRO:
case ARECORD_IMACRO_ABORTED: case ARECORD_IMACRO_ABORTED:
atoms = rt->atomState.commonAtomsStart(); atoms = COMMON_ATOMS_START(&rt->atomState);
op = JSOp(*regs.pc); op = JSOp(*regs.pc);
CLEAR_LEAVE_ON_TRACE_POINT(); CLEAR_LEAVE_ON_TRACE_POINT();
if (status == ARECORD_IMACRO) if (status == ARECORD_IMACRO)

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

@ -3995,7 +3995,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *protoProto,
JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *ps, JSFunctionSpec *fs,
JSPropertySpec *static_ps, JSFunctionSpec *static_fs) JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
{ {
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name)); JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
if (!atom) if (!atom)
return NULL; return NULL;
@ -4282,7 +4282,7 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
} }
id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[protoKey]); id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[protoKey]);
} else { } else {
JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name)); JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
if (!atom) if (!atom)
return false; return false;
id = ATOM_TO_JSID(atom); id = ATOM_TO_JSID(atom);
@ -6323,7 +6323,7 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
if (protoKey != JSProto_Null) { if (protoKey != JSProto_Null) {
classDef |= (protoKey << 1); classDef |= (protoKey << 1);
} else { } else {
atom = js_Atomize(cx, clasp->name, strlen(clasp->name)); atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
} }

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

@ -87,7 +87,7 @@ JSONSourceParser::readString()
size_t length = current - start; size_t length = current - start;
current++; current++;
JSFlatString *str = (ST == JSONSourceParser::PropertyName) JSFlatString *str = (ST == JSONSourceParser::PropertyName)
? js_AtomizeChars(cx, start, length) ? js_AtomizeChars(cx, start, length, 0)
: js_NewStringCopyN(cx, start, length); : js_NewStringCopyN(cx, start, length);
if (!str) if (!str)
return token(OOM); return token(OOM);

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

@ -981,7 +981,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
* Save eval program source in script->atomMap.vector[0] for the * Save eval program source in script->atomMap.vector[0] for the
* eval cache (see EvalCacheLookup in jsobj.cpp). * eval cache (see EvalCacheLookup in jsobj.cpp).
*/ */
JSAtom *atom = js_AtomizeString(cx, source); JSAtom *atom = js_AtomizeString(cx, source, 0);
if (!atom || !cg.atomList.add(&parser, atom)) if (!atom || !cg.atomList.add(&parser, atom))
goto out; goto out;
} }
@ -8880,7 +8880,7 @@ FoldType(JSContext *cx, JSParseNode *pn, TokenKind type)
JSString *str = js_NumberToString(cx, pn->pn_dval); JSString *str = js_NumberToString(cx, pn->pn_dval);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
pn->pn_atom = js_AtomizeString(cx, str); pn->pn_atom = js_AtomizeString(cx, str, 0);
if (!pn->pn_atom) if (!pn->pn_atom)
return JS_FALSE; return JS_FALSE;
pn->pn_type = TOK_STRING; pn->pn_type = TOK_STRING;
@ -9064,7 +9064,7 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
pn1->pn_type = TOK_XMLTEXT; pn1->pn_type = TOK_XMLTEXT;
pn1->pn_op = JSOP_STRING; pn1->pn_op = JSOP_STRING;
pn1->pn_arity = PN_NULLARY; pn1->pn_arity = PN_NULLARY;
pn1->pn_atom = js_AtomizeString(cx, accum); pn1->pn_atom = js_AtomizeString(cx, accum, 0);
if (!pn1->pn_atom) if (!pn1->pn_atom)
return JS_FALSE; return JS_FALSE;
JS_ASSERT(pnp != &pn1->pn_next); JS_ASSERT(pnp != &pn1->pn_next);
@ -9117,7 +9117,7 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
pn1->pn_type = TOK_XMLTEXT; pn1->pn_type = TOK_XMLTEXT;
pn1->pn_op = JSOP_STRING; pn1->pn_op = JSOP_STRING;
pn1->pn_arity = PN_NULLARY; pn1->pn_arity = PN_NULLARY;
pn1->pn_atom = js_AtomizeString(cx, accum); pn1->pn_atom = js_AtomizeString(cx, accum, 0);
if (!pn1->pn_atom) if (!pn1->pn_atom)
return JS_FALSE; return JS_FALSE;
JS_ASSERT(pnp != &pn1->pn_next); JS_ASSERT(pnp != &pn1->pn_next);
@ -9481,7 +9481,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
JS_ASSERT(*chars == 0); JS_ASSERT(*chars == 0);
/* Atomize the result string and mutate pn to refer to it. */ /* Atomize the result string and mutate pn to refer to it. */
pn->pn_atom = js_AtomizeString(cx, str); pn->pn_atom = js_AtomizeString(cx, str, 0);
if (!pn->pn_atom) if (!pn->pn_atom)
return JS_FALSE; return JS_FALSE;
pn->pn_type = TOK_STRING; pn->pn_type = TOK_STRING;
@ -9506,7 +9506,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
str = js_ConcatStrings(cx, left, right); str = js_ConcatStrings(cx, left, right);
if (!str) if (!str)
return JS_FALSE; return JS_FALSE;
pn->pn_atom = js_AtomizeString(cx, str); pn->pn_atom = js_AtomizeString(cx, str, 0);
if (!pn->pn_atom) if (!pn->pn_atom)
return JS_FALSE; return JS_FALSE;
pn->pn_type = TOK_STRING; pn->pn_type = TOK_STRING;

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

@ -203,7 +203,7 @@ class NodeBuilder
Value funv; Value funv;
const char *name = callbackNames[i]; const char *name = callbackNames[i];
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom || !GetPropertyDefault(cx, userobj, ATOM_TO_JSID(atom), NullValue(), &funv)) if (!atom || !GetPropertyDefault(cx, userobj, ATOM_TO_JSID(atom), NullValue(), &funv))
return false; return false;
@ -313,7 +313,7 @@ class NodeBuilder
/* /*
* Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file * Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file
*/ */
JSAtom *atom = js_Atomize(cx, s, strlen(s)); JSAtom *atom = js_Atomize(cx, s, strlen(s), 0);
if (!atom) if (!atom)
return false; return false;
@ -425,7 +425,7 @@ class NodeBuilder
/* /*
* Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file * Bug 575416: instead of js_Atomize, lookup constant atoms in tbl file
*/ */
JSAtom *atom = js_Atomize(cx, name, strlen(name)); JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
if (!atom) if (!atom)
return false; return false;

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

@ -1020,7 +1020,7 @@ TokenStream::getXMLMarkup(TokenKind *ttp, Token **tpp)
atom = cx->runtime->atomState.emptyAtom; atom = cx->runtime->atomState.emptyAtom;
} else { } else {
atom = js_AtomizeChars(cx, tokenbuf.begin() + contentIndex, atom = js_AtomizeChars(cx, tokenbuf.begin() + contentIndex,
tokenbuf.length() - contentIndex); tokenbuf.length() - contentIndex, 0);
if (!atom) if (!atom)
goto error; goto error;
} }
@ -1184,7 +1184,7 @@ TokenStream::newToken(ptrdiff_t adjust)
JS_ALWAYS_INLINE JSAtom * JS_ALWAYS_INLINE JSAtom *
TokenStream::atomize(JSContext *cx, CharBuffer &cb) TokenStream::atomize(JSContext *cx, CharBuffer &cb)
{ {
return js_AtomizeChars(cx, cb.begin(), cb.length()); return js_AtomizeChars(cx, cb.begin(), cb.length(), 0);
} }
#ifdef DEBUG #ifdef DEBUG
@ -1363,7 +1363,7 @@ TokenStream::getTokenInternal()
*/ */
JSAtom *atom; JSAtom *atom;
if (!hadUnicodeEscape) if (!hadUnicodeEscape)
atom = js_AtomizeChars(cx, identStart, userbuf.addressOfNextRawChar() - identStart); atom = js_AtomizeChars(cx, identStart, userbuf.addressOfNextRawChar() - identStart, 0);
else if (putIdentInTokenbuf(identStart)) else if (putIdentInTokenbuf(identStart))
atom = atomize(cx, tokenbuf); atom = atomize(cx, tokenbuf);
else else

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

@ -610,7 +610,6 @@ struct Shape : public js::gc::Cell
void finalize(JSContext *cx); void finalize(JSContext *cx);
void removeChild(js::Shape *child); void removeChild(js::Shape *child);
void removeChildSlowly(js::Shape *child);
}; };
struct EmptyShape : public js::Shape struct EmptyShape : public js::Shape

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

@ -262,7 +262,7 @@ Bindings::sharpSlotBase(JSContext *cx)
{ {
JS_ASSERT(lastBinding); JS_ASSERT(lastBinding);
#if JS_HAS_SHARP_VARS #if JS_HAS_SHARP_VARS
if (JSAtom *name = js_Atomize(cx, "#array", 6)) { if (JSAtom *name = js_Atomize(cx, "#array", 6, 0)) {
uintN index = uintN(-1); uintN index = uintN(-1);
DebugOnly<BindingKind> kind = lookup(cx, name, &index); DebugOnly<BindingKind> kind = lookup(cx, name, &index);
JS_ASSERT(kind == VARIABLE); JS_ASSERT(kind == VARIABLE);

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

@ -649,7 +649,7 @@ StackDepth(JSScript *script)
if ((pc_) < (script_)->code || \ if ((pc_) < (script_)->code || \
(script_)->code + (script_)->length <= (pc_)) { \ (script_)->code + (script_)->length <= (pc_)) { \
JS_ASSERT((size_t)(index) < js_common_atom_count); \ JS_ASSERT((size_t)(index) < js_common_atom_count); \
(atom) = cx->runtime->atomState.commonAtomsStart()[index]; \ (atom) = COMMON_ATOMS_START(&cx->runtime->atomState)[index]; \
} else { \ } else { \
(atom) = script_->getAtom(index); \ (atom) = script_->getAtom(index); \
} \ } \

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

@ -2068,7 +2068,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
if (str->isAtom()) { if (str->isAtom()) {
atom = &str->asAtom(); atom = &str->asAtom();
} else { } else {
atom = js_AtomizeString(cx, str); atom = js_AtomizeString(cx, str, 0);
if (!atom) if (!atom)
return false; return false;
} }
@ -3721,7 +3721,7 @@ StringBuffer::finishAtom()
if (length == 0) if (length == 0)
return cx->runtime->atomState.emptyAtom; return cx->runtime->atomState.emptyAtom;
JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length); JSAtom *atom = js_AtomizeChars(cx, cb.begin(), length, 0);
cb.clear(); cb.clear();
return atom; return atom;
} }

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

@ -486,11 +486,10 @@ class JSFixedString : public JSFlatString
static inline JSFixedString *new_(JSContext *cx, const jschar *chars, size_t length); static inline JSFixedString *new_(JSContext *cx, const jschar *chars, size_t length);
/* /*
* Once a JSFixedString has been added to the atom state, this operation * Once a JSFixedString has been added to the atom table, this operation
* changes the type (in place, as reflected by the flag bits) of the * changes the type (in place) of the JSFixedString into a JSAtom.
* JSFixedString into a JSAtom.
*/ */
inline JSAtom *morphAtomizedStringIntoAtom(); inline JSAtom *morphInternedStringIntoAtom();
}; };
JS_STATIC_ASSERT(sizeof(JSFixedString) == sizeof(JSString)); JS_STATIC_ASSERT(sizeof(JSFixedString) == sizeof(JSString));

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

@ -344,7 +344,7 @@ JSFixedString::new_(JSContext *cx, const jschar *chars, size_t length)
} }
JS_ALWAYS_INLINE JSAtom * JS_ALWAYS_INLINE JSAtom *
JSFixedString::morphAtomizedStringIntoAtom() JSFixedString::morphInternedStringIntoAtom()
{ {
JS_ASSERT((d.lengthAndFlags & FLAGS_MASK) == JS_BIT(2)); JS_ASSERT((d.lengthAndFlags & FLAGS_MASK) == JS_BIT(2));
JS_STATIC_ASSERT(NON_STATIC_ATOM == JS_BIT(3)); JS_STATIC_ASSERT(NON_STATIC_ATOM == JS_BIT(3));

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

@ -12470,11 +12470,11 @@ RootedStringToId(JSContext* cx, JSString** namep, jsid* idp)
{ {
JSString* name = *namep; JSString* name = *namep;
if (name->isAtom()) { if (name->isAtom()) {
*idp = ATOM_TO_JSID(&name->asAtom()); *idp = INTERNED_STRING_TO_JSID(name);
return true; return true;
} }
JSAtom* atom = js_AtomizeString(cx, name); JSAtom* atom = js_AtomizeString(cx, name, 0);
if (!atom) if (!atom)
return false; return false;
*namep = atom; /* write back to GC root */ *namep = atom; /* write back to GC root */

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

@ -87,8 +87,6 @@ JS_Assert(const char *s, const char *file, JSIntn ln);
# define JS_THREADSAFE_ASSERT(expr) ((void) 0) # define JS_THREADSAFE_ASSERT(expr) ((void) 0)
# endif # endif
#define JS_FREE_PATTERN 0xDA
#else #else
#define JS_ASSERT(expr) ((void) 0) #define JS_ASSERT(expr) ((void) 0)

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

@ -658,7 +658,7 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
if (!buf) if (!buf)
return false; return false;
JSAtom *atom = js_Atomize(xdr->cx, buf, len, DoNotInternAtom, true); JSAtom *atom = js_Atomize(xdr->cx, buf, len, 0, true);
if (!atom) if (!atom)
return false; return false;

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

@ -2872,7 +2872,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
return NULL; return NULL;
} }
atomizedName = js_AtomizeString(cx, name); atomizedName = js_AtomizeString(cx, name, 0);
if (!atomizedName) if (!atomizedName)
return NULL; return NULL;
@ -5344,7 +5344,7 @@ ValueToId(JSContext *cx, jsval v, AutoIdRooter *idr)
else if (!js_ValueToStringId(cx, Valueify(v), idr->addr())) else if (!js_ValueToStringId(cx, Valueify(v), idr->addr()))
return JS_FALSE; return JS_FALSE;
} else if (JSVAL_IS_STRING(v)) { } else if (JSVAL_IS_STRING(v)) {
JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v)); JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v), 0);
if (!atom) if (!atom)
return JS_FALSE; return JS_FALSE;
*idr->addr() = ATOM_TO_JSID(atom); *idr->addr() = ATOM_TO_JSID(atom);

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

@ -190,7 +190,7 @@ PRBool InitializeMember(JSContext * cx, ITypeInfo * pTypeInfo,
pInfo = new (pInfo) XPCDispInterface::Member; pInfo = new (pInfo) XPCDispInterface::Member;
if(!pInfo) if(!pInfo)
return PR_FALSE; return PR_FALSE;
pInfo->SetName(INTERNED_STRING_TO_JSID(cx, str)); pInfo->SetName(INTERNED_STRING_TO_JSID(str));
pInfo->ResetType(); pInfo->ResetType();
ConvertInvokeKind(pFuncDesc->invkind, *pInfo); ConvertInvokeKind(pFuncDesc->invkind, *pInfo);
pInfo->SetTypeInfo(pFuncDesc->memid, pTypeInfo, pFuncDesc); pInfo->SetTypeInfo(pFuncDesc->memid, pTypeInfo, pFuncDesc);

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

@ -548,7 +548,7 @@ GetMethodInfo(JSContext *cx, jsval *vp, const char **ifaceNamep, jsid *memberIdp
NS_ASSERTION(JS_ObjectIsFunction(cx, funobj), NS_ASSERTION(JS_ObjectIsFunction(cx, funobj),
"JSNative callee should be Function object"); "JSNative callee should be Function object");
JSString *str = JS_GetFunctionId((JSFunction *) JS_GetPrivate(cx, funobj)); JSString *str = JS_GetFunctionId((JSFunction *) JS_GetPrivate(cx, funobj));
jsid methodId = str ? INTERNED_STRING_TO_JSID(cx, str) : JSID_VOID; jsid methodId = str ? INTERNED_STRING_TO_JSID(str) : JSID_VOID;
GetMemberInfo(JSVAL_TO_OBJECT(vp[1]), methodId, ifaceNamep); GetMemberInfo(JSVAL_TO_OBJECT(vp[1]), methodId, ifaceNamep);
*memberIdp = methodId; *memberIdp = methodId;
} }

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

@ -382,7 +382,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
failed = JS_TRUE; failed = JS_TRUE;
break; break;
} }
name = INTERNED_STRING_TO_JSID(ccx, str); name = INTERNED_STRING_TO_JSID(str);
if(info->IsSetter()) if(info->IsSetter())
{ {
@ -426,7 +426,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
failed = JS_TRUE; failed = JS_TRUE;
break; break;
} }
name = INTERNED_STRING_TO_JSID(ccx, str); name = INTERNED_STRING_TO_JSID(str);
// XXX need better way to find dups // XXX need better way to find dups
//NS_ASSERTION(!LookupMemberByID(name),"duplicate method/constant name"); //NS_ASSERTION(!LookupMemberByID(name),"duplicate method/constant name");
@ -445,7 +445,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
{ {
failed = JS_TRUE; failed = JS_TRUE;
} }
interfaceName = INTERNED_STRING_TO_JSID(ccx, str); interfaceName = INTERNED_STRING_TO_JSID(str);
} }
if(!failed) if(!failed)