Disallow non-canonical jsids, bug 751331. r=luke
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 06 May 2012 13:45:19 -0700
changeset 97374 86d28b6fa4fc7c4d153cc4bd22362970b9e4e059
parent 97373 eaf078ed96b953e5c05747d0c2705084f4a4a4d2
child 97375 390dc1d722ab55ddc633cef232822a7f156778ac
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs751331
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Disallow non-canonical jsids, bug 751331. r=luke
js/src/builtin/RegExp.cpp
js/src/ctypes/CTypes.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/gc/Marking.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jsbool.cpp
js/src/jsclone.cpp
js/src/jscntxt.cpp
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfun.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsmath.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsonparser.cpp
js/src/jspropertycache.cpp
js/src/jsproxy.cpp
js/src/jsreflect.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jswatchpoint.cpp
js/src/jsweakmap.cpp
js/src/jswrapper.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/String.cpp
js/src/vm/String.h
js/src/vm/StringObject-inl.h
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -52,17 +52,17 @@ using namespace js;
 using namespace js::types;
 
 class RegExpMatchBuilder
 {
     JSContext   * const cx;
     RootedVarObject array;
 
     bool setProperty(JSAtom *name, Value v) {
-        return !!js_DefineProperty(cx, array, ATOM_TO_JSID(name), &v,
+        return !!js_DefineProperty(cx, array, AtomToId(name), &v,
                                    JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
     }
 
   public:
     RegExpMatchBuilder(JSContext *cx, JSObject *array) : cx(cx), array(cx, array) {}
 
     bool append(uint32_t index, Value v) {
         JS_ASSERT(!array->getOps()->getElement);
@@ -495,17 +495,17 @@ js_InitRegExpClass(JSContext *cx, JSObje
     RegExpObjectBuilder builder(cx, &proto->asRegExp());
     if (!builder.build(RootedVarAtom(cx, cx->runtime->emptyString), RegExpFlag(0)))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))
         return NULL;
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, regexp_construct, CLASS_ATOM(cx, RegExp), 2);
+    ctor = global->createConstructor(cx, regexp_construct, CLASS_NAME(cx, RegExp), 2);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return NULL;
 
     /* Add static properties to the RegExp constructor. */
     if (!JS_DefineProperties(cx, ctor, regexp_static_props))
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -4175,17 +4175,18 @@ ArrayType::Getter(JSContext* cx, JSObjec
   JSObject* typeObj = CData::GetCType(obj);
   if (CType::GetTypeCode(typeObj) != TYPE_array)
     return JS_TRUE;
 
   // Convert the index to a size_t and bounds-check it.
   size_t index;
   size_t length = GetLength(typeObj);
   bool ok = jsidToSize(cx, idval, true, &index);
-  if (!ok && JSID_IS_STRING(idval)) {
+  int32_t dummy;
+  if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) {
     // String either isn't a number, or doesn't fit in size_t.
     // Chances are it's a regular property lookup, so return.
     return JS_TRUE;
   }
   if (!ok || index >= length) {
     JS_ReportError(cx, "invalid index");
     return JS_FALSE;
   }
@@ -4210,17 +4211,18 @@ ArrayType::Setter(JSContext* cx, JSObjec
   JSObject* typeObj = CData::GetCType(obj);
   if (CType::GetTypeCode(typeObj) != TYPE_array)
     return JS_TRUE;
 
   // Convert the index to a size_t and bounds-check it.
   size_t index;
   size_t length = GetLength(typeObj);
   bool ok = jsidToSize(cx, idval, true, &index);
-  if (!ok && JSID_IS_STRING(idval)) {
+  int32_t dummy;
+  if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) {
     // String either isn't a number, or doesn't fit in size_t.
     // Chances are it's a regular property lookup, so return.
     return JS_TRUE;
   }
   if (!ok || index >= length) {
     JS_ReportError(cx, "invalid index");
     return JS_FALSE;
   }
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -62,17 +62,17 @@ DefineGlobals(JSContext *cx, GlobalScope
     /* Define and update global properties. */
     for (size_t i = 0; i < globalScope.defs.length(); i++) {
         GlobalScope::GlobalDef &def = globalScope.defs[i];
 
         /* Names that could be resolved ahead of time can be skipped. */
         if (!def.atom)
             continue;
 
-        jsid id = ATOM_TO_JSID(def.atom);
+        jsid id = AtomToId(def.atom);
         Value rval;
 
         if (def.funbox) {
             JSFunction *fun = def.funbox->function();
 
             /*
              * No need to check for redeclarations or anything, global
              * optimizations only take place if the property is not defined.
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -763,17 +763,17 @@ frontend::LexicalLookup(TreeContext *tc,
         if (stmt->type == STMT_WITH)
             break;
 
         /* Skip "maybe scope" statements that don't contain let bindings. */
         if (!(stmt->flags & SIF_SCOPE))
             continue;
 
         StaticBlockObject &blockObj = *stmt->blockObj;
-        const Shape *shape = blockObj.nativeLookup(tc->parser->context, ATOM_TO_JSID(atom));
+        const Shape *shape = blockObj.nativeLookup(tc->parser->context, AtomToId(atom));
         if (shape) {
             JS_ASSERT(shape->hasShortID());
 
             if (slotp)
                 *slotp = blockObj.stackDepth() + shape->shortid();
             return stmt;
         }
     }
@@ -818,17 +818,17 @@ LookupCompileTimeConstant(JSContext *cx,
              */
             if (bce->inFunction()) {
                 if (bce->bindings.hasBinding(cx, atom))
                     break;
             } else {
                 JS_ASSERT(bce->compileAndGo());
                 JSObject *obj = bce->scopeChain();
 
-                const Shape *shape = obj->nativeLookup(cx, ATOM_TO_JSID(atom));
+                const Shape *shape = obj->nativeLookup(cx, AtomToId(atom));
                 if (shape) {
                     /*
                      * We're compiling code that will be executed immediately,
                      * not re-executed against a different scope chain and/or
                      * variable object.  Therefore we can get constant values
                      * from our variable object here.
                      */
                     if (!shape->writable() && !shape->configurable() &&
@@ -3970,24 +3970,24 @@ ParseNode::getConstantValue(JSContext *c
                 return false;
 
             ParseNode *pnid = pn->pn_left;
             if (pnid->isKind(PNK_NUMBER)) {
                 Value idvalue = NumberValue(pnid->pn_dval);
                 jsid id;
                 if (idvalue.isInt32() && INT_FITS_IN_JSID(idvalue.toInt32()))
                     id = INT_TO_JSID(idvalue.toInt32());
-                else if (!js_InternNonIntElementId(cx, obj, idvalue, &id))
+                else if (!InternNonIntElementId(cx, obj, idvalue, &id))
                     return false;
                 if (!obj->defineGeneric(cx, id, value, NULL, NULL, JSPROP_ENUMERATE))
                     return false;
             } else {
                 JS_ASSERT(pnid->isKind(PNK_NAME) || pnid->isKind(PNK_STRING));
                 JS_ASSERT(pnid->pn_atom != cx->runtime->atomState.protoAtom);
-                jsid id = ATOM_TO_JSID(pnid->pn_atom);
+                jsid id = AtomToId(pnid->pn_atom);
                 if (!DefineNativeProperty(cx, obj, id, value, NULL, NULL,
                                           JSPROP_ENUMERATE, 0, 0)) {
                     return false;
                 }
             }
         }
 
         types::FixObjectType(cx, obj);
@@ -5974,17 +5974,17 @@ EmitObject(JSContext *cx, BytecodeEmitte
              * a non-standard setter on objects.
              */
             if (pn3->pn_atom == cx->runtime->atomState.protoAtom)
                 obj = NULL;
             op = JSOP_INITPROP;
 
             if (obj) {
                 JS_ASSERT(!obj->inDictionaryMode());
-                if (!DefineNativeProperty(cx, obj, ATOM_TO_JSID(pn3->pn_atom),
+                if (!DefineNativeProperty(cx, obj, AtomToId(pn3->pn_atom),
                                           UndefinedValue(), NULL, NULL,
                                           JSPROP_ENUMERATE, 0, 0))
                 {
                     return false;
                 }
                 if (obj->inDictionaryMode())
                     obj = NULL;
             }
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2003,17 +2003,17 @@ BindLet(JSContext *cx, BindData *data, J
     pn->pn_cookie.set(tc->staticLevel, uint16_t(blockCount));
     pn->pn_dflags |= PND_LET | PND_BOUND;
 
     /*
      * Define the let binding's property before storing pn in the the binding's
      * slot indexed by blockCount off the class-reserved slot base.
      */
     bool redeclared;
-    jsid id = ATOM_TO_JSID(atom);
+    jsid id = AtomToId(atom);
     const Shape *shape = blockObj->addVar(cx, id, blockCount, &redeclared);
     if (!shape) {
         if (redeclared)
             ReportRedeclaration(cx, tc, pn, false, atom);
         return false;
     }
 
     /* Store pn in the static block object. */
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -270,17 +270,17 @@ MarkGCThingRoot(JSTracer *trc, void **th
 
 static inline void
 MarkIdInternal(JSTracer *trc, jsid *id)
 {
     JS_SET_TRACING_LOCATION(trc, (void *)id);
     if (JSID_IS_STRING(*id)) {
         JSString *str = JSID_TO_STRING(*id);
         MarkInternal(trc, &str);
-        *id = ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
+        *id = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
     } else if (JS_UNLIKELY(JSID_IS_OBJECT(*id))) {
         JSObject *obj = JSID_TO_OBJECT(*id);
         MarkInternal(trc, &obj);
         *id = OBJECT_TO_JSID(obj);
     }
 }
 
 void
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1737,42 +1737,42 @@ JS_InitStandardClasses(JSContext *cx, JS
 
     assertSameCompartment(cx, obj);
 
     return GlobalObject::initStandardClasses(cx, RootedVar<GlobalObject*>(cx, &obj->global()));
 }
 
 #define CLASP(name)                 (&name##Class)
 #define TYPED_ARRAY_CLASP(type)     (&TypedArray::classes[TypedArray::type])
-#define EAGER_ATOM(name)            ATOM_OFFSET(name), NULL
-#define EAGER_CLASS_ATOM(name)      CLASS_ATOM_OFFSET(name), NULL
+#define EAGER_ATOM(name)            NAME_OFFSET(name), NULL
+#define EAGER_CLASS_ATOM(name)      CLASS_NAME_OFFSET(name), NULL
 #define EAGER_ATOM_AND_CLASP(name)  EAGER_CLASS_ATOM(name), CLASP(name)
-#define LAZY_ATOM(name)             ATOM_OFFSET(lazy.name), js_##name##_str
+#define LAZY_ATOM(name)             NAME_OFFSET(lazy.name), js_##name##_str
 
 typedef struct JSStdName {
     JSObjectOp  init;
     size_t      atomOffset;     /* offset of atom pointer in JSAtomState */
     const char  *name;          /* null if atom is pre-pinned, else name */
     Class       *clasp;
 } JSStdName;
 
-static JSAtom *
-StdNameToAtom(JSContext *cx, JSStdName *stdn)
+static PropertyName *
+StdNameToPropertyName(JSContext *cx, JSStdName *stdn)
 {
     size_t offset;
-    JSAtom *atom;
+    PropertyName *atom;
     const char *name;
 
     offset = stdn->atomOffset;
-    atom = OFFSET_TO_ATOM(cx->runtime, offset);
+    atom = OFFSET_TO_NAME(cx->runtime, offset);
     if (!atom) {
         name = stdn->name;
         if (name) {
-            atom = js_Atomize(cx, name, strlen(name), InternAtom);
-            OFFSET_TO_ATOM(cx->runtime, offset) = atom;
+            atom = js_Atomize(cx, name, strlen(name), InternAtom)->asPropertyName();
+            OFFSET_TO_NAME(cx->runtime, offset) = atom;
         }
     }
     return atom;
 }
 
 /*
  * Table of class initializers and their atom offsets in rt->atomState.
  * If you add a "standard" class, remember to update this table.
@@ -1926,45 +1926,45 @@ JS_ResolveStandardClass(JSContext *cx, J
                                    JS_PropertyStub, JS_StrictPropertyStub,
                                    JSPROP_PERMANENT | JSPROP_READONLY);
     }
 
     /* Try for class constructors/prototypes named by well-known atoms. */
     stdnm = NULL;
     for (i = 0; standard_class_atoms[i].init; i++) {
         JS_ASSERT(standard_class_atoms[i].clasp);
-        atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
+        atom = OFFSET_TO_NAME(rt, standard_class_atoms[i].atomOffset);
         if (idstr == atom) {
             stdnm = &standard_class_atoms[i];
             break;
         }
     }
 
     if (!stdnm) {
         /* Try less frequently used top-level functions and constants. */
         for (i = 0; standard_class_names[i].init; i++) {
             JS_ASSERT(standard_class_names[i].clasp);
-            atom = StdNameToAtom(cx, &standard_class_names[i]);
+            atom = StdNameToPropertyName(cx, &standard_class_names[i]);
             if (!atom)
                 return JS_FALSE;
             if (idstr == atom) {
                 stdnm = &standard_class_names[i];
                 break;
             }
         }
 
         if (!stdnm && !obj->getProto()) {
             /*
              * Try even less frequently used names delegated from the global
              * object to Object.prototype, but only if the Object class hasn't
              * yet been initialized.
              */
             for (i = 0; object_prototype_names[i].init; i++) {
                 JS_ASSERT(object_prototype_names[i].clasp);
-                atom = StdNameToAtom(cx, &object_prototype_names[i]);
+                atom = StdNameToPropertyName(cx, &object_prototype_names[i]);
                 if (!atom)
                     return JS_FALSE;
                 if (idstr == atom) {
                     stdnm = &object_prototype_names[i];
                     break;
                 }
             }
         }
@@ -2002,17 +2002,17 @@ JS_EnumerateStandardClasses(JSContext *c
 
     RootedVarObject obj(cx, obj_);
 
     /*
      * Check whether we need to bind 'undefined' and define it if so.
      * Since ES5 15.1.1.3 undefined can't be deleted.
      */
     PropertyName *name = rt->atomState.typeAtoms[JSTYPE_VOID];
-    if (!obj->nativeContains(cx, ATOM_TO_JSID(name)) &&
+    if (!obj->nativeContains(cx, NameToId(name)) &&
         !obj->defineProperty(cx, name, UndefinedValue(),
                              JS_PropertyStub, JS_StrictPropertyStub,
                              JSPROP_PERMANENT | JSPROP_READONLY)) {
         return JS_FALSE;
     }
 
     /* Initialize any classes that have not been initialized yet. */
     for (i = 0; standard_class_atoms[i].init; i++) {
@@ -2053,47 +2053,47 @@ SetIdArrayLength(JSContext *cx, JSIdArra
         JS_DestroyIdArray(cx, ida);
     } else {
         rida->length = length;
     }
     return rida;
 }
 
 static JSIdArray *
-AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, int *ip)
+AddNameToArray(JSContext *cx, PropertyName *name, JSIdArray *ida, int *ip)
 {
     int i = *ip;
     int length = ida->length;
     if (i >= length) {
         ida = SetIdArrayLength(cx, ida, JS_MAX(length * 2, 8));
         if (!ida)
             return NULL;
         JS_ASSERT(i < ida->length);
     }
-    ida->vector[i].init(ATOM_TO_JSID(atom));
+    ida->vector[i].init(NameToId(name));
     *ip = i + 1;
     return ida;
 }
 
 static JSIdArray *
-EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida,
+EnumerateIfResolved(JSContext *cx, JSObject *obj, PropertyName *name, JSIdArray *ida,
                     int *ip, JSBool *foundp)
 {
-    *foundp = obj->nativeContains(cx, ATOM_TO_JSID(atom));
+    *foundp = obj->nativeContains(cx, NameToId(name));
     if (*foundp)
-        ida = AddAtomToArray(cx, atom, ida, ip);
+        ida = AddNameToArray(cx, name, ida, ip);
     return ida;
 }
 
 JS_PUBLIC_API(JSIdArray *)
 JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida)
 {
     JSRuntime *rt;
     int i, j, k;
-    JSAtom *atom;
+    PropertyName *name;
     JSBool found;
     JSObjectOp init;
 
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, ida);
     rt = cx->runtime;
     if (ida) {
@@ -2101,44 +2101,44 @@ JS_EnumerateResolvedStandardClasses(JSCo
     } else {
         ida = NewIdArray(cx, 8);
         if (!ida)
             return NULL;
         i = 0;
     }
 
     /* Check whether 'undefined' has been resolved and enumerate it if so. */
-    atom = rt->atomState.typeAtoms[JSTYPE_VOID];
-    ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
+    name = rt->atomState.typeAtoms[JSTYPE_VOID];
+    ida = EnumerateIfResolved(cx, obj, name, ida, &i, &found);
     if (!ida)
         return NULL;
 
     /* Enumerate only classes that *have* been resolved. */
     for (j = 0; standard_class_atoms[j].init; j++) {
-        atom = OFFSET_TO_ATOM(rt, standard_class_atoms[j].atomOffset);
-        ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
+        name = OFFSET_TO_NAME(rt, standard_class_atoms[j].atomOffset);
+        ida = EnumerateIfResolved(cx, obj, name, ida, &i, &found);
         if (!ida)
             return NULL;
 
         if (found) {
             init = standard_class_atoms[j].init;
 
             for (k = 0; standard_class_names[k].init; k++) {
                 if (standard_class_names[k].init == init) {
-                    atom = StdNameToAtom(cx, &standard_class_names[k]);
-                    ida = AddAtomToArray(cx, atom, ida, &i);
+                    name = StdNameToPropertyName(cx, &standard_class_names[k]);
+                    ida = AddNameToArray(cx, name, ida, &i);
                     if (!ida)
                         return NULL;
                 }
             }
 
             if (init == js_InitObjectClass) {
                 for (k = 0; object_prototype_names[k].init; k++) {
-                    atom = StdNameToAtom(cx, &object_prototype_names[k]);
-                    ida = AddAtomToArray(cx, atom, ida, &i);
+                    name = StdNameToPropertyName(cx, &object_prototype_names[k]);
+                    ida = AddNameToArray(cx, name, ida, &i);
                     if (!ida)
                         return NULL;
                 }
             }
         }
     }
 
     /* Trim to exact length. */
@@ -3450,17 +3450,16 @@ static JSBool
 LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                    JSObject **objp, JSProperty **propp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
 
     JSAutoResolveFlags rf(cx, flags);
-    id = js_CheckForStringIndex(id);
     return obj->lookupGeneric(cx, id, objp, propp);
 }
 
 #define AUTO_NAMELEN(s,n)   (((n) == (size_t)-1) ? js_strlen(s) : (n))
 
 static JSBool
 LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, jsid id,
              JSProperty *prop, Value *vp)
@@ -3516,24 +3515,24 @@ JS_LookupElement(JSContext *cx, JSObject
         return false;
     return JS_LookupPropertyById(cx, obj, id, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_LookupUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_LookupPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                                JSObject **objp, jsval *vp)
 {
     JSBool ok;
     JSProperty *prop;
@@ -3547,17 +3546,17 @@ JS_LookupPropertyWithFlagsById(JSContext
     return ok && LookupResult(cx, obj, *objp, id, prop, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, unsigned flags, jsval *vp)
 {
     JSObject *obj2;
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_LookupPropertyWithFlagsById(cx, obj, ATOM_TO_JSID(atom), flags, &obj2, vp);
+    return atom && JS_LookupPropertyWithFlagsById(cx, obj, AtomToId(atom), flags, &obj2, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_HasPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp)
 {
     JSObject *obj2;
     JSProperty *prop;
     JSBool ok = LookupPropertyById(cx, obj, id, JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING,
@@ -3576,24 +3575,24 @@ JS_HasElement(JSContext *cx, JSObject *o
         return false;
     return JS_HasPropertyById(cx, obj, id, foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
+    return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_HasUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, JSBool *foundp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_HasPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
+    return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
@@ -3624,25 +3623,25 @@ JS_AlreadyHasOwnElement(JSContext *cx, J
         return false;
     return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
+    return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
                            JSBool *foundp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_AlreadyHasOwnPropertyById(cx, obj, ATOM_TO_JSID(atom), foundp);
+    return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
 }
 
 static JSBool
 DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
                    PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                    unsigned flags, int tinyid)
 {
     /*
@@ -3736,17 +3735,17 @@ DefineProperty(JSContext *cx, JSObject *
 
     if (attrs & JSPROP_INDEX) {
         id = INT_TO_JSID(intptr_t(name));
         attrs &= ~JSPROP_INDEX;
     } else {
         JSAtom *atom = js_Atomize(cx, name, strlen(name));
         if (!atom)
             return JS_FALSE;
-        id = ATOM_TO_JSID(atom);
+        id = AtomToId(atom);
     }
 
     return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
                   PropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
@@ -3767,17 +3766,17 @@ DefineUCProperty(JSContext *cx, JSObject
                  unsigned flags, int tinyid)
 {
     RootedVarObject obj(cx, obj_);
     RootedVarValue value(cx, value_);
     RootGetterSetter gsRoot(cx, attrs, &getter, &setter);
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
-    RootedVarId id(cx, ATOM_TO_JSID(atom));
+    RootedVarId id(cx, AtomToId(atom));
     return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DefineUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
                     jsval value, JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
 {
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0, 0);
@@ -3933,47 +3932,47 @@ JS_GetPropertyAttrsGetterAndSetterById(J
     return true;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
                          unsigned *attrsp, JSBool *foundp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
+    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
                                                           attrsp, foundp, NULL, NULL);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
                            unsigned *attrsp, JSBool *foundp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
+    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
                                                           attrsp, foundp, NULL, NULL);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, const char *name,
                                    unsigned *attrsp, JSBool *foundp,
                                    JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
+    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
                                                           attrsp, foundp, getterp, setterp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
                                      const jschar *name, size_t namelen,
                                      unsigned *attrsp, JSBool *foundp,
                                      JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, ATOM_TO_JSID(atom),
+    return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
                                                           attrsp, foundp, getterp, setterp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
@@ -4001,25 +4000,25 @@ SetPropertyAttributesById(JSContext *cx,
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
                          unsigned attrs, JSBool *foundp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
+    return atom && SetPropertyAttributesById(cx, obj, AtomToId(atom), attrs, foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen,
                            unsigned attrs, JSBool *foundp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && SetPropertyAttributesById(cx, obj, ATOM_TO_JSID(atom), attrs, foundp);
+    return atom && SetPropertyAttributesById(cx, obj, AtomToId(atom), attrs, foundp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return JS_ForwardGetPropertyTo(cx, obj, id, obj, vp);
 }
 
@@ -4070,33 +4069,33 @@ JS_GetElementIfPresent(JSContext *cx, JS
     return true;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetProperty(JSContext *cx, JSObject *obj_, const char *name, jsval *vp)
 {
     RootedVarObject obj(cx, obj_);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyDefault(JSContext *cx, JSObject *obj_, const char *name, jsval def, jsval *vp)
 {
     RootedVarObject obj(cx, obj_);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp);
+    return atom && JS_GetPropertyByIdDefault(cx, obj, AtomToId(atom), def, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetUCProperty(JSContext *cx, JSObject *obj_, const jschar *name, size_t namelen, jsval *vp)
 {
     RootedVarObject obj(cx, obj_);
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, jsval *vp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
@@ -4106,17 +4105,17 @@ JS_GetMethodById(JSContext *cx, JSObject
         *objp = obj;
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, jsval *vp)
 {
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), objp, vp);
+    return atom && JS_GetMethodById(cx, obj, AtomToId(atom), objp, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
@@ -4137,24 +4136,24 @@ JS_SetElement(JSContext *cx, JSObject *o
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetProperty(JSContext *cx, JSObject *obj_, const char *name, jsval *vp)
 {
     RootedVarObject obj(cx, obj_);
     RootValue vpRoot(cx, vp);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_SetPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_SetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
+    return atom && JS_SetPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
@@ -4252,18 +4251,16 @@ JS_Enumerate(JSContext *cx, JSObject *ob
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     AutoIdVector props(cx);
     JSIdArray *ida;
     if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &props) || !VectorToIdArray(cx, props, &ida))
         return NULL;
-    for (size_t n = 0; n < size_t(ida->length); ++n)
-        JS_ASSERT(js_CheckForStringIndex(ida->vector[n]) == ida->vector[n]);
     return ida;
 }
 
 /*
  * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
  *     prop_iterator_class somehow...
  * + preserve the obj->enumerate API while optimizing the native object case
  * + native case here uses a Shape *, but that iterates in reverse!
@@ -4704,33 +4701,33 @@ JS_DefineFunctions(JSContext *cx, JSObje
 
             if (!ctor) {
                 ctor = JS_GetConstructor(cx, obj);
                 if (!ctor)
                     return JS_FALSE;
             }
 
             flags &= ~JSFUN_GENERIC_NATIVE;
-            fun = js_DefineFunction(cx, ctor, ATOM_TO_JSID(atom),
+            fun = js_DefineFunction(cx, ctor, AtomToId(atom),
                                     js_generic_native_method_dispatcher,
                                     fs->nargs + 1,
                                     flags,
                                     JSFunction::ExtendedFinalizeKind);
             if (!fun)
                 return JS_FALSE;
 
             /*
              * As jsapi.h notes, fs must point to storage that lives as long
              * as fun->object lives.
              */
             fun->setExtendedSlot(0, PrivateValue(fs));
         }
 
         fun = js_DefineFunction(cx, objRoot,
-                                ATOM_TO_JSID(atom), fs->call, fs->nargs, flags);
+                                AtomToId(atom), fs->call, fs->nargs, flags);
         if (!fun)
             return JS_FALSE;
     }
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
@@ -4740,34 +4737,34 @@ JS_DefineFunction(JSContext *cx, JSObjec
 
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     if (!atom)
         return NULL;
-    return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs);
+    return js_DefineFunction(cx, objRoot, AtomToId(atom), call, nargs, attrs);
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_DefineUCFunction(JSContext *cx, JSObject *obj,
                     const jschar *name, size_t namelen, JSNative call,
                     unsigned nargs, unsigned attrs)
 {
     RootObject objRoot(cx, &obj);
 
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return NULL;
-    return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs);
+    return js_DefineFunction(cx, objRoot, AtomToId(atom), call, nargs, attrs);
 }
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunctionById(JSContext *cx, JSObject *obj, jsid id, JSNative call,
                     unsigned nargs, unsigned attrs)
 {
     RootObject objRoot(cx, &obj);
 
@@ -5124,17 +5121,17 @@ CompileUCFunctionForPrincipalsCommon(JSC
 
     if (!frontend::CompileFunctionBody(cx, fun, principals, NULL, &bindings,
                                        chars, length, filename, lineno, version))
     {
         return NULL;
     }
 
     if (obj && funAtom &&
-        !obj->defineGeneric(cx, ATOM_TO_JSID(funAtom), ObjectValue(*fun), NULL, NULL,
+        !obj->defineGeneric(cx, AtomToId(funAtom), ObjectValue(*fun), NULL, NULL,
                             JSPROP_ENUMERATE))
     {
         return NULL;
     }
 
     return fun;
 }
 
@@ -5426,17 +5423,17 @@ JS_CallFunctionName(JSContext *cx, JSObj
     assertSameCompartment(cx, obj_, JSValueArray(argv, argc));
     AutoLastFrameCheck lfc(cx);
 
     RootedVarObject obj(cx, obj_);
 
     Value v;
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     return atom &&
-           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &v) &&
+           js_GetMethod(cx, obj, AtomToId(atom), 0, &v) &&
            Invoke(cx, ObjectOrNullValue(obj), v, argc, argv, rval);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, unsigned argc, jsval *argv,
                      jsval *rval)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
@@ -5598,16 +5595,25 @@ JS_StringHasBeenInterned(JSContext *cx, 
     CHECK_REQUEST(cx);
 
     if (!str->isAtom())
         return false;
 
     return AtomIsInterned(cx, &str->asAtom());
 }
 
+JS_PUBLIC_API(jsid)
+INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
+{
+    JS_ASSERT(str);
+    JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
+    JS_ASSERT_IF(cx, JS_StringHasBeenInterned(cx, str));
+    return AtomToId(&str->asAtom());
+}
+
 JS_PUBLIC_API(JSString *)
 JS_InternJSString(JSContext *cx, JSString *str)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     JSAtom *atom = js_AtomizeString(cx, str, InternAtom);
     JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
     return atom;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1977,56 +1977,39 @@ JS_StringHasBeenInterned(JSContext *cx, 
 
 /*
  * 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
-INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str)
-{
-    jsid id;
-    JS_ASSERT(str);
-    JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
-#ifdef DEBUG
-    JS_ASSERT(JS_StringHasBeenInterned(cx, str));
-#else
-    (void)cx;
-#endif
-    JSID_BITS(id) = (size_t)str;
-    return id;
-}
+JS_PUBLIC_API(jsid)
+INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str);
 
 static JS_ALWAYS_INLINE JSBool
 JSID_IS_INT(jsid id)
 {
     return !!(JSID_BITS(id) & JSID_TYPE_INT);
 }
 
 static JS_ALWAYS_INLINE int32_t
 JSID_TO_INT(jsid id)
 {
     JS_ASSERT(JSID_IS_INT(id));
-    return ((int32_t)JSID_BITS(id)) >> 1;
+    return ((uint32_t)JSID_BITS(id)) >> 1;
 }
 
-/*
- * Note: when changing these values, verify that their use in
- * js_CheckForStringIndex is still valid.
- */
-#define JSID_INT_MIN  (-(1 << 30))
-#define JSID_INT_MAX  ((1 << 30) - 1)
+#define JSID_INT_MIN  0
+#define JSID_INT_MAX  ((1 << 31) - 1)
 
 static JS_ALWAYS_INLINE JSBool
 INT_FITS_IN_JSID(int32_t i)
 {
-    return ((uint32_t)(i) - (uint32_t)JSID_INT_MIN <=
-            (uint32_t)(JSID_INT_MAX - JSID_INT_MIN));
+    return i >= 0;
 }
 
 static JS_ALWAYS_INLINE jsid
 INT_TO_JSID(int32_t i)
 {
     jsid id;
     JS_ASSERT(INT_FITS_IN_JSID(i));
     JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -269,17 +269,17 @@ BigIndexToId(JSContext *cx, JSObject *ob
             return JS_TRUE;
         }
     } else {
         atom = js_AtomizeChars(cx, start, ArrayEnd(buf) - start);
         if (!atom)
             return JS_FALSE;
     }
 
-    *idp = ATOM_TO_JSID(atom);
+    *idp = NON_INTEGER_ATOM_TO_JSID(atom);
     return JS_TRUE;
 }
 
 bool
 JSObject::willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint)
 {
     JS_ASSERT(isDenseArray());
     JS_ASSERT(requiredCapacity > MIN_SPARSE_INDEX);
@@ -305,17 +305,17 @@ JSObject::willBeSparseDenseArray(unsigne
             return false;
     }
     return true;
 }
 
 static bool
 ReallyBigIndexToId(JSContext* cx, double index, jsid* idp)
 {
-    return js_ValueToStringId(cx, DoubleValue(index), idp);
+    return ValueToId(cx, DoubleValue(index), idp);
 }
 
 static bool
 IndexToId(JSContext* cx, JSObject* obj, double index, JSBool* hole, jsid* idp,
           JSBool createAtom = JS_FALSE)
 {
     if (index <= JSID_INT_MAX) {
         *idp = INT_TO_JSID(int(index));
@@ -744,17 +744,17 @@ array_lookupGeneric(JSContext *cx, JSObj
     }
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 static JSBool
 array_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
                      JSProperty **propp)
 {
-    return array_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return array_lookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 static JSBool
 array_lookupElement(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp,
                     JSProperty **propp)
 {
     if (!obj->isDenseArray())
         return js_LookupElement(cx, obj, index, objp, propp);
@@ -808,17 +808,17 @@ array_getProperty(JSContext *cx, JSObjec
         return true;
     }
 
     if (!obj->isDenseArray())
     {
         return js_GetProperty(cx,
                               RootedVarObject(cx, obj),
                               RootedVarObject(cx, receiver),
-                              ATOM_TO_JSID(name),
+                              NameToId(name),
                               vp);
     }
 
     JSObject *proto = obj->getProto();
     if (!proto) {
         vp->setUndefined();
         return true;
     }
@@ -951,17 +951,17 @@ array_setGeneric(JSContext *cx, JSObject
     if (!JSObject::makeDenseArraySlow(cx, obj))
         return false;
     return js_SetPropertyHelper(cx, obj, id, 0, vp, strict);
 }
 
 static JSBool
 array_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
 {
-    return array_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
+    return array_setGeneric(cx, obj, NameToId(name), vp, strict);
 }
 
 static JSBool
 array_setElement(JSContext *cx, JSObject *obj_, uint32_t index, Value *vp, JSBool strict)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
@@ -1064,17 +1064,17 @@ array_defineGeneric(JSContext *cx, JSObj
         return false;
     return js_DefineProperty(cx, obj, id, value, getter, setter, attrs);
 }
 
 static JSBool
 array_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *value,
                      JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    return array_defineGeneric(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs);
+    return array_defineGeneric(cx, obj, NameToId(name), value, getter, setter, attrs);
 }
 
 namespace js {
 
 /* non-static for direct definition of array elements within the engine */
 JSBool
 array_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
@@ -1344,17 +1344,17 @@ AddLengthProperty(JSContext *cx, JSObjec
 {
     /*
      * Add the 'length' property for a newly created or converted slow array,
      * and update the elements to be an empty array owned by the object.
      * The shared emptyObjectElements singleton cannot be used for slow arrays,
      * as accesses to 'length' will use the elements header.
      */
 
-    const jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    const jsid lengthId = NameToId(cx->runtime->atomState.lengthAtom);
     JS_ASSERT(!obj->nativeLookup(cx, lengthId));
 
     if (!obj->allocateSlowArrayElements(cx))
         return false;
 
     return obj->addProperty(cx, lengthId, array_length_getter, array_length_setter,
                             SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0, 0);
 }
@@ -1680,17 +1680,17 @@ array_toString_sub(JSContext *cx, Handle
             if (!GetElement(cx, obj, index, &hole, &elt))
                 return false;
 
             if (!hole && !elt.isNullOrUndefined()) {
                 if (locale) {
                     JSObject *robj = ToObject(cx, &elt);
                     if (!robj)
                         return false;
-                    jsid id = ATOM_TO_JSID(cx->runtime->atomState.toLocaleStringAtom);
+                    jsid id = NameToId(cx->runtime->atomState.toLocaleStringAtom);
                     if (!robj->callMethod(cx, id, 0, NULL, &elt))
                         return false;
                 }
                 if (!ValueToStringBuffer(cx, elt, sb))
                     return false;
             }
 
             if (index + 1 != length) {
@@ -1842,17 +1842,17 @@ InitArrayElements(JSContext *cx, HandleO
         return false;
 
     JS_ASSERT(start == MAX_ARRAY_INDEX + 1);
     RootedVarValue value(cx);
     RootedVarId id(cx);
     Value idval = DoubleValue(MAX_ARRAY_INDEX + 1);
     do {
         value = *vector++;
-        if (!js_ValueToStringId(cx, idval, id.address()) ||
+        if (!ValueToId(cx, idval, id.address()) ||
             !obj->setGeneric(cx, id, value.address(), true)) {
             return false;
         }
         idval.getDoubleRef() += 1;
     } while (vector != end);
 
     return true;
 }
@@ -3724,17 +3724,17 @@ js_InitArrayClass(JSContext *cx, JSObjec
 
     RootedVarObject arrayProto(cx);
     arrayProto = global->createBlankPrototype(cx, &SlowArrayClass);
     if (!arrayProto || !AddLengthProperty(cx, arrayProto))
         return NULL;
     arrayProto->setArrayLength(cx, 0);
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, js_Array, CLASS_ATOM(cx, Array), 1);
+    ctor = global->createConstructor(cx, js_Array, CLASS_NAME(cx, Array), 1);
     if (!ctor)
         return NULL;
 
     /*
      * The default 'new' type of Array.prototype is required by type inference
      * to have unknown properties, to simplify handling of e.g. heterogenous
      * arrays in JSON and script literals and allows setDenseArrayElement to
      * be used without updating the indexed type set for such default arrays.
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -535,135 +535,58 @@ IndexToIdSlow(JSContext *cx, uint32_t in
     jschar buf[UINT32_CHAR_BUFFER_LENGTH];
     RangedPtr<jschar> end(ArrayEnd(buf), buf, ArrayEnd(buf));
     RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
 
     JSAtom *atom = js_AtomizeChars(cx, start.get(), end - start);
     if (!atom)
         return false;
 
-    *idp = ATOM_TO_JSID(atom);
-    JS_ASSERT(js_CheckForStringIndex(*idp) == *idp);
+    *idp = JSID_FROM_BITS((size_t)atom);
+    return true;
+}
+
+bool
+InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
+                      jsid *idp, Value *vp)
+{
+#if JS_HAS_XML_SUPPORT
+    if (idval.isObject()) {
+        JSObject *idobj = &idval.toObject();
+
+        if (obj && obj->isXML()) {
+            *idp = OBJECT_TO_JSID(idobj);
+            *vp = idval;
+            return true;
+        }
+
+        if (js_GetLocalNameFromFunctionQName(idobj, idp, cx)) {
+            *vp = IdToValue(*idp);
+            return true;
+        }
+
+        if (!obj && idobj->isXMLId()) {
+            *idp = OBJECT_TO_JSID(idobj);
+            *vp = idval;
+            return JS_TRUE;
+        }
+    }
+#endif
+
+    JSAtom *atom;
+    if (!js_ValueToAtom(cx, idval, &atom))
+        return false;
+
+    *idp = AtomToId(atom);
+    vp->setString(atom);
     return true;
 }
 
 } /* namespace js */
 
-/* JSBOXEDWORD_INT_MAX as a string */
-#define JSBOXEDWORD_INT_MAX_STRING "1073741823"
-
-/*
- * Convert string indexes that convert to int jsvals as ints to save memory.
- * Care must be taken to use this macro every time a property name is used, or
- * else double-sets, incorrect property cache misses, or other mistakes could
- * occur.
- */
-jsid
-js_CheckForStringIndex(jsid id)
-{
-    if (!JSID_IS_ATOM(id))
-        return id;
-
-    JSAtom *atom = JSID_TO_ATOM(id);
-    const jschar *s = atom->chars();
-    jschar ch = *s;
-
-    JSBool negative = (ch == '-');
-    if (negative)
-        ch = *++s;
-
-    if (!JS7_ISDEC(ch))
-        return id;
-
-    size_t n = atom->length() - negative;
-    if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
-        return id;
-
-    const jschar *cp = s;
-    const jschar *end = s + n;
-
-    uint32_t index = JS7_UNDEC(*cp++);
-    uint32_t oldIndex = 0;
-    uint32_t c = 0;
-
-    if (index != 0) {
-        while (JS7_ISDEC(*cp)) {
-            oldIndex = index;
-            c = JS7_UNDEC(*cp);
-            index = 10 * index + c;
-            cp++;
-        }
-    }
-
-    /*
-     * Non-integer indexes can't be represented as integers.  Also, distinguish
-     * index "-0" from "0", because JSBOXEDWORD_INT cannot.
-     */
-    if (cp != end || (negative && index == 0))
-        return id;
-
-    if (negative) {
-        if (oldIndex < -(JSID_INT_MIN / 10) ||
-            (oldIndex == -(JSID_INT_MIN / 10) && c <= (-JSID_INT_MIN % 10)))
-        {
-            id = INT_TO_JSID(-int32_t(index));
-        }
-    } else {
-        if (oldIndex < JSID_INT_MAX / 10 ||
-            (oldIndex == JSID_INT_MAX / 10 && c <= (JSID_INT_MAX % 10)))
-        {
-            id = INT_TO_JSID(int32_t(index));
-        }
-    }
-
-    return id;
-}
-
-#if JS_HAS_XML_SUPPORT
-bool
-js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
-                             jsid *idp)
-{
-    JS_ASSERT(idval.isObject());
-    if (obj->isXML()) {
-        *idp = OBJECT_TO_JSID(&idval.toObject());
-        return true;
-    }
-
-    if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx))
-        return true;
-
-    return js_ValueToStringId(cx, idval, idp);
-}
-
-bool
-js_InternNonIntElementIdSlow(JSContext *cx, JSObject *obj, const Value &idval,
-                             jsid *idp, Value *vp)
-{
-    JS_ASSERT(idval.isObject());
-    if (obj->isXML()) {
-        JSObject &idobj = idval.toObject();
-        *idp = OBJECT_TO_JSID(&idobj);
-        vp->setObject(idobj);
-        return true;
-    }
-
-    if (js_GetLocalNameFromFunctionQName(&idval.toObject(), idp, cx)) {
-        *vp = IdToValue(*idp);
-        return true;
-    }
-
-    if (js_ValueToStringId(cx, idval, idp)) {
-        vp->setString(JSID_TO_STRING(*idp));
-        return true;
-    }
-    return false;
-}
-#endif
-
 template<XDRMode mode>
 bool
 js::XDRAtom(XDRState<mode> *xdr, JSAtom **atomp)
 {
     if (mode == XDR_ENCODE) {
         uint32_t nchars = (*atomp)->length();
         if (!xdr->codeUint32(&nchars))
             return false;
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -62,54 +62,73 @@ struct JSIdArray {
 static JS_ALWAYS_INLINE jsid
 JSID_FROM_BITS(size_t bits)
 {
     jsid id;
     JSID_BITS(id) = bits;
     return id;
 }
 
+/*
+ * Must not be used on atoms that are representable as integer jsids.
+ * Prefer NameToId or AtomToId over this function:
+ *
+ * A PropertyName is an atom that does not contain an integer in the range
+ * [0, UINT32_MAX]. However, jsid can only hold an integer in the range
+ * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1).  Thus, for the range of
+ * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
+ * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName().  In most
+ * cases when creating a jsid, code does not have to care about this corner
+ * case because:
+ *
+ * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
+ *   integer atoms representable as integer jsids, and does this conversion.
+ *
+ * - When given a PropertyName*, NameToId can be used which which does not need
+ *   to do any dynamic checks.
+ *
+ * Thus, it is only the rare third case which needs this function, which
+ * handles any JSAtom* that is known not to be representable with an int jsid.
+ */
 static JS_ALWAYS_INLINE jsid
-ATOM_TO_JSID(JSAtom *atom)
+NON_INTEGER_ATOM_TO_JSID(JSAtom *atom)
 {
     JS_ASSERT(((size_t)atom & 0x7) == 0);
-    return JSID_FROM_BITS((size_t)atom);
+    jsid id = JSID_FROM_BITS((size_t)atom);
+    JS_ASSERT(id == INTERNED_STRING_TO_JSID(NULL, (JSString*)atom));
+    return id;
 }
 
-/* All strings stored in jsids are atomized. */
+/* All strings stored in jsids are atomized, but are not necessarily property names. */
 static JS_ALWAYS_INLINE JSBool
 JSID_IS_ATOM(jsid id)
 {
     return JSID_IS_STRING(id);
 }
 
 static JS_ALWAYS_INLINE JSBool
 JSID_IS_ATOM(jsid id, JSAtom *atom)
 {
-    return JSID_BITS(id) == JSID_BITS(ATOM_TO_JSID(atom));
+    return id == JSID_FROM_BITS((size_t)atom);
 }
 
 static JS_ALWAYS_INLINE JSAtom *
 JSID_TO_ATOM(jsid id)
 {
     return (JSAtom *)JSID_TO_STRING(id);
 }
 
-extern jsid
-js_CheckForStringIndex(jsid id);
-
 JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4);
 JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
 
 namespace js {
 
 static JS_ALWAYS_INLINE JSHashNumber
 HashId(jsid id)
 {
-    JS_ASSERT(js_CheckForStringIndex(id) == id);
     JSHashNumber n =
 #if JS_BYTES_PER_WORD == 4
         JSHashNumber(JSID_BITS(id));
 #elif JS_BYTES_PER_WORD == 8
         JSHashNumber(JSID_BITS(id)) ^ JSHashNumber(JSID_BITS(id) >> 32);
 #else
 # error "Unsupported configuration"
 #endif
@@ -135,21 +154,19 @@ IdToJsval(jsid id)
     return IdToValue(id);
 }
 
 template<>
 struct DefaultHasher<jsid>
 {
     typedef jsid Lookup;
     static HashNumber hash(const Lookup &l) {
-        JS_ASSERT(l == js_CheckForStringIndex(l));
         return HashNumber(JSID_BITS(l));
     }
     static bool match(const jsid &id, const Lookup &l) {
-        JS_ASSERT(l == js_CheckForStringIndex(l));
         return id == l;
     }
 };
 
 }
 
 #if JS_BYTES_PER_WORD == 4
 # define ATOM_HASH(atom)          ((JSHashNumber)(atom) >> 2)
@@ -344,20 +361,20 @@ AtomIsInterned(JSContext *cx, JSAtom *at
 
 #define COMMON_ATOM_INDEX(name)                                               \
     ((offsetof(JSAtomState, name##Atom) - JSAtomState::commonAtomsOffset)     \
      / sizeof(JSAtom*))
 #define COMMON_TYPE_ATOM_INDEX(type)                                          \
     ((offsetof(JSAtomState, typeAtoms[type]) - JSAtomState::commonAtomsOffset)\
      / sizeof(JSAtom*))
 
-#define ATOM_OFFSET(name)       offsetof(JSAtomState, name##Atom)
-#define OFFSET_TO_ATOM(rt,off)  (*(JSAtom **)((char*)&(rt)->atomState + (off)))
-#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
-#define CLASS_ATOM(cx,name)     ((cx)->runtime->atomState.classAtoms[JSProto_##name])
+#define NAME_OFFSET(name)       offsetof(JSAtomState, name##Atom)
+#define OFFSET_TO_NAME(rt,off)  (*(js::PropertyName **)((char*)&(rt)->atomState + (off)))
+#define CLASS_NAME_OFFSET(name) offsetof(JSAtomState, classAtoms[JSProto_##name])
+#define CLASS_NAME(cx,name)     ((cx)->runtime->atomState.classAtoms[JSProto_##name])
 
 extern const char *const js_common_atom_names[];
 extern const size_t      js_common_atom_count;
 
 /*
  * Macros to access C strings for JSType and boolean literals.
  */
 #define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + (type)])
@@ -455,27 +472,28 @@ js_GetExistingStringAtom(JSContext *cx, 
 extern JS_FRIEND_API(void)
 js_DumpAtoms(JSContext *cx, FILE *fp);
 
 #endif
 
 inline bool
 js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp);
 
-inline bool
-js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp);
+namespace js {
+
+bool
+InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
+                      jsid *idp, Value *vp);
 
 inline bool
-js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
-                         jsid *idp);
-inline bool
-js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
-                         jsid *idp, js::Value *vp);
-
-namespace js {
+InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid *idp)
+{
+    Value dummy;
+    return InternNonIntElementId(cx, obj, idval, idp, &dummy);
+}
 
 /*
  * For all unmapped atoms recorded in al, add a mapping from the atom's index
  * to its address. map->length must already be set to the number of atoms in
  * the list and map->vector must point to pre-allocated memory.
  */
 extern void
 InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtr<JSAtom> *atoms);
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -74,83 +74,36 @@ js_ValueToAtom(JSContext *cx, const js::
         *atomp = &str->asAtom();
         return true;
     }
 
     *atomp = js_AtomizeString(cx, str);
     return !!*atomp;
 }
 
-inline bool
-js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
-{
-    JSAtom *atom;
-    if (js_ValueToAtom(cx, v, &atom)) {
-        *idp = ATOM_TO_JSID(atom);
-        return true;
-    }
-    return false;
-}
+namespace js {
 
 inline bool
-js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
-                         jsid *idp)
+ValueToId(JSContext* cx, JSObject *obj, const Value &v, jsid *idp)
 {
-    JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
+    int32_t i;
+    if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
+        *idp = INT_TO_JSID(i);
+        return true;
+    }
 
-#if JS_HAS_XML_SUPPORT
-    extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
-                                             const js::Value &, jsid *);
-    if (idval.isObject())
-        return js_InternNonIntElementIdSlow(cx, obj, idval, idp);
-#endif
-
-    return js_ValueToStringId(cx, idval, idp);
+    return InternNonIntElementId(cx, obj, v, idp);
 }
 
 inline bool
-js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
-                         jsid *idp, js::Value *vp)
+ValueToId(JSContext* cx, const Value &v, jsid *idp)
 {
-    JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
-
-#if JS_HAS_XML_SUPPORT
-    extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
-                                             const js::Value &,
-                                             jsid *, js::Value *);
-    if (idval.isObject())
-        return js_InternNonIntElementIdSlow(cx, obj, idval, idp, vp);
-#endif
-
-    JSAtom *atom;
-    if (js_ValueToAtom(cx, idval, &atom)) {
-        *idp = ATOM_TO_JSID(atom);
-        vp->setString(atom);
-        return true;
-    }
-    return false;
+    return ValueToId(cx, NULL, v, idp);
 }
 
-inline bool
-js_Int32ToId(JSContext* cx, int32_t index, jsid* id)
-{
-    if (INT_FITS_IN_JSID(index)) {
-        *id = INT_TO_JSID(index);
-        return true;
-    }
-
-    JSString* str = js_NumberToString(cx, index);
-    if (!str)
-        return false;
-
-    return js_ValueToStringId(cx, js::StringValue(str), id);
-}
-
-namespace js {
-
 /*
  * Write out character representing |index| to the memory just before |end|.
  * Thus |*end| is not touched, but |end[-1]| and earlier are modified as
  * appropriate.  There must be at least js::UINT32_CHAR_BUFFER_LENGTH elements
  * before |end| to avoid buffer underflow.  The start of the characters written
  * is returned and is necessarily before |end|.
  */
 template <typename T>
@@ -184,16 +137,28 @@ IndexToId(JSContext *cx, uint32_t index,
         *idp = INT_TO_JSID(index);
         return true;
     }
 
     extern bool IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp);
     return IndexToIdSlow(cx, index, idp);
 }
 
+inline jsid
+AtomToId(JSAtom *atom)
+{
+    JS_STATIC_ASSERT(JSID_INT_MIN == 0);
+
+    uint32_t index;
+    if (atom->isIndex(&index) && index <= JSID_INT_MAX)
+        return INT_TO_JSID((int32_t) index);
+
+    return JSID_FROM_BITS((size_t)atom);
+}
+
 static JS_ALWAYS_INLINE JSFlatString *
 IdToString(JSContext *cx, jsid id)
 {
     if (JSID_IS_STRING(id))
         return JSID_TO_ATOM(id);
 
     JSString *str;
      if (JS_LIKELY(JSID_IS_INT(id)))
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -162,17 +162,17 @@ js_InitBooleanClass(JSContext *cx, JSObj
     RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedVarObject booleanProto (cx, global->createBlankPrototype(cx, &BooleanClass));
     if (!booleanProto)
         return NULL;
     booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false));
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, Boolean, CLASS_ATOM(cx, Boolean), 1);
+    ctor = global->createConstructor(cx, Boolean, CLASS_NAME(cx, Boolean), 1);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, booleanProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, booleanProto, NULL, boolean_methods))
         return NULL;
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -939,17 +939,17 @@ JSStructuredCloneReader::readId(jsid *id
     }
     if (tag == SCTAG_STRING) {
         JSString *str = readString(data);
         if (!str)
             return false;
         JSAtom *atom = js_AtomizeString(context(), str);
         if (!atom)
             return false;
-        *idp = ATOM_TO_JSID(atom);
+        *idp = NON_INTEGER_ATOM_TO_JSID(atom);
         return true;
     }
     if (tag == SCTAG_NULL) {
         *idp = JSID_VOID;
         return true;
     }
     JS_ReportErrorNumber(context(), js_GetErrorMessage, NULL, JSMSG_SC_BAD_SERIALIZED_DATA, "id");
     return false;
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -521,18 +521,18 @@ js_ReportErrorVA(JSContext *cx, unsigned
 
 namespace js {
 
 /* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
 void
 ReportUsageError(JSContext *cx, JSObject *callee, const char *msg)
 {
     const char *usageStr = "usage";
-    JSAtom *usageAtom = js_Atomize(cx, usageStr, strlen(usageStr));
-    DebugOnly<const Shape *> shape = callee->nativeLookup(cx, ATOM_TO_JSID(usageAtom));
+    PropertyName *usageAtom = js_Atomize(cx, usageStr, strlen(usageStr))->asPropertyName();
+    DebugOnly<const Shape *> shape = callee->nativeLookup(cx, NameToId(usageAtom));
     JS_ASSERT(!shape->configurable());
     JS_ASSERT(!shape->writable());
     JS_ASSERT(shape->hasDefaultGetter());
 
     jsval usage;
     if (!JS_LookupProperty(cx, callee, "usage", &usage))
         return;
 
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2670,17 +2670,17 @@ js_InitDateClass(JSContext *cx, JSObject
     RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedVarObject dateProto(cx, global->createBlankPrototype(cx, &DateClass));
     if (!dateProto)
         return NULL;
     SetDateToNaN(cx, dateProto);
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, js_Date, CLASS_ATOM(cx, Date), MAXARGS);
+    ctor = global->createConstructor(cx, js_Date, CLASS_NAME(cx, Date), MAXARGS);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, dateProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, ctor, NULL, date_static_methods))
         return NULL;
@@ -2688,18 +2688,18 @@ js_InitDateClass(JSContext *cx, JSObject
     /*
      * Define all Date.prototype.* functions, then brand for trace-jitted code.
      * Date.prototype.toGMTString has the same initial value as
      * Date.prototype.toUTCString.
      */
     if (!JS_DefineFunctions(cx, dateProto, date_methods))
         return NULL;
     Value toUTCStringFun;
-    jsid toUTCStringId = ATOM_TO_JSID(cx->runtime->atomState.toUTCStringAtom);
-    jsid toGMTStringId = ATOM_TO_JSID(cx->runtime->atomState.toGMTStringAtom);
+    jsid toUTCStringId = NameToId(cx->runtime->atomState.toUTCStringAtom);
+    jsid toGMTStringId = NameToId(cx->runtime->atomState.toGMTStringAtom);
     if (!js_GetProperty(cx, dateProto, toUTCStringId, &toUTCStringFun) ||
         !js_DefineProperty(cx, dateProto, toGMTStringId, &toUTCStringFun,
                            JS_PropertyStub, JS_StrictPropertyStub, 0))
     {
         return NULL;
     }
 
     if (!DefineConstructorAndPrototype(cx, global, JSProto_Date, ctor, dateProto))
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -258,17 +258,16 @@ JS_ClearInterrupt(JSRuntime *rt, JSInter
 
 /************************************************************************/
 
 JS_PUBLIC_API(JSBool)
 JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id,
                  JSWatchPointHandler handler, JSObject *closure_)
 {
     assertSameCompartment(cx, obj_);
-    id = js_CheckForStringIndex(id);
 
     RootedVarObject obj(cx, obj_), closure(cx, closure_);
 
     JSObject *origobj;
     Value v;
     unsigned attrs;
 
     origobj = obj;
@@ -279,19 +278,18 @@ JS_SetWatchPoint(JSContext *cx, JSObject
     RootedVarId propid(cx);
 
     if (JSID_IS_INT(id)) {
         propid = id;
     } else if (JSID_IS_OBJECT(id)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH_PROP);
         return false;
     } else {
-        if (!js_ValueToStringId(cx, IdToValue(id), propid.address()))
+        if (!ValueToId(cx, IdToValue(id), propid.address()))
             return false;
-        propid = js_CheckForStringIndex(propid);
     }
 
     /*
      * If, by unwrapping and innerizing, we changed the object, check
      * again to make sure that we're allowed to set a watch point.
      */
     if (origobj != obj && !CheckAccess(cx, obj, propid, JSACC_WATCH, &v, &attrs))
         return false;
@@ -317,17 +315,16 @@ JS_SetWatchPoint(JSContext *cx, JSObject
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
                    JSWatchPointHandler *handlerp, JSObject **closurep)
 {
     assertSameCompartment(cx, obj, id);
 
-    id = js_CheckForStringIndex(id);
     if (WatchpointMap *wpmap = cx->compartment->watchpointMap)
         wpmap->unwatch(obj, id, handlerp, closurep);
     return true;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
 {
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -296,17 +296,17 @@ InitExnPrivate(JSContext *cx, HandleObje
             StackFrame *fp = i.fp();
 
             /*
              * Ask the crystal CAPS ball whether we can see across compartments.
              * NB: this means 'fp' may point to cross-compartment frames.
              */
             if (checkAccess && i.isNonEvalFunctionFrame()) {
                 Value v = NullValue();
-                jsid callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
+                jsid callerid = NameToId(cx->runtime->atomState.callerAtom);
                 if (!checkAccess(cx, i.callee(), callerid, JSACC_READ, &v))
                     break;
             }
 
             if (!frames.growBy(1))
                 return false;
             JSStackTraceStackElem &frame = frames.back();
             if (i.isNonEvalFunctionFrame())
@@ -710,17 +710,17 @@ exn_toString(JSContext *cx, unsigned arg
     /* Step 3. */
     Value nameVal;
     if (!obj.getProperty(cx, cx->runtime->atomState.nameAtom, &nameVal))
         return false;
 
     /* Step 4. */
     RootedVarString name(cx);
     if (nameVal.isUndefined()) {
-        name = CLASS_ATOM(cx, Error);
+        name = CLASS_NAME(cx, Error);
     } else {
         name = ToString(cx, nameVal);
         if (!name)
             return false;
     }
 
     /* Step 5. */
     Value msgVal;
@@ -734,17 +734,17 @@ exn_toString(JSContext *cx, unsigned arg
     } else {
         message = ToString(cx, msgVal);
         if (!message)
             return false;
     }
 
     /* Step 7. */
     if (name->empty() && message->empty()) {
-        args.rval().setString(CLASS_ATOM(cx, Error));
+        args.rval().setString(CLASS_NAME(cx, Error));
         return true;
     }
 
     /* Step 8. */
     if (name->empty()) {
         args.rval().setString(message);
         return true;
     }
@@ -870,20 +870,20 @@ InitErrorClass(JSContext *cx, Handle<Glo
 {
     JSProtoKey key = GetExceptionProtoKey(type);
     RootedVarAtom name(cx, cx->runtime->atomState.classAtoms[key]);
     RootedVarObject errorProto(cx, global->createBlankPrototypeInheriting(cx, &ErrorClass, *proto));
     if (!errorProto)
         return NULL;
 
     RootedVarValue empty(cx, StringValue(cx->runtime->emptyString));
-    RootedVarId nameId(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom));
-    RootedVarId messageId(cx, ATOM_TO_JSID(cx->runtime->atomState.messageAtom));
-    RootedVarId fileNameId(cx, ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom));
-    RootedVarId lineNumberId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom));
+    RootedVarId nameId(cx, NameToId(cx->runtime->atomState.nameAtom));
+    RootedVarId messageId(cx, NameToId(cx->runtime->atomState.messageAtom));
+    RootedVarId fileNameId(cx, NameToId(cx->runtime->atomState.fileNameAtom));
+    RootedVarId lineNumberId(cx, NameToId(cx->runtime->atomState.lineNumberAtom));
     if (!DefineNativeProperty(cx, errorProto, nameId, StringValue(name),
                               JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) ||
         !DefineNativeProperty(cx, errorProto, messageId, empty,
                               JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) ||
         !DefineNativeProperty(cx, errorProto, fileNameId, empty,
                               JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE, 0, 0) ||
         !DefineNativeProperty(cx, errorProto, lineNumberId, Int32Value(0),
                               JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE, 0, 0))
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -219,18 +219,18 @@ JS_DefineFunctionsWithHelp(JSContext *cx
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     for (; fs->name; fs++) {
         JSAtom *atom = js_Atomize(cx, fs->name, strlen(fs->name));
         if (!atom)
             return false;
 
         RootedVarFunction fun(cx);
-        fun = js_DefineFunction(cx, objRoot,
-                                ATOM_TO_JSID(atom), fs->call, fs->nargs, fs->flags);
+        fun = js_DefineFunction(cx, objRoot, AtomToId(atom),
+                                fs->call, fs->nargs, fs->flags);
         if (!fun)
             return false;
 
         if (fs->usage) {
             if (!DefineHelpProperty(cx, fun, "usage", fs->usage))
                 return false;
         }
 
@@ -320,17 +320,18 @@ js::DefineFunctionWithReserved(JSContext
     RootObject objRoot(cx, &obj);
 
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     if (!atom)
         return NULL;
-    return js_DefineFunction(cx, objRoot, ATOM_TO_JSID(atom), call, nargs, attrs,
+    return js_DefineFunction(cx, objRoot, AtomToId(atom),
+                             call, nargs, attrs,
                              JSFunction::ExtendedFinalizeKind);
 }
 
 JS_FRIEND_API(JSFunction *)
 js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
                             JSObject *parent, const char *name)
 {
     RootObject parentRoot(cx, &parent);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -199,47 +199,47 @@ fun_getProperty(JSContext *cx, JSObject 
     return false;
 }
 
 
 
 /* NB: no sentinels at ends -- use ArrayLength to bound loops.
  * Properties censored into [[ThrowTypeError]] in strict mode. */
 static const uint16_t poisonPillProps[] = {
-    ATOM_OFFSET(arguments),
-    ATOM_OFFSET(caller),
+    NAME_OFFSET(arguments),
+    NAME_OFFSET(caller),
 };
 
 static JSBool
 fun_enumerate(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isFunction());
 
     RootObject root(cx, &obj);
 
     jsid id;
     bool found;
 
     if (!obj->isBoundFunction()) {
-        id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+        id = NameToId(cx->runtime->atomState.classPrototypeAtom);
         if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
             return false;
     }
 
-    id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    id = NameToId(cx->runtime->atomState.lengthAtom);
     if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
         return false;
         
-    id = ATOM_TO_JSID(cx->runtime->atomState.nameAtom);
+    id = NameToId(cx->runtime->atomState.nameAtom);
     if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
         return false;
 
     for (unsigned i = 0; i < ArrayLength(poisonPillProps); i++) {
         const uint16_t offset = poisonPillProps[i];
-        id = ATOM_TO_JSID(OFFSET_TO_ATOM(cx->runtime, offset));
+        id = NameToId(OFFSET_TO_NAME(cx->runtime, offset));
         if (!obj->hasProperty(cx, id, &found, JSRESOLVE_QUALIFIED))
             return false;
     }
 
     return true;
 }
 
 static JSObject *
@@ -336,17 +336,17 @@ fun_resolve(JSContext *cx, JSObject *obj
         }
         *objp = fun;
         return true;
     }
 
     for (unsigned i = 0; i < ArrayLength(poisonPillProps); i++) {
         const uint16_t offset = poisonPillProps[i];
 
-        if (JSID_IS_ATOM(id, OFFSET_TO_ATOM(cx->runtime, offset))) {
+        if (JSID_IS_ATOM(id, OFFSET_TO_NAME(cx->runtime, offset))) {
             JS_ASSERT(!IsInternalFunctionObject(fun));
 
             PropertyOp getter;
             StrictPropertyOp setter;
             unsigned attrs = JSPROP_PERMANENT;
             if (fun->isInterpreted() ? fun->inStrictMode() : fun->isBoundFunction()) {
                 JSObject *throwTypeError = fun->global().getThrowTypeError();
 
@@ -1207,22 +1207,22 @@ LookupInterpretedFunctionPrototype(JSCon
 {
 #ifdef DEBUG
     JSFunction *fun = funobj->toFunction();
     JS_ASSERT(fun->isInterpreted());
     JS_ASSERT(!fun->isFunctionPrototype());
     JS_ASSERT(!funobj->isBoundFunction());
 #endif
 
-    jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+    jsid id = NameToId(cx->runtime->atomState.classPrototypeAtom);
     RootedVar<const Shape*> shape(cx, funobj->nativeLookup(cx, id));
     if (!shape) {
         if (!ResolveInterpretedFunctionPrototype(cx, funobj))
             return NULL;
-        id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+        id = NameToId(cx->runtime->atomState.classPrototypeAtom);
         shape = funobj->nativeLookup(cx, id);
     }
     JS_ASSERT(!shape->configurable());
     JS_ASSERT(shape->isDataDescriptor());
     JS_ASSERT(shape->hasSlot());
     return shape;
 }
 
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -79,54 +79,54 @@
 #endif
 
 using namespace js;
 using namespace js::types;
 using namespace js::analyze;
 
 static inline jsid
 id_prototype(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+    return NameToId(cx->runtime->atomState.classPrototypeAtom);
 }
 
 static inline jsid
 id_arguments(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom);
+    return NameToId(cx->runtime->atomState.argumentsAtom);
 }
 
 static inline jsid
 id_length(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    return NameToId(cx->runtime->atomState.lengthAtom);
 }
 
 static inline jsid
 id___proto__(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
+    return NameToId(cx->runtime->atomState.protoAtom);
 }
 
 static inline jsid
 id_constructor(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.constructorAtom);
+    return NameToId(cx->runtime->atomState.constructorAtom);
 }
 
 static inline jsid
 id_caller(JSContext *cx) {
-    return ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
+    return NameToId(cx->runtime->atomState.callerAtom);
 }
 
 static inline jsid
 id_toString(JSContext *cx)
 {
-    return ATOM_TO_JSID(cx->runtime->atomState.toStringAtom);
+    return NameToId(cx->runtime->atomState.toStringAtom);
 }
 
 static inline jsid
 id_toSource(JSContext *cx)
 {
-    return ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
+    return NameToId(cx->runtime->atomState.toSourceAtom);
 }
 
 #ifdef DEBUG
 const char *
 types::TypeIdStringImpl(jsid id)
 {
     if (JSID_IS_VOID(id))
         return "(index)";
@@ -1973,18 +1973,18 @@ TypeCompartment::newAllocationSiteTypeOb
     }
 
     return res;
 }
 
 static inline jsid
 GetAtomId(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset)
 {
-    JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc + offset));
-    return MakeTypeId(cx, ATOM_TO_JSID(atom));
+    PropertyName *name = script->getName(GET_UINT32_INDEX(pc + offset));
+    return MakeTypeId(cx, NameToId(name));
 }
 
 bool
 types::UseNewType(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(cx->typeInferenceEnabled());
 
     /*
@@ -2897,17 +2897,17 @@ TypeObject::addPropertyType(JSContext *c
     jsid id = JSID_VOID;
     if (name) {
         JSAtom *atom = js_Atomize(cx, name, strlen(name));
         if (!atom) {
             AutoEnterTypeInference enter(cx);
             cx->compartment->types.setPendingNukeTypes(cx);
             return;
         }
-        id = ATOM_TO_JSID(atom);
+        id = AtomToId(atom);
     }
     InlineAddTypeProperty(cx, this, id, type);
 }
 
 void
 TypeObject::addPropertyType(JSContext *cx, const char *name, const Value &value)
 {
     addPropertyType(cx, name, GetValueType(cx, value));
@@ -3515,21 +3515,21 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
         TypeSet *seen = bytecodeTypes(pc);
         seen->addSubset(cx, &pushed[0]);
 
         /*
          * Normally we rely on lazy standard class initialization to fill in
          * the types of global properties the script can access. In a few cases
          * the method JIT will bypass this, and we need to add the types direclty.
          */
-        if (id == ATOM_TO_JSID(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]))
+        if (id == NameToId(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]))
             seen->addType(cx, Type::UndefinedType());
-        if (id == ATOM_TO_JSID(cx->runtime->atomState.NaNAtom))
+        if (id == NameToId(cx->runtime->atomState.NaNAtom))
             seen->addType(cx, Type::DoubleType());
-        if (id == ATOM_TO_JSID(cx->runtime->atomState.InfinityAtom))
+        if (id == NameToId(cx->runtime->atomState.InfinityAtom))
             seen->addType(cx, Type::DoubleType());
 
         /* Handle as a property access. */
         PropertyAccess(cx, script, pc, script->global()->getType(cx), false, seen, id);
 
         if (op == JSOP_CALLGNAME)
             pushed[0].addPropagateThis(cx, script, pc, Type::UnknownType());
 
@@ -4387,17 +4387,17 @@ AnalyzeNewScriptProperties(JSContext *cx
         RootedVarObject obj(cx, *pbaseobj);
 
         if (op == JSOP_SETPROP && uses->u.which == 1) {
             /*
              * Don't use GetAtomId here, we need to watch for SETPROP on
              * integer properties and bail out. We can't mark the aggregate
              * JSID_VOID type property as being in a definite slot.
              */
-            jsid id = ATOM_TO_JSID(script->getAtom(GET_UINT32_INDEX(pc)));
+            jsid id = NameToId(script->getName(GET_UINT32_INDEX(pc)));
             if (MakeTypeId(cx, id) != id)
                 return false;
             if (id == id_prototype(cx) || id == id___proto__(cx) || id == id_constructor(cx))
                 return false;
 
             /*
              * Ensure that if the properties named here could have a setter or
              * a permanent property in any transitive prototype, the definite
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -370,17 +370,17 @@ Class js_NoSuchMethodClass = {
  * call by name, and args is an Array containing this invocation's actual
  * parameters.
  */
 bool
 js::OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval_, Value *vp)
 {
     RootedVarValue idval(cx, idval_);
 
-    jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
+    jsid id = NameToId(cx->runtime->atomState.noSuchMethodAtom);
     RootedVarValue value(cx);
     if (!js_GetMethod(cx, obj, id, 0, value.address()))
         return false;
     TypeScript::MonitorUnknown(cx, cx->fp()->script(), cx->regs().pc);
 
     if (value.reference().isPrimitive()) {
         *vp = value;
     } else {
@@ -893,38 +893,16 @@ js::TypeOfValue(JSContext *cx, const Val
     if (v.isUndefined())
         return JSTYPE_VOID;
     if (v.isObject())
         return v.toObject().typeOf(cx);
     JS_ASSERT(v.isBoolean());
     return JSTYPE_BOOLEAN;
 }
 
-bool
-js::ValueToId(JSContext *cx, const Value &v, jsid *idp)
-{
-    int32_t i;
-    if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
-        *idp = INT_TO_JSID(i);
-        return true;
-    }
-
-#if JS_HAS_XML_SUPPORT
-    if (v.isObject()) {
-        JSObject *obj = &v.toObject();
-        if (obj->isXMLId()) {
-            *idp = OBJECT_TO_JSID(obj);
-            return JS_TRUE;
-        }
-    }
-#endif
-
-    return js_ValueToStringId(cx, v, idp);
-}
-
 /*
  * Enter the new with scope using an object at sp[-1] and associate the depth
  * of the with block with sp + stackIndex.
  */
 static bool
 EnterWith(JSContext *cx, int stackIndex)
 {
     StackFrame *fp = cx->fp();
@@ -2018,23 +1996,18 @@ END_CASE(JSOP_AND)
  * If the index value at sp[n] is not an int that fits in a jsval, it could
  * be an object (an XML QName, AttributeName, or AnyName), but only if we are
  * compiling with JS_HAS_XML_SUPPORT.  Otherwise convert the index value to a
  * string atom id.
  */
 #define FETCH_ELEMENT_ID(obj, n, id)                                          \
     JS_BEGIN_MACRO                                                            \
         const Value &idval_ = regs.sp[n];                                     \
-        int32_t i_;                                                           \
-        if (ValueFitsInInt32(idval_, &i_) && INT_FITS_IN_JSID(i_)) {          \
-            id = INT_TO_JSID(i_);                                             \
-        } else {                                                              \
-            if (!js_InternNonIntElementId(cx, obj, idval_, &id, &regs.sp[n])) \
-                goto error;                                                   \
-        }                                                                     \
+        if (!ValueToId(cx, obj, idval_, &id))                                 \
+            goto error;                                                       \
     JS_END_MACRO
 
 #define TRY_BRANCH_AFTER_COND(cond,spdec)                                     \
     JS_BEGIN_MACRO                                                            \
         JS_ASSERT(js_CodeSpec[op].length == 1);                               \
         unsigned diff_ = (unsigned) GET_UINT8(regs.pc) - (unsigned) JSOP_IFEQ;         \
         if (diff_ <= 1) {                                                     \
             regs.sp -= spdec;                                                 \
@@ -3323,17 +3296,17 @@ BEGIN_CASE(JSOP_SETTER)
     int i;
     JSObject *obj;
     switch (op2) {
       case JSOP_SETNAME:
       case JSOP_SETPROP:
       {
         PropertyName *name;
         LOAD_NAME(0, name);
-        id = ATOM_TO_JSID(name);
+        id = NameToId(name);
         rval = regs.sp[-1];
         i = -1;
         goto gs_pop_lval;
       }
       case JSOP_SETELEM:
         rval = regs.sp[-1];
         id = JSID_VOID;
         i = -2;
@@ -3343,17 +3316,17 @@ BEGIN_CASE(JSOP_SETTER)
 
       case JSOP_INITPROP:
       {
         JS_ASSERT(regs.sp - regs.fp()->base() >= 2);
         rval = regs.sp[-1];
         i = -1;
         PropertyName *name;
         LOAD_NAME(0, name);
-        id = ATOM_TO_JSID(name);
+        id = NameToId(name);
         goto gs_get_lval;
       }
       default:
         JS_ASSERT(op2 == JSOP_INITELEM);
 
         JS_ASSERT(regs.sp - regs.fp()->base() >= 3);
         rval = regs.sp[-1];
         id = JSID_VOID;
@@ -3477,21 +3450,21 @@ BEGIN_CASE(JSOP_INITPROP)
     JS_ASSERT(regs.sp - regs.fp()->base() >= 2);
     Value rval = regs.sp[-1];
 
     /* Load the object being initialized into lval/obj. */
     RootedVarObject &obj = rootObject0;
     obj = &regs.sp[-2].toObject();
     JS_ASSERT(obj->isObject());
 
-    JSAtom *atom;
-    LOAD_ATOM(0, atom);
-    jsid id = ATOM_TO_JSID(atom);
-
-    if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
+    PropertyName *name;
+    LOAD_NAME(0, name);
+    jsid id = NameToId(name);
+
+    if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
         ? !js_SetPropertyHelper(cx, obj, id, 0, &rval, script->strictModeCode)
         : !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
                                 JSPROP_ENUMERATE, 0, 0, 0)) {
         goto error;
     }
 
     regs.sp--;
 }
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -255,19 +255,16 @@ extern bool
 SameValue(JSContext *cx, const Value &v1, const Value &v2, bool *same);
 
 extern JSType
 TypeOfValue(JSContext *cx, const Value &v);
 
 extern JSBool
 HasInstance(JSContext *cx, JSObject *obj, const js::Value *v, JSBool *bp);
 
-extern bool
-ValueToId(JSContext *cx, const Value &v, jsid *idp);
-
 /*
  * A linked list of the |FrameRegs regs;| variables belonging to all
  * js::Interpret C++ frames on this thread's stack.
  *
  * Note that this is *not* a list of all JS frames running under the
  * interpreter; that would include inlined frames, whose FrameRegs are
  * saved in various pieces in various places. Rather, this lists each
  * js::Interpret call's live 'regs'; when control returns to that call, it
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -250,17 +250,17 @@ GetPropertyOperation(JSContext *cx, jsby
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
         if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp))
             return false;
         return true;
     }
 
     RootObject objRoot(cx, &obj);
-    RootedVarId id(cx, ATOM_TO_JSID(name));
+    RootedVarId id(cx, NameToId(name));
 
     if (obj->getOps()->getProperty) {
         if (!GetPropertyGenericMaybeCallXML(cx, op, objRoot, id, vp))
             return false;
     } else {
         if (!GetPropertyHelper(cx, objRoot, id, JSGET_CACHE_RESULT, vp))
             return false;
     }
@@ -334,17 +334,17 @@ SetPropertyOperation(JSContext *cx, jsby
 
     bool strict = cx->stack.currentScript()->strictModeCode;
     RootedVarValue rref(cx, rval);
 
     JSOp op = JSOp(*pc);
 
     RootObject objRoot(cx, &obj);
 
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     if (JS_LIKELY(!obj->getOps()->setProperty)) {
         unsigned defineHow = (op == JSOP_SETNAME)
                              ? DNP_CACHE_RESULT | DNP_UNQUALIFIED
                              : DNP_CACHE_RESULT;
         if (!js_SetPropertyHelper(cx, objRoot, id, defineHow, rref.address(), strict))
             return false;
     } else {
         if (!obj->setGeneric(cx, id, rref.address(), strict))
@@ -377,17 +377,17 @@ NameOperation(JSContext *cx, jsbytecode 
     JS_PROPERTY_CACHE(cx).test(cx, pc, obj, obj2, entry, name);
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
         if (!NativeGet(cx, obj, obj2, entry->prop, 0, vp))
             return false;
         return true;
     }
 
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
 
     RootPropertyName nameRoot(cx, &name);
     RootObject objRoot(cx, &obj);
 
     JSProperty *prop;
     if (!FindPropertyHelper(cx, nameRoot, true, objRoot, &obj, &obj2, &prop))
         return false;
     if (!prop) {
@@ -670,33 +670,33 @@ ModOperation(JSContext *cx, HandleValue 
 static inline bool
 FetchElementId(JSContext *cx, JSObject *obj, const Value &idval, jsid &id, Value *vp)
 {
     int32_t i_;
     if (ValueFitsInInt32(idval, &i_) && INT_FITS_IN_JSID(i_)) {
         id = INT_TO_JSID(i_);
         return true;
     }
-    return !!js_InternNonIntElementId(cx, obj, idval, &id, vp);
+    return !!InternNonIntElementId(cx, obj, idval, &id, vp);
 }
 
 static JS_ALWAYS_INLINE bool
 ToIdOperation(JSContext *cx, const Value &objval, const Value &idval, Value *res)
 {
     if (idval.isInt32()) {
         *res = idval;
         return true;
     }
 
     JSObject *obj = ValueToObject(cx, objval);
     if (!obj)
         return false;
 
     jsid dummy;
-    if (!js_InternNonIntElementId(cx, obj, idval, &dummy, res))
+    if (!InternNonIntElementId(cx, obj, idval, &dummy, res))
         return false;
 
     if (!res->isInt32())
         types::TypeScript::MonitorUnknown(cx);
     return true;
 }
 
 static JS_ALWAYS_INLINE bool
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -259,17 +259,17 @@ EnumerateNativeProperties(JSContext *cx,
     ::Reverse(props->begin() + initialLength, props->end());
     return true;
 }
 
 static bool
 EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, JSObject *pobj, unsigned flags,
                               IdSet &ht, AutoIdVector *props)
 {
-    if (!Enumerate(cx, obj, pobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), false,
+    if (!Enumerate(cx, obj, pobj, NameToId(cx->runtime->atomState.lengthAtom), false,
                    flags, ht, props)) {
         return false;
     }
 
     if (pobj->getArrayLength() > 0) {
         size_t initlen = pobj->getDenseArrayInitializedLength();
         const Value *vp = pobj->getDenseArrayElements();
         for (size_t i = 0; i < initlen; ++i, ++vp) {
@@ -453,18 +453,18 @@ GetCustomIterator(JSContext *cx, HandleO
      */
     if (flags == JSITER_FOR_OF) {
         js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_ITERABLE,
                                  JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL, NULL, NULL);
         return false;
     }
 
     /* Check whether we have a valid __iterator__ method. */
-    JSAtom *atom = cx->runtime->atomState.iteratorAtom;
-    if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, vp))
+    PropertyName *name = cx->runtime->atomState.iteratorAtom;
+    if (!js_GetMethod(cx, obj, NameToId(name), 0, vp))
         return false;
 
     /* If there is no custom __iterator__ method, we are done here. */
     if (!vp->isObject()) {
         vp->setUndefined();
         return true;
     }
 
@@ -476,17 +476,17 @@ GetCustomIterator(JSContext *cx, HandleO
     if (!Invoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp))
         return false;
     if (vp->isPrimitive()) {
         /*
          * We are always coming from js::ValueToIterator, and we are no longer on
          * trace, so the object we are iterating over is on top of the stack (-1).
          */
         JSAutoByteString bytes;
-        if (!js_AtomToPrintableString(cx, atom, &bytes))
+        if (!js_AtomToPrintableString(cx, name, &bytes))
             return false;
         js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
                              -1, ObjectValue(*obj), NULL, bytes.ptr());
         return false;
     }
     return true;
 }
 
@@ -1011,17 +1011,16 @@ SuppressDeletedPropertyHelper(JSContext 
                      */
                     if (obj->getProto()) {
                         JSObject *proto = obj->getProto();
                         JSObject *obj2;
                         JSProperty *prop;
                         jsid id;
                         if (!ValueToId(cx, StringValue(*idp), &id))
                             return false;
-                        id = js_CheckForStringIndex(id);
                         if (!proto->lookupGeneric(cx, id, &obj2, &prop))
                             return false;
                         if (prop) {
                             unsigned attrs;
                             if (obj2->isNative())
                                 attrs = ((Shape *) prop)->attributes();
                             else if (!obj2->getGenericAttributes(cx, id, &attrs))
                                 return false;
@@ -1212,17 +1211,16 @@ js_IteratorMore(JSContext *cx, HandleObj
     JS_CHECK_RECURSION(cx, return false);
 
     /* Fetch and cache the next value from the iterator. */
     if (ni) {
         JS_ASSERT(!ni->isKeyIter());
         jsid id;
         if (!ValueToId(cx, StringValue(*ni->current()), &id))
             return false;
-        id = js_CheckForStringIndex(id);
         ni->incCursor();
         if (!ni->obj->getGeneric(cx, id, rval))
             return false;
         if ((ni->flags & JSITER_KEYVALUE) && !NewKeyValuePair(cx, id, *rval, rval))
             return false;
     } else if (iterobj->isElementIterator()) {
         /*
          * Like native iterators, element iterators do not have a .next
@@ -1239,17 +1237,17 @@ js_IteratorMore(JSContext *cx, HandleObj
         if (!Proxy::iteratorNext(cx, iterobj, rval))
             return false;
         if (rval->isMagic(JS_NO_ITER_VALUE)) {
             rval->setBoolean(false);
             return true;
         }
     } else {
         /* Call the iterator object's .next method. */
-        jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);
+        jsid id = NameToId(cx->runtime->atomState.nextAtom);
         if (!js_GetMethod(cx, iterobj, id, 0, rval))
             return false;
         if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
             /* Check for StopIteration. */
             if (!cx->isExceptionPending() || !IsStopIteration(cx->getPendingException()))
                 return false;
 
             cx->clearPendingException();
@@ -1740,17 +1738,17 @@ InitIteratorClass(JSContext *cx, Handle<
     NativeIterator *ni = NativeIterator::allocateIterator(cx, 0, blank);
     if (!ni)
         return false;
     ni->init(NULL, 0 /* flags */, 0, 0);
 
     iteratorProto->setNativeIterator(ni);
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, Iterator, CLASS_ATOM(cx, Iterator), 2);
+    ctor = global->createConstructor(cx, Iterator, CLASS_NAME(cx, Iterator), 2);
     if (!ctor)
         return false;
 
     if (!LinkConstructorAndPrototype(cx, ctor, iteratorProto))
         return false;
 
     if (!DefinePropertiesAndBrand(cx, iteratorProto, NULL, iterator_methods))
         return false;
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -648,17 +648,17 @@ math_tan(JSContext *cx, unsigned argc, V
     vp->setDouble(z);
     return JS_TRUE;
 }
 
 #if JS_HAS_TOSOURCE
 static JSBool
 math_toSource(JSContext *cx, unsigned argc, Value *vp)
 {
-    vp->setString(CLASS_ATOM(cx, Math));
+    vp->setString(CLASS_NAME(cx, Math));
     return JS_TRUE;
 }
 #endif
 
 static JSFunctionSpec math_static_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,  math_toSource,        0, 0),
 #endif
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -1021,17 +1021,17 @@ js_InitNumberClass(JSContext *cx, JSObje
     RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedVarObject numberProto(cx, global->createBlankPrototype(cx, &NumberClass));
     if (!numberProto)
         return NULL;
     numberProto->asNumber().setPrimitiveValue(0);
 
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, Number, CLASS_ATOM(cx, Number), 1);
+    ctor = global->createConstructor(cx, Number, CLASS_NAME(cx, Number), 1);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, numberProto))
         return NULL;
 
     /* Add numeric constants (MAX_VALUE, NaN, &c.) to the Number constructor. */
     if (!JS_DefineConstDoubles(cx, ctor, number_constants))
@@ -1039,20 +1039,20 @@ js_InitNumberClass(JSContext *cx, JSObje
 
     if (!DefinePropertiesAndBrand(cx, numberProto, NULL, number_methods))
         return NULL;
 
     if (!JS_DefineFunctions(cx, global, number_functions))
         return NULL;
 
     /* ES5 15.1.1.1, 15.1.1.2 */
-    if (!DefineNativeProperty(cx, global, ATOM_TO_JSID(cx->runtime->atomState.NaNAtom),
+    if (!DefineNativeProperty(cx, global, NameToId(cx->runtime->atomState.NaNAtom),
                               cx->runtime->NaNValue, JS_PropertyStub, JS_StrictPropertyStub,
                               JSPROP_PERMANENT | JSPROP_READONLY, 0, 0) ||
-        !DefineNativeProperty(cx, global, ATOM_TO_JSID(cx->runtime->atomState.InfinityAtom),
+        !DefineNativeProperty(cx, global, NameToId(cx->runtime->atomState.InfinityAtom),
                               cx->runtime->positiveInfinityValue,
                               JS_PropertyStub, JS_StrictPropertyStub,
                               JSPROP_PERMANENT | JSPROP_READONLY, 0, 0))
     {
         return NULL;
     }
 
     if (!DefineConstructorAndPrototype(cx, global, JSProto_Number, ctor, numberProto))
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -146,17 +146,17 @@ JSPropertySpec object_props[] = {
     {0,0,0,0,0}
 };
 
 static JSBool
 obj_getProto(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     /* Let CheckAccess get the slot's value, based on the access mode. */
     unsigned attrs;
-    id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
+    id = NameToId(cx->runtime->atomState.protoAtom);
     return CheckAccess(cx, obj, id, JSACC_PROTO, vp, &attrs);
 }
 
 size_t sSetProtoCalled = 0;
 
 static JSBool
 obj_setProto(JSContext *cx, JSObject *obj_, jsid id, JSBool strict, Value *vp)
 {
@@ -171,17 +171,17 @@ obj_setProto(JSContext *cx, JSObject *ob
         return false;
     }
 
     if (!vp->isObjectOrNull())
         return true;
 
     RootedVarObject pobj(cx, vp->toObjectOrNull());
     unsigned attrs;
-    id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
+    id = NameToId(cx->runtime->atomState.protoAtom);
     if (!CheckAccess(cx, obj, id, JSAccessMode(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
         return false;
 
     return SetProto(cx, obj, pobj, true);
 }
 
 #else  /* !JS_HAS_OBJ_PROTO_PROP */
 
@@ -710,17 +710,17 @@ obj_toLocaleString(JSContext *cx, unsign
     JS_CHECK_RECURSION(cx, return false);
 
     /* Step 1. */
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
 
     /* Steps 2-4. */
-    return obj->callMethod(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), 0, NULL, vp);
+    return obj->callMethod(cx, NameToId(cx->runtime->atomState.toStringAtom), 0, NULL, vp);
 }
 
 static JSBool
 obj_valueOf(JSContext *cx, unsigned argc, Value *vp)
 {
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
@@ -1522,17 +1522,17 @@ obj_getPrototypeOf(JSContext *cx, unsign
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_UNEXPECTED_TYPE, bytes, "not an object");
         JS_free(cx, bytes);
         return JS_FALSE;
     }
 
     JSObject *obj = &vp[2].toObject();
     unsigned attrs;
-    return CheckAccess(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.protoAtom),
+    return CheckAccess(cx, obj, NameToId(cx->runtime->atomState.protoAtom),
                        JSACC_PROTO, vp, &attrs);
 }
 
 namespace js {
 
 bool
 NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp)
 {
@@ -1781,64 +1781,64 @@ PropDesc::initialize(JSContext *cx, cons
     attrs = JSPROP_PERMANENT | JSPROP_READONLY;
 
     bool found;
 
     /* 8.10.5 step 3 */
 #ifdef __GNUC__ /* quell GCC overwarning */
     found = false;
 #endif
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.enumerableAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.enumerableAtom), &v, &found))
         return false;
     if (found) {
         hasEnumerable_ = true;
         if (js_ValueToBoolean(v))
             attrs |= JSPROP_ENUMERATE;
     }
 
     /* 8.10.5 step 4 */
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.configurableAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.configurableAtom), &v, &found))
         return false;
     if (found) {
         hasConfigurable_ = true;
         if (js_ValueToBoolean(v))
             attrs &= ~JSPROP_PERMANENT;
     }
 
     /* 8.10.5 step 5 */
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.valueAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.valueAtom), &v, &found))
         return false;
     if (found) {
         hasValue_ = true;
         value_ = v;
     }
 
     /* 8.10.6 step 6 */
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.writableAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.writableAtom), &v, &found))
         return false;
     if (found) {
         hasWritable_ = true;
         if (js_ValueToBoolean(v))
             attrs &= ~JSPROP_READONLY;
     }
 
     /* 8.10.7 step 7 */
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.getAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.getAtom), &v, &found))
         return false;
     if (found) {
         hasGet_ = true;
         get_ = v;
         attrs |= JSPROP_GETTER | JSPROP_SHARED;
         attrs &= ~JSPROP_READONLY;
         if (checkAccessors && !checkGetter(cx))
             return false;
     }
 
     /* 8.10.7 step 8 */
-    if (!HasProperty(cx, desc, ATOM_TO_JSID(cx->runtime->atomState.setAtom), &v, &found))
+    if (!HasProperty(cx, desc, NameToId(cx->runtime->atomState.setAtom), &v, &found))
         return false;
     if (found) {
         hasSet_ = true;
         set_ = v;
         attrs |= JSPROP_SETTER | JSPROP_SHARED;
         attrs &= ~JSPROP_READONLY;
         if (checkAccessors && !checkSetter(cx))
             return false;
@@ -3101,18 +3101,16 @@ js_InferFlags(JSContext *cx, unsigned de
     return flags;
 }
 
 JSBool
 JSObject::nonNativeSetProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict)
 {
     JSObject *self = this;
     if (JS_UNLIKELY(watched())) {
-        id = js_CheckForStringIndex(id);
-
         RootObject selfRoot(cx, &self);
         RootId idRoot(cx, &id);
 
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, selfRoot, idRoot, vp))
             return false;
     }
     return self->getOps()->setGeneric(cx, self, id, vp, strict);
@@ -3123,17 +3121,16 @@ JSObject::nonNativeSetElement(JSContext 
 {
     JSObject *self = this;
     if (JS_UNLIKELY(watched())) {
         RootObject selfRoot(cx, &self);
 
         jsid id;
         if (!IndexToId(cx, index, &id))
             return false;
-        JS_ASSERT(id == js_CheckForStringIndex(id));
 
         RootId idRoot(cx, &id);
 
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, selfRoot, idRoot, vp))
             return false;
     }
     return self->getOps()->setElement(cx, self, index, vp, strict);
@@ -3565,17 +3562,17 @@ JSObject::swap(JSContext *cx, JSObject *
 
     return true;
 }
 
 static bool
 DefineStandardSlot(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
                    const Value &v, uint32_t attrs, bool &named)
 {
-    jsid id = ATOM_TO_JSID(atom);
+    jsid id = AtomToId(atom);
 
     if (key != JSProto_Null) {
         /*
          * Initializing an actual standard class on a global object. If the
          * property is not yet present, force it into a new one bound to a
          * reserved slot. Otherwise, go through the normal property path.
          */
         JS_ASSERT(obj->isGlobal());
@@ -4239,17 +4236,17 @@ js_GetClassObject(JSContext *cx, JSObjec
     }
 
     Value v = obj->getReservedSlot(key);
     if (v.isObject()) {
         *objp = &v.toObject();
         return true;
     }
 
-    AutoResolving resolving(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]));
+    AutoResolving resolving(cx, obj, NameToId(cx->runtime->atomState.classAtoms[key]));
     if (resolving.alreadyStarted()) {
         /* Already caching id in obj -- suppress recursion. */
         *objp = NULL;
         return true;
     }
 
     JSObject *cobj = NULL;
     if (JSObjectOp init = lazy_prototype_init[key]) {
@@ -4288,22 +4285,22 @@ js_FindClassObject(JSContext *cx, JSObje
         JS_ASSERT(JSProto_Null < protoKey);
         JS_ASSERT(protoKey < JSProto_LIMIT);
         if (!js_GetClassObject(cx, obj, protoKey, &cobj))
             return false;
         if (cobj) {
             vp->setObject(*cobj);
             return JS_TRUE;
         }
-        id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[protoKey]);
+        id = NameToId(cx->runtime->atomState.classAtoms[protoKey]);
     } else {
         JSAtom *atom = js_Atomize(cx, clasp->name, strlen(clasp->name));
         if (!atom)
             return false;
-        id = ATOM_TO_JSID(atom);
+        id = AtomToId(atom);
     }
 
     JS_ASSERT(obj->isNative());
     if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_CLASSNAME, &pobj, &prop))
         return false;
     Value v = UndefinedValue();
     if (prop && pobj->isNative()) {
         shape = (Shape *) prop;
@@ -4438,19 +4435,16 @@ js_PurgeScopeChainHelper(JSContext *cx, 
 
 Shape *
 js_AddNativeProperty(JSContext *cx, HandleObject obj, jsid id_,
                      PropertyOp getter, StrictPropertyOp setter, uint32_t slot,
                      unsigned attrs, unsigned flags, int shortid)
 {
     RootedVarId id(cx, id_);
 
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     /*
      * Purge the property cache of now-shadowed id in obj's scope chain. Do
      * this optimistically (assuming no failure below) before locking obj, so
      * we can lock the shadowed scope.
      */
     if (!js_PurgeScopeChain(cx, obj, id))
         return NULL;
 
@@ -4520,19 +4514,16 @@ DefineNativeProperty(JSContext *cx, Hand
 
     RootId idRoot(cx, &id);
     RootGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
     /* Make a local copy of value so addProperty can mutate its inout parameter. */
     RootedVarValue value(cx);
     value = value_;
 
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     /*
      * If defining a getter or setter, we must check for its counterpart and
      * update the attributes and property ops.  A getter or setter is really
      * only half of a property.
      */
     Shape *shape = NULL;
     if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
         JSObject *pobj;
@@ -4703,19 +4694,16 @@ CallResolveOp(JSContext *cx, JSObject *s
 
 static JS_ALWAYS_INLINE bool
 LookupPropertyWithFlagsInline(JSContext *cx, JSObject *obj_, jsid id_, unsigned flags,
                               JSObject **objp, JSProperty **propp)
 {
     RootedVarObject obj(cx, obj_);
     RootedVarId id(cx, id_);
 
-    /* We should not get string indices which aren't already integers here. */
-    JS_ASSERT(id.raw() == js_CheckForStringIndex(id));
-
     /* Search scopes starting with obj and following the prototype link. */
     RootedVarObject start(cx, obj);
     while (true) {
         const Shape *shape = obj->nativeLookup(cx, id);
         if (shape) {
             *objp = obj;
             *propp = (JSProperty *) shape;
             return true;
@@ -4768,19 +4756,16 @@ LookupPropertyWithFlagsInline(JSContext 
     *propp = NULL;
     return true;
 }
 
 JS_FRIEND_API(JSBool)
 js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
                   JSProperty **propp)
 {
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp);
 }
 
 JS_FRIEND_API(JSBool)
 js_LookupElement(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp, JSProperty **propp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
@@ -4788,28 +4773,25 @@ js_LookupElement(JSContext *cx, JSObject
 
     return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp);
 }
 
 bool
 js::LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                             JSObject **objp, JSProperty **propp)
 {
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     return LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
 }
 
 bool
 js::FindPropertyHelper(JSContext *cx,
                        HandlePropertyName name, bool cacheResult, HandleObject scopeChain,
                        JSObject **objp, JSObject **pobjp, JSProperty **propp)
 {
-    RootedVarId id(cx, ATOM_TO_JSID(name));
+    RootedVarId id(cx, NameToId(name));
 
     JSObject *pobj;
     int scopeIndex;
     JSProperty *prop;
 
     /* Scan entries on the scope chain that we can cache across. */
     RootedVarObject obj(cx, scopeChain);
     RootedVarObject parent(cx, obj->enclosingScope());
@@ -5059,19 +5041,16 @@ js_NativeSet(JSContext *cx, JSObject *ob
 static JS_ALWAYS_INLINE JSBool
 js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receiver, jsid id_,
                            uint32_t getHow, Value *vp)
 {
     JSProperty *prop;
 
     RootedVarId id(cx, id_);
 
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     /* This call site is hot -- use the always-inlined variant of LookupPropertyWithFlags(). */
     RootedVarObject obj2(cx);
     if (!LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, obj2.address(), &prop))
         return false;
 
     if (!prop) {
         vp->setUndefined();
 
@@ -5276,19 +5255,16 @@ js_SetPropertyHelper(JSContext *cx, Hand
     Class *clasp;
     PropertyOp getter;
     StrictPropertyOp setter;
     bool added;
 
     JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
     RootId idRoot(cx, &id);
 
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     if (JS_UNLIKELY(obj->watched())) {
         /* Fire watchpoints, if any. */
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, obj, idRoot, vp))
             return false;
     }
 
     if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
@@ -5533,19 +5509,16 @@ js_DeleteGeneric(JSContext *cx, JSObject
     JSProperty *prop;
     const Shape *shape;
 
     rval->setBoolean(true);
 
     RootedVarObject obj(cx, obj_);
     RootedVarId id(cx, id_);
 
-    /* Convert string indices to integers if appropriate. */
-    id = js_CheckForStringIndex(id);
-
     if (!js_LookupProperty(cx, obj, id, &proto, &prop))
         return false;
     if (!prop || proto != obj) {
         /*
          * If no property, or the property comes from a prototype, call the
          * class's delProperty hook, passing rval as the result parameter.
          */
         return CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, id, rval);
@@ -5559,28 +5532,32 @@ js_DeleteGeneric(JSContext *cx, JSObject
         return true;
     }
 
     if (shape->hasSlot()) {
         const Value &v = obj->nativeGetSlot(shape->slot());
         GCPoke(cx->runtime, v);
     }
 
-    if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
+    jsid userid;
+    if (!shape->getUserId(cx, &userid))
+        return false;
+
+    if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, userid, rval))
         return false;
     if (rval->isFalse())
         return true;
 
     return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
 }
 
 JSBool
 js_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    return js_DeleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
+    return js_DeleteGeneric(cx, obj, NameToId(name), rval, strict);
 }
 
 JSBool
 js_DeleteElement(JSContext *cx, JSObject *obj_, uint32_t index, Value *rval, JSBool strict)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
@@ -5595,17 +5572,16 @@ js_DeleteSpecial(JSContext *cx, JSObject
     return js_DeleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
 }
 
 namespace js {
 
 bool
 HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp)
 {
-    JS_ASSERT(id == js_CheckForStringIndex(id));
     if (const Shape *shape = obj->nativeLookup(cx, id)) {
         if (shape->hasDefaultGetter() && shape->hasSlot()) {
             *vp = obj->nativeGetSlot(shape->slot());
             return true;
         }
     }
 
     return false;
@@ -5638,53 +5614,53 @@ DefaultValue(JSContext *cx, HandleObject
     JS_ASSERT(!obj->isXML());
 
     Class *clasp = obj->getClass();
     if (hint == JSTYPE_STRING) {
         /* Optimize (new String(...)).toString(). */
         if (clasp == &StringClass &&
             ClassMethodIsNative(cx, obj,
                                  &StringClass,
-                                 RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
+                                 RootedVarId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
                                  js_str_toString)) {
             *vp = StringValue(obj->asString().unbox());
             return true;
         }
 
-        if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.toStringAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
-        if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom), vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.valueOfAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
     } else {
         /* Optimize (new String(...)).valueOf(). */
         if ((clasp == &StringClass &&
              ClassMethodIsNative(cx, obj, &StringClass,
-                                 RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
+                                 RootedVarId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
                                  js_str_toString)) ||
             (clasp == &NumberClass &&
              ClassMethodIsNative(cx, obj, &NumberClass,
-                                 RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom)),
+                                 RootedVarId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
                                  js_num_valueOf))) {
             *vp = obj->isString()
                   ? StringValue(obj->asString().unbox())
                   : NumberValue(obj->asNumber().unbox());
             return true;
         }
 
-        if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom), vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.valueOfAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
-        if (!MaybeCallMethod(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom), vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.toStringAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
     }
 
     /* Avoid recursive death when decompiling in js_ReportValueError. */
     JSString *str;
     if (hint == JSTYPE_STRING) {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -129,17 +129,17 @@ js_LookupProperty(JSContext *cx, JSObjec
                   JSProperty **propp);
 
 namespace js {
 
 inline bool
 LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
                JSObject **objp, JSProperty **propp)
 {
-    return js_LookupProperty(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return js_LookupProperty(cx, obj, NameToId(name), objp, propp);
 }
 
 }
 
 extern JS_FRIEND_API(JSBool)
 js_LookupElement(JSContext *cx, JSObject *obj, uint32_t index,
                  JSObject **objp, JSProperty **propp);
 
@@ -181,17 +181,17 @@ js_SetPropertyHelper(JSContext *cx, js::
                      js::Value *vp, JSBool strict);
 
 namespace js {
 
 inline bool
 SetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, unsigned defineHow,
                   Value *vp, JSBool strict)
 {
-    return !!js_SetPropertyHelper(cx, obj, ATOM_TO_JSID(name), defineHow, vp, strict);
+    return !!js_SetPropertyHelper(cx, obj, NameToId(name), defineHow, vp, strict);
 }
 
 } /* namespace js */
 
 extern JSBool
 js_SetElementHelper(JSContext *cx, js::HandleObject obj, uint32_t index, unsigned defineHow,
                     js::Value *vp, JSBool strict);
 
@@ -792,17 +792,17 @@ struct JSObject : public js::ObjectImpl
     js::Shape *putProperty(JSContext *cx, jsid id,
                            JSPropertyOp getter, JSStrictPropertyOp setter,
                            uint32_t slot, unsigned attrs,
                            unsigned flags, int shortid);
     inline js::Shape *
     putProperty(JSContext *cx, js::PropertyName *name,
                 JSPropertyOp getter, JSStrictPropertyOp setter,
                 uint32_t slot, unsigned attrs, unsigned flags, int shortid) {
-        return putProperty(cx, js_CheckForStringIndex(ATOM_TO_JSID(name)), getter, setter, slot, attrs, flags, shortid);
+        return putProperty(cx, js::NameToId(name), getter, setter, slot, attrs, flags, shortid);
     }
 
     /* Change the given property into a sibling with the same id in this scope. */
     js::Shape *changeProperty(JSContext *cx, js::Shape *shape, unsigned attrs, unsigned mask,
                               JSPropertyOp getter, JSStrictPropertyOp setter);
 
     inline bool changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs);
 
@@ -1127,19 +1127,16 @@ js_CreateThisForFunctionWithProto(JSCont
 // Specialized call for constructing |this| with a known function callee.
 extern JSObject *
 js_CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
 
 // Generic call for constructing |this|.
 extern JSObject *
 js_CreateThis(JSContext *cx, js::Class *clasp, JSObject *callee);
 
-extern jsid
-js_CheckForStringIndex(jsid id);
-
 /*
  * Find or create a property named by id in obj's scope, with the given getter
  * and setter, slot, attributes, and other members.
  */
 extern js::Shape *
 js_AddNativeProperty(JSContext *cx, js::HandleObject obj, jsid id,
                      JSPropertyOp getter, JSStrictPropertyOp setter, uint32_t slot,
                      unsigned attrs, unsigned flags, int shortid);
@@ -1168,32 +1165,32 @@ DefineNativeProperty(JSContext *cx, Hand
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                      unsigned flags, int shortid, unsigned defineHow = 0);
 
 inline const Shape *
 DefineNativeProperty(JSContext *cx, HandleObject obj, PropertyName *name, const Value &value,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                      unsigned flags, int shortid, unsigned defineHow = 0)
 {
-    return DefineNativeProperty(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs, flags,
+    return DefineNativeProperty(cx, obj, NameToId(name), value, getter, setter, attrs, flags,
                                 shortid, defineHow);
 }
 
 /*
  * Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
  */
 extern bool
 LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                         JSObject **objp, JSProperty **propp);
 
 inline bool
 LookupPropertyWithFlags(JSContext *cx, JSObject *obj, PropertyName *name, unsigned flags,
                         JSObject **objp, JSProperty **propp)
 {
-    return LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(name), flags, objp, propp);
+    return LookupPropertyWithFlags(cx, obj, NameToId(name), flags, objp, propp);
 }
 
 /*
  * Call the [[DefineOwnProperty]] internal method of obj.
  *
  * If obj is an array, this follows ES5 15.4.5.1.
  * If obj is any other native object, this follows ES5 8.12.9.
  * If obj is a proxy, this calls the proxy handler's defineProperty method.
@@ -1262,17 +1259,17 @@ js_NativeSet(JSContext *cx, JSObject *ob
 namespace js {
 
 bool
 GetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, uint32_t getHow, Value *vp);
 
 inline bool
 GetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, uint32_t getHow, Value *vp)
 {
-    return GetPropertyHelper(cx, obj, ATOM_TO_JSID(name), getHow, vp);
+    return GetPropertyHelper(cx, obj, NameToId(name), getHow, vp);
 }
 
 bool
 GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, PropertyDescriptor *desc);
 
 bool
 GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
 
@@ -1284,35 +1281,34 @@ NewPropertyDescriptorObject(JSContext *c
 extern JSBool
 js_GetMethod(JSContext *cx, js::HandleObject obj, jsid id, unsigned getHow, js::Value *vp);
 
 namespace js {
 
 inline bool
 GetMethod(JSContext *cx, HandleObject obj, PropertyName *name, unsigned getHow, Value *vp)
 {
-    return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
+    return js_GetMethod(cx, obj, NameToId(name), getHow, vp);
 }
 
 } /* namespace js */
 
 namespace js {
 
 /*
  * If obj has an already-resolved data property for id, return true and
- * store the property value in *vp. This helper assumes the caller has already
- * called js_CheckForStringIndex.
+ * store the property value in *vp.
  */
 extern bool
 HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp);
 
 inline bool
-HasDataProperty(JSContext *cx, HandleObject obj, JSAtom *atom, Value *vp)
+HasDataProperty(JSContext *cx, HandleObject obj, PropertyName *name, Value *vp)
 {
-    return HasDataProperty(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(atom)), vp);
+    return HasDataProperty(cx, obj, NameToId(name), vp);
 }
 
 extern JSBool
 CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
             js::Value *vp, unsigned *attrsp);
 
 } /* namespace js */
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -126,17 +126,17 @@ JSObject::setGeneric(JSContext *cx, jsid
                                 js::RootedVarObject(cx, this),
                                 js::RootedVarId(cx, id),
                                 0, vp, strict);
 }
 
 inline JSBool
 JSObject::setProperty(JSContext *cx, js::PropertyName *name, js::Value *vp, JSBool strict)
 {
-    return setGeneric(cx, ATOM_TO_JSID(name), vp, strict);
+    return setGeneric(cx, js::NameToId(name), vp, strict);
 }
 
 inline JSBool
 JSObject::setElement(JSContext *cx, uint32_t index, js::Value *vp, JSBool strict)
 {
     if (getOps()->setElement)
         return nonNativeSetElement(cx, index, vp, strict);
     return js_SetElementHelper(cx, js::RootedVarObject(cx, this), index, 0, vp, strict);
@@ -154,17 +154,17 @@ JSObject::setGenericAttributes(JSContext
     js::types::MarkTypePropertyConfigured(cx, this, id);
     js::GenericAttributesOp op = getOps()->setGenericAttributes;
     return (op ? op : js_SetAttributes)(cx, this, id, attrsp);
 }
 
 inline JSBool
 JSObject::setPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
 {
-    return setGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
+    return setGenericAttributes(cx, js::NameToId(name), attrsp);
 }
 
 inline JSBool
 JSObject::setElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
 {
     js::ElementAttributesOp op = getOps()->setElementAttributes;
     return (op ? op : js_SetElementAttributes)(cx, this, index, attrsp);
 }
@@ -193,35 +193,35 @@ JSObject::getGeneric(JSContext *cx, JSOb
             return false;
     }
     return true;
 }
 
 inline JSBool
 JSObject::getProperty(JSContext *cx, JSObject *receiver, js::PropertyName *name, js::Value *vp)
 {
-    return getGeneric(cx, receiver, ATOM_TO_JSID(name), vp);
+    return getGeneric(cx, receiver, js::NameToId(name), vp);
 }
 
 inline JSBool
 JSObject::getGeneric(JSContext *cx, jsid id, js::Value *vp)
 {
     return getGeneric(cx, this, id, vp);
 }
 
 inline JSBool
 JSObject::getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp)
 {
-    return getGeneric(cx, ATOM_TO_JSID(name), vp);
+    return getGeneric(cx, js::NameToId(name), vp);
 }
 
 inline bool
 JSObject::deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict)
 {
-    jsid id = js_CheckForStringIndex(ATOM_TO_JSID(name));
+    jsid id = js::NameToId(name);
     js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
     js::types::MarkTypePropertyConfigured(cx, this, id);
     js::DeletePropertyOp op = getOps()->deleteProperty;
     return (op ? op : js_DeleteProperty)(cx, this, name, rval, strict);
 }
 
 inline bool
 JSObject::deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict)
@@ -393,17 +393,17 @@ JSObject::setArrayLength(JSContext *cx, 
     if (length > INT32_MAX) {
         /*
          * Mark the type of this object as possibly not a dense array, per the
          * requirements of OBJECT_FLAG_NON_DENSE_ARRAY.
          */
         js::types::MarkTypeObjectFlags(cx, this,
                                        js::types::OBJECT_FLAG_NON_PACKED_ARRAY |
                                        js::types::OBJECT_FLAG_NON_DENSE_ARRAY);
-        jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+        jsid lengthId = js::NameToId(cx->runtime->atomState.lengthAtom);
         js::types::AddTypePropertyId(cx, this, lengthId,
                                      js::types::Type::DoubleType());
     }
 
     getElementsHeader()->length = length;
 }
 
 inline void
@@ -1025,17 +1025,17 @@ JSObject::lookupGeneric(JSContext *cx, j
 {
     js::LookupGenericOp op = getOps()->lookupGeneric;
     return (op ? op : js_LookupProperty)(cx, this, id, objp, propp);
 }
 
 inline JSBool
 JSObject::lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp)
 {
-    return lookupGeneric(cx, ATOM_TO_JSID(name), objp, propp);
+    return lookupGeneric(cx, js::NameToId(name), objp, propp);
 }
 
 inline JSBool
 JSObject::defineGeneric(JSContext *cx, jsid id, const js::Value &value,
                         JSPropertyOp getter /* = JS_PropertyStub */,
                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
                         unsigned attrs /* = JSPROP_ENUMERATE */)
 {
@@ -1045,17 +1045,17 @@ JSObject::defineGeneric(JSContext *cx, j
 }
 
 inline JSBool
 JSObject::defineProperty(JSContext *cx, js::PropertyName *name, const js::Value &value,
                         JSPropertyOp getter /* = JS_PropertyStub */,
                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
                         unsigned attrs /* = JSPROP_ENUMERATE */)
 {
-    return defineGeneric(cx, ATOM_TO_JSID(name), value, getter, setter, attrs);
+    return defineGeneric(cx, js::NameToId(name), value, getter, setter, attrs);
 }
 
 inline JSBool
 JSObject::defineElement(JSContext *cx, uint32_t index, const js::Value &value,
                         JSPropertyOp getter /* = JS_PropertyStub */,
                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
                         unsigned attrs /* = JSPROP_ENUMERATE */)
 {
@@ -1152,17 +1152,17 @@ JSObject::getGenericAttributes(JSContext
 {
     js::GenericAttributesOp op = getOps()->getGenericAttributes;
     return (op ? op : js_GetAttributes)(cx, this, id, attrsp);
 }
 
 inline JSBool
 JSObject::getPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
 {
-    return getGenericAttributes(cx, ATOM_TO_JSID(name), attrsp);
+    return getGenericAttributes(cx, js::NameToId(name), attrsp);
 }
 
 inline JSBool
 JSObject::getElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
 {
     jsid id;
     if (!js::IndexToId(cx, index, &id))
         return false;
@@ -1543,17 +1543,17 @@ PreallocateObjectDynamicSlots(JSContext 
 inline bool
 DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
                               JSProtoKey key, JSObject *ctor, JSObject *proto)
 {
     JS_ASSERT(!global->nativeEmpty()); /* reserved slots already allocated */
     JS_ASSERT(ctor);
     JS_ASSERT(proto);
 
-    jsid id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
+    jsid id = NameToId(cx->runtime->atomState.classAtoms[key]);
     JS_ASSERT(!global->nativeLookupNoAllocation(cx, id));
 
     /* Set these first in case AddTypePropertyId looks for this class. */
     global->setSlot(key, ObjectValue(*ctor));
     global->setSlot(key + JSProto_LIMIT, ObjectValue(*proto));
     global->setSlot(key + JSProto_LIMIT * 2, ObjectValue(*ctor));
 
     types::AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -308,17 +308,17 @@ template<typename KeyType>
 static bool
 PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, StringifyContext *scx)
 {
     JSString *keyStr = NULL;
 
     /* Step 2. */
     if (vp->isObject()) {
         Value toJSON;
-        jsid id = ATOM_TO_JSID(cx->runtime->atomState.toJSONAtom);
+        jsid id = NameToId(cx->runtime->atomState.toJSONAtom);
         if (!js_GetMethod(cx, RootedVarObject(cx, &vp->toObject()), id, 0, &toJSON))
             return false;
 
         if (js_IsCallable(toJSON)) {
             keyStr = KeyStringifier<KeyType>::toString(cx, key);
             if (!keyStr)
                 return false;
 
@@ -675,29 +675,27 @@ js_Stringify(JSContext *cx, Value *vp, J
 
                 jsid id;
                 if (v.isNumber()) {
                     /* Step 4b(iv)(4). */
                     int32_t n;
                     if (v.isNumber() && ValueFitsInInt32(v, &n) && INT_FITS_IN_JSID(n)) {
                         id = INT_TO_JSID(n);
                     } else {
-                        if (!js_ValueToStringId(cx, v, &id))
+                        if (!ValueToId(cx, v, &id))
                             return false;
-                        id = js_CheckForStringIndex(id);
                     }
                 } else if (v.isString() ||
                            (v.isObject() &&
                             (ObjectClassIs(v.toObject(), ESClass_String, cx) ||
                              ObjectClassIs(v.toObject(), ESClass_Number, cx))))
                 {
                     /* Step 4b(iv)(3), 4b(iv)(5). */
-                    if (!js_ValueToStringId(cx, v, &id))
+                    if (!ValueToId(cx, v, &id))
                         return false;
-                    id = js_CheckForStringIndex(id);
                 } else {
                     continue;
                 }
 
                 /* Step 4b(iv)(6). */
                 HashSet<jsid>::AddPtr p = idSet.lookupForAdd(id);
                 if (!p) {
                     /* Step 4b(iv)(6)(a). */
@@ -750,17 +748,17 @@ js_Stringify(JSContext *cx, Value *vp, J
     }
 
     /* Step 9. */
     RootedVarObject wrapper(cx, NewBuiltinClassInstance(cx, &ObjectClass));
     if (!wrapper)
         return false;
 
     /* Step 10. */
-    jsid emptyId = ATOM_TO_JSID(cx->runtime->atomState.emptyAtom);
+    jsid emptyId = NameToId(cx->runtime->atomState.emptyAtom);
     if (!DefineNativeProperty(cx, wrapper, emptyId, *vp, JS_PropertyStub, JS_StrictPropertyStub,
                               JSPROP_ENUMERATE, 0, 0))
     {
         return false;
     }
 
     /* Step 11. */
     StringifyContext scx(cx, sb, gap, replacer, propertyList);
@@ -884,17 +882,17 @@ Revive(JSContext *cx, const Value &reviv
 
     JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
     if (!obj)
         return false;
 
     if (!obj->defineProperty(cx, cx->runtime->atomState.emptyAtom, *vp))
         return false;
 
-    return Walk(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.emptyAtom), reviver, vp);
+    return Walk(cx, obj, NameToId(cx->runtime->atomState.emptyAtom), reviver, vp);
 }
 
 namespace js {
 
 JSBool
 ParseJSONWithReviver(JSContext *cx, const jschar *chars, size_t length, const Value &reviver,
                      Value *vp, DecodingMode decodingMode /* = STRICT */)
 {
@@ -911,17 +909,17 @@ ParseJSONWithReviver(JSContext *cx, cons
 }
 
 } /* namespace js */
 
 #if JS_HAS_TOSOURCE
 static JSBool
 json_toSource(JSContext *cx, unsigned argc, Value *vp)
 {
-    vp->setString(CLASS_ATOM(cx, JSON));
+    vp->setString(CLASS_NAME(cx, JSON));
     return JS_TRUE;
 }
 #endif
 
 static JSFunctionSpec json_static_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,  json_toSource,      0, 0),
 #endif
--- a/js/src/jsonparser.cpp
+++ b/js/src/jsonparser.cpp
@@ -529,21 +529,17 @@ JSONParser::parse(Value *vp)
     *vp = UndefinedValue();
 
     Token token;
     ParserState state = JSONValue;
     while (true) {
         switch (state) {
           case FinishObjectMember: {
             Value v = valueStack.popCopy();
-            /*
-             * NB: Relies on js_DefineNativeProperty performing
-             *     js_CheckForStringIndex.
-             */
-            jsid propid = ATOM_TO_JSID(&valueStack.popCopy().toString()->asAtom());
+            jsid propid = AtomToId(&valueStack.popCopy().toString()->asAtom());
             RootedVarObject obj(cx, &valueStack.back().toObject());
             if (!DefineNativeProperty(cx, obj, propid, v,
                                       JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE,
                                       0, 0))
             {
                 return false;
             }
             token = advanceAfterProperty();
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -222,17 +222,17 @@ PropertyCache::fullTest(JSContext *cx, j
             break;
         pobj = tmp;
         protoIndex--;
     }
 
     if (pobj->lastProperty() == entry->pshape) {
 #ifdef DEBUG
         PropertyName *name = GetNameFromBytecode(cx, pc, op, cs);
-        JS_ASSERT(pobj->nativeContains(cx, js_CheckForStringIndex(ATOM_TO_JSID(name))));
+        JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));
 #endif
         *pobjp = pobj;
         return NULL;
     }
 
     PCMETER(vcapmisses++);
     return GetNameFromBytecode(cx, pc, op, cs);
 }
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -391,50 +391,50 @@ ProxyHandler::finalize(JSFreeOp *fop, JS
 }
 
 void
 ProxyHandler::trace(JSTracer *trc, JSObject *proxy)
 {
 }
 
 static bool
-GetTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
+GetTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
 {
     JS_CHECK_RECURSION(cx, return false);
 
-    return handler->getGeneric(cx, ATOM_TO_JSID(atom), fvalp);
+    return handler->getGeneric(cx, NameToId(name), fvalp);
 }
 
 static bool
-GetFundamentalTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
+GetFundamentalTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
 {
-    if (!GetTrap(cx, handler, atom, fvalp))
+    if (!GetTrap(cx, handler, name, fvalp))
         return false;
 
     if (!js_IsCallable(*fvalp)) {
         JSAutoByteString bytes;
-        if (js_AtomToPrintableString(cx, atom, &bytes))
+        if (js_AtomToPrintableString(cx, name, &bytes))
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_FUNCTION, bytes.ptr());
         return false;
     }
 
     return true;
 }
 
 static bool
-GetDerivedTrap(JSContext *cx, JSObject *handler, JSAtom *atom, Value *fvalp)
+GetDerivedTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
 {
-    JS_ASSERT(atom == ATOM(has) ||
-              atom == ATOM(hasOwn) ||
-              atom == ATOM(get) ||
-              atom == ATOM(set) ||
-              atom == ATOM(keys) ||
-              atom == ATOM(iterate));
+    JS_ASSERT(name == ATOM(has) ||
+              name == ATOM(hasOwn) ||
+              name == ATOM(get) ||
+              name == ATOM(set) ||
+              name == ATOM(keys) ||
+              name == ATOM(iterate));
 
-    return GetTrap(cx, handler, atom, fvalp);
+    return GetTrap(cx, handler, name, fvalp);
 }
 
 static bool
 Trap(JSContext *cx, HandleObject handler, HandleValue fval, unsigned argc, Value* argv, Value *rval)
 {
     return Invoke(cx, ObjectValue(*handler), fval, argc, argv, rval);
 }
 
@@ -508,17 +508,17 @@ ArrayToIdVector(JSContext *cx, const Val
         if (!JS_CHECK_OPERATION_LIMIT(cx))
             return false;
         Value v;
         if (!obj->getElement(cx, n, &v))
             return false;
         jsid id;
         if (!ValueToId(cx, v, &id))
             return false;
-        if (!props.append(js_CheckForStringIndex(id)))
+        if (!props.append(id))
             return false;
     }
 
     return true;
 }
 
 /* Derived class for all scripted proxy handlers. */
 class ScriptedProxyHandler : public ProxyHandler {
@@ -998,18 +998,16 @@ proxy_innerObject(JSContext *cx, JSObjec
 }
 
 static JSBool
 proxy_LookupGeneric(JSContext *cx, JSObject *obj_, jsid id, JSObject **objp,
                     JSProperty **propp)
 {
     RootedVarObject obj(cx, obj_);
 
-    id = js_CheckForStringIndex(id);
-
     bool found;
     if (!Proxy::has(cx, obj, id, &found))
         return false;
 
     if (found) {
         *propp = (JSProperty *)0x1;
         *objp = obj;
     } else {
@@ -1018,17 +1016,17 @@ proxy_LookupGeneric(JSContext *cx, JSObj
     }
     return true;
 }
 
 static JSBool
 proxy_LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
                      JSProperty **propp)
 {
-    return proxy_LookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return proxy_LookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 static JSBool
 proxy_LookupElement(JSContext *cx, JSObject *obj_, uint32_t index, JSObject **objp,
                     JSProperty **propp)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -1043,33 +1041,31 @@ proxy_LookupSpecial(JSContext *cx, JSObj
 {
     return proxy_LookupGeneric(cx, obj, SPECIALID_TO_JSID(sid), objp, propp);
 }
 
 static JSBool
 proxy_DefineGeneric(JSContext *cx, JSObject *obj, jsid id, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    id = js_CheckForStringIndex(id);
-
     AutoPropertyDescriptorRooter desc(cx);
     desc.obj = obj;
     desc.value = *value;
     desc.attrs = (attrs & (~JSPROP_SHORTID));
     desc.getter = getter;
     desc.setter = setter;
     desc.shortid = 0;
     return Proxy::defineProperty(cx, obj, id, &desc);
 }
 
 static JSBool
 proxy_DefineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *value,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    return proxy_DefineGeneric(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs);
+    return proxy_DefineGeneric(cx, obj, NameToId(name), value, getter, setter, attrs);
 }
 
 static JSBool
 proxy_DefineElement(JSContext *cx, JSObject *obj_, uint32_t index, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -1084,25 +1080,23 @@ proxy_DefineSpecial(JSContext *cx, JSObj
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     return proxy_DefineGeneric(cx, obj, SPECIALID_TO_JSID(sid), value, getter, setter, attrs);
 }
 
 static JSBool
 proxy_GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
-    id = js_CheckForStringIndex(id);
-
     return Proxy::get(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 proxy_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
 {
-    return proxy_GetGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
+    return proxy_GetGeneric(cx, obj, receiver, NameToId(name), vp);
 }
 
 static JSBool
 proxy_GetElement(JSContext *cx, JSObject *obj_, JSObject *receiver_, uint32_t index, Value *vp)
 {
     RootedVarObject obj(cx, obj_);
     RootedVarObject receiver(cx, receiver_);
 
@@ -1123,25 +1117,23 @@ static JSBool
 proxy_GetSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp)
 {
     return proxy_GetGeneric(cx, obj, receiver, SPECIALID_TO_JSID(sid), vp);
 }
 
 static JSBool
 proxy_SetGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
-    id = js_CheckForStringIndex(id);
-
     return Proxy::set(cx, obj, obj, id, strict, vp);
 }
 
 static JSBool
 proxy_SetProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
 {
-    return proxy_SetGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
+    return proxy_SetGeneric(cx, obj, NameToId(name), vp, strict);
 }
 
 static JSBool
 proxy_SetElement(JSContext *cx, JSObject *obj_, uint32_t index, Value *vp, JSBool strict)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
@@ -1154,29 +1146,27 @@ static JSBool
 proxy_SetSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool strict)
 {
     return proxy_SetGeneric(cx, obj, SPECIALID_TO_JSID(sid), vp, strict);
 }
 
 static JSBool
 proxy_GetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp)
 {
-    id = js_CheckForStringIndex(id);
-
     AutoPropertyDescriptorRooter desc(cx);
     if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, false, &desc))
         return false;
     *attrsp = desc.attrs;
     return true;
 }
 
 static JSBool
 proxy_GetPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
 {
-    return proxy_GetGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return proxy_GetGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 static JSBool
 proxy_GetElementAttributes(JSContext *cx, JSObject *obj_, uint32_t index, unsigned *attrsp)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
@@ -1189,30 +1179,28 @@ static JSBool
 proxy_GetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp)
 {
     return proxy_GetGenericAttributes(cx, obj, SPECIALID_TO_JSID(sid), attrsp);
 }
 
 static JSBool
 proxy_SetGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp)
 {
-    id = js_CheckForStringIndex(id);
-
     /* Lookup the current property descriptor so we have setter/getter/value. */
     AutoPropertyDescriptorRooter desc(cx);
     if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, true, &desc))
         return false;
     desc.attrs = (*attrsp & (~JSPROP_SHORTID));
     return Proxy::defineProperty(cx, obj, id, &desc);
 }
 
 static JSBool
 proxy_SetPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
 {
-    return proxy_SetGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return proxy_SetGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 static JSBool
 proxy_SetElementAttributes(JSContext *cx, JSObject *obj_, uint32_t index, unsigned *attrsp)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
@@ -1225,32 +1213,30 @@ static JSBool
 proxy_SetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp)
 {
     return proxy_SetGenericAttributes(cx, obj, SPECIALID_TO_JSID(sid), attrsp);
 }
 
 static JSBool
 proxy_DeleteGeneric(JSContext *cx, JSObject *obj_, jsid id, Value *rval, JSBool strict)
 {
-    JS_ASSERT(id == js_CheckForStringIndex(id));
-
     RootedVarObject obj(cx, obj_);
 
     // TODO: throwing away strict
     bool deleted;
     if (!Proxy::delete_(cx, obj, id, &deleted) || !js_SuppressDeletedProperty(cx, obj, id))
         return false;
     rval->setBoolean(deleted);
     return true;
 }
 
 static JSBool
 proxy_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    return proxy_DeleteGeneric(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(name)), rval, strict);
+    return proxy_DeleteGeneric(cx, obj, NameToId(name), rval, strict);
 }
 
 static JSBool
 proxy_DeleteElement(JSContext *cx, JSObject *obj_, uint32_t index, Value *rval, JSBool strict)
 {
     RootedVarObject obj(cx, obj_);
 
     jsid id;
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -201,17 +201,17 @@ class NodeBuilder
 
         for (unsigned i = 0; i < AST_LIMIT; i++) {
             Value funv;
 
             const char *name = callbackNames[i];
             JSAtom *atom = js_Atomize(cx, name, strlen(name));
             if (!atom)
                 return false;
-            RootedVarId id(cx, ATOM_TO_JSID(atom));
+            RootedVarId id(cx, AtomToId(atom));
             if (!GetPropertyDefault(cx, userobj, id, NullValue(), &funv))
                 return false;
 
             if (funv.isNullOrUndefined()) {
                 callbacks[i].setNull();
                 continue;
             }
 
@@ -3130,25 +3130,25 @@ reflect_parse(JSContext *cx, uint32_t ar
             return JS_FALSE;
         }
 
         RootedVarObject config(cx, &arg.toObject());
 
         Value prop;
 
         /* config.loc */
-        RootedVarId locId(cx, ATOM_TO_JSID(cx->runtime->atomState.locAtom));
+        RootedVarId locId(cx, NameToId(cx->runtime->atomState.locAtom));
         if (!GetPropertyDefault(cx, config, locId, BooleanValue(true), &prop))
             return JS_FALSE;
 
         loc = js_ValueToBoolean(prop);
 
         if (loc) {
             /* config.source */
-            RootedVarId sourceId(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom));
+            RootedVarId sourceId(cx, NameToId(cx->runtime->atomState.sourceAtom));
             if (!GetPropertyDefault(cx, config, sourceId, NullValue(), &prop))
                 return JS_FALSE;
 
             if (!prop.isNullOrUndefined()) {
                 JSString *str = ToString(cx, prop);
                 if (!str)
                     return JS_FALSE;
 
@@ -3159,25 +3159,25 @@ reflect_parse(JSContext *cx, uint32_t ar
 
                 filename = DeflateString(cx, chars, length);
                 if (!filename)
                     return JS_FALSE;
                 filenamep.reset(filename);
             }
 
             /* config.line */
-            RootedVarId lineId(cx, ATOM_TO_JSID(cx->runtime->atomState.lineAtom));
+            RootedVarId lineId(cx, NameToId(cx->runtime->atomState.lineAtom));
             if (!GetPropertyDefault(cx, config, lineId, Int32Value(1), &prop) ||
                 !ToUint32(cx, prop, &lineno)) {
                 return JS_FALSE;
             }
         }
 
         /* config.builder */
-        RootedVarId builderId(cx, ATOM_TO_JSID(cx->runtime->atomState.builderAtom));
+        RootedVarId builderId(cx, NameToId(cx->runtime->atomState.builderAtom));
         if (!GetPropertyDefault(cx, config, builderId, NullValue(), &prop))
             return JS_FALSE;
 
         if (!prop.isNullOrUndefined()) {
             if (!prop.isObject()) {
                 js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
                                          JSDVG_SEARCH_STACK, prop, NULL, "not an object", NULL);
                 return JS_FALSE;
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -758,19 +758,17 @@ struct Shape : public js::gc::Cell
 
     int16_t shortid() const { JS_ASSERT(hasShortID()); return maybeShortid(); }
     int16_t maybeShortid() const { return shortid_; }
 
     /*
      * If SHORTID is set in shape->flags, we use shape->shortid rather
      * than id when calling shape's getter or setter.
      */
-    jsid getUserId() const {
-        return hasShortID() ? INT_TO_JSID(shortid()) : propid();
-    }
+    inline bool getUserId(JSContext *cx, jsid *idp) const;
 
     uint8_t attributes() const { return attrs; }
     bool configurable() const { return (attrs & JSPROP_PERMANENT) == 0; }
     bool enumerable() const { return (attrs & JSPROP_ENUMERATE) != 0; }
     bool writable() const {
         // JS_ASSERT(isDataDescriptor());
         return (attrs & JSPROP_READONLY) == 0;
     }
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -272,32 +272,58 @@ Shape::matchesParamsAfterId(BaseShape *b
     return base->unowned() == this->base()->unowned() &&
            maybeSlot() == aslot &&
            attrs == aattrs &&
            ((flags ^ aflags) & PUBLIC_FLAGS) == 0 &&
            shortid_ == ashortid;
 }
 
 inline bool
+Shape::getUserId(JSContext *cx, jsid *idp) const
+{
+    const Shape *self = this;
+#ifdef DEBUG
+    {
+        SkipRoot skip(cx, &self);
+        MaybeCheckStackRoots(cx);
+    }
+#endif
+    if (self->hasShortID()) {
+        int16_t id = self->shortid();
+        if (id < 0)
+            return ValueToId(cx, Int32Value(id), idp);
+        *idp = INT_TO_JSID(id);
+    } else {
+        *idp = propid();
+    }
+    return true;
+}
+
+inline bool
 Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
 {
     JS_ASSERT(!hasDefaultGetter());
 
     if (hasGetterValue()) {
         js::Value fval = getterValue();
         return js::InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
     }
 
     /*
      * |with (it) color;| ends up here, as do XML filter-expressions.
      * Avoid exposing the With object to native getters.
      */
     if (obj->isWith())
         obj = &obj->asWith().object();
-    return js::CallJSPropertyOp(cx, getterOp(), receiver, getUserId(), vp);
+
+    jsid id;
+    if (!getUserId(cx, &id))
+        return false;
+
+    return js::CallJSPropertyOp(cx, getterOp(), receiver, id, vp);
 }
 
 inline bool
 Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const
 {
     JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
 
     if (attrs & JSPROP_SETTER) {
@@ -306,17 +332,22 @@ Shape::set(JSContext* cx, JSObject* obj,
     }
 
     if (attrs & JSPROP_GETTER)
         return js_ReportGetterOnlyAssignment(cx);
 
     /* See the comment in js::Shape::get as to why we check for With. */
     if (obj->isWith())
         obj = &obj->asWith().object();
-    return js::CallJSPropertyOpSetter(cx, setterOp(), obj, getUserId(), strict, vp);
+
+    jsid id;
+    if (!getUserId(cx, &id))
+        return false;
+
+    return js::CallJSPropertyOpSetter(cx, setterOp(), obj, id, strict, vp);
 }
 
 inline void
 Shape::setParent(js::Shape *p)
 {
     JS_ASSERT_IF(p && !p->hasMissingSlot() && !inDictionary(),
                  p->maybeSlot() <= maybeSlot());
     JS_ASSERT_IF(p && !inDictionary(),
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -86,17 +86,17 @@ namespace js {
 
 BindingKind
 Bindings::lookup(JSContext *cx, JSAtom *name, unsigned *indexp) const
 {
     if (!lastBinding)
         return NONE;
 
     Shape **spp;
-    Shape *shape = Shape::search(cx, lastBinding, ATOM_TO_JSID(name), &spp);
+    Shape *shape = Shape::search(cx, lastBinding, AtomToId(name), &spp);
     if (!shape)
         return NONE;
 
     if (indexp)
         *indexp = shape->shortid();
 
     if (shape->getter() == CallObject::getArgOp)
         return ARGUMENT;
@@ -147,17 +147,17 @@ Bindings::add(JSContext *cx, HandleAtom 
         slot += nargs + nvars;
     }
 
     RootedVarId id(cx);
     if (!name) {
         JS_ASSERT(kind == ARGUMENT); /* destructuring */
         id = INT_TO_JSID(nargs);
     } else {
-        id = ATOM_TO_JSID(name);
+        id = AtomToId(name);
     }
 
     StackBaseShape base(&CallClass, NULL, BaseShape::VAROBJ);
     base.updateGetterSetter(attrs, getter, setter);
 
     UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);
     if (!nbase)
         return NULL;
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -472,17 +472,17 @@ ThisToStringForStringProto(JSContext *cx
     if (call.thisv().isString())
         return call.thisv().toString();
 
     if (call.thisv().isObject()) {
         RootedVarObject obj(cx, &call.thisv().toObject());
         if (obj->isString() &&
             ClassMethodIsNative(cx, obj,
                                 &StringClass,
-                                RootedVarId(cx, ATOM_TO_JSID(cx->runtime->atomState.toStringAtom)),
+                                RootedVarId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
                                 js_str_toString))
         {
             JSString *str = obj->asString().unbox();
             call.thisv().setString(str);
             return str;
         }
     } else if (call.thisv().isNullOrUndefined()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
@@ -1829,17 +1829,17 @@ FindReplaceLength(JSContext *cx, RegExpS
             atom = &str->asAtom();
         } else {
             atom = js_AtomizeString(cx, str);
             if (!atom)
                 return false;
         }
 
         Value v;
-        if (HasDataProperty(cx, base, atom, &v) && v.isString()) {
+        if (HasDataProperty(cx, base, AtomToId(atom), &v) && v.isString()) {
             rdata.repstr = v.toString()->ensureLinear(cx);
             if (!rdata.repstr)
                 return false;
             *sizep = rdata.repstr->length();
             return true;
         }
 
         /*
@@ -3099,34 +3099,34 @@ static JSFunctionSpec string_static_meth
     JS_FS_END
 };
 
 Shape *
 StringObject::assignInitialShape(JSContext *cx)
 {
     JS_ASSERT(nativeEmpty());
 
-    return addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
+    return addDataProperty(cx, NameToId(cx->runtime->atomState.lengthAtom),
                            LENGTH_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 JSObject *
 js_InitStringClass(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isNative());
 
     RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedVarObject proto(cx, global->createBlankPrototype(cx, &StringClass));
     if (!proto || !proto->asString().init(cx, RootedVarString(cx, cx->runtime->emptyString)))
         return NULL;
 
     /* Now create the String function. */
     RootedVarFunction ctor(cx);
-    ctor = global->createConstructor(cx, js_String, CLASS_ATOM(cx, String), 1);
+    ctor = global->createConstructor(cx, js_String, CLASS_NAME(cx, String), 1);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, proto, NULL, string_methods) ||
         !DefinePropertiesAndBrand(cx, ctor, NULL, string_static_methods))
@@ -3330,17 +3330,17 @@ js_ValueToSource(JSContext *cx, const Va
 
             return js_NewStringCopyN(cx, js_negzero_ucNstr, 2);
         }
         return ToString(cx, v);
     }
 
     Value rval = NullValue();
     Value fval;
-    jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
+    jsid id = NameToId(cx->runtime->atomState.toSourceAtom);
     if (!js_GetMethod(cx, RootedVarObject(cx, &v.toObject()), id, 0, &fval))
         return NULL;
     if (js_IsCallable(fval)) {
         if (!Invoke(cx, v, fval, 0, NULL, &rval))
             return NULL;
     }
 
     return ToString(cx, rval);
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -384,17 +384,17 @@ ArrayBufferObject::obj_lookupGeneric(JSC
 
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 JSBool
 ArrayBufferObject::obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
                                       JSObject **objp, JSProperty **propp)
 {
-    return obj_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return obj_lookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 JSBool
 ArrayBufferObject::obj_lookupElement(JSContext *cx, JSObject *obj_, uint32_t index,
                                      JSObject **objp, JSProperty **propp)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -449,17 +449,17 @@ ArrayBufferObject::obj_defineGeneric(JSC
     return js_DefineProperty(cx, delegate, id, v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_defineProperty(JSContext *cx, JSObject *obj,
                                       PropertyName *name, const Value *v,
                                       PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    return obj_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
+    return obj_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_defineElement(JSContext *cx, JSObject *obj_, uint32_t index, const Value *v,
                                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     RootedVarObject obj(cx, obj_);
     RootGetterSetter gsRoot(cx, attrs, &getter, &setter);
@@ -515,17 +515,17 @@ ArrayBufferObject::obj_getProperty(JSCon
     if (name == cx->runtime->atomState.byteLengthAtom) {
         vp->setInt32(obj->asArrayBuffer().byteLength());
         return true;
     }
 
     RootedVarObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
         return false;
-    return js_GetProperty(cx, delegate, receiver, ATOM_TO_JSID(name), vp);
+    return js_GetProperty(cx, delegate, receiver, NameToId(name), vp);
 }
 
 JSBool
 ArrayBufferObject::obj_getElement(JSContext *cx, JSObject *obj,
                                   JSObject *receiver_, uint32_t index, Value *vp)
 {
     RootedVarObject receiver(cx, receiver_);
 
@@ -611,17 +611,17 @@ ArrayBufferObject::obj_setGeneric(JSCont
 
     return js_SetPropertyHelper(cx, delegate, id, 0, vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_setProperty(JSContext *cx, JSObject *obj,
                                    PropertyName *name, Value *vp, JSBool strict)
 {
-    return obj_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
+    return obj_setGeneric(cx, obj, NameToId(name), vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_setElement(JSContext *cx, JSObject *obj_,
                                   uint32_t index, Value *vp, JSBool strict)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -656,17 +656,17 @@ ArrayBufferObject::obj_getGenericAttribu
         return false;
     return js_GetAttributes(cx, delegate, id, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_getPropertyAttributes(JSContext *cx, JSObject *obj,
                                              PropertyName *name, unsigned *attrsp)
 {
-    return obj_getGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return obj_getGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_getElementAttributes(JSContext *cx, JSObject *obj_,
                                             uint32_t index, unsigned *attrsp)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -701,17 +701,17 @@ ArrayBufferObject::obj_setGenericAttribu
         return false;
     return js_SetAttributes(cx, delegate, id, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setPropertyAttributes(JSContext *cx, JSObject *obj,
                                              PropertyName *name, unsigned *attrsp)
 {
-    return obj_setGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return obj_setGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setElementAttributes(JSContext *cx, JSObject *obj_,
                                             uint32_t index, unsigned *attrsp)
 {
     RootedVarObject obj(cx, obj_);
 
@@ -902,17 +902,17 @@ TypedArray::obj_lookupGeneric(JSContext 
 
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 JSBool
 TypedArray::obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
                                JSObject **objp, JSProperty **propp)
 {
-    return obj_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return obj_lookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 JSBool
 TypedArray::obj_lookupElement(JSContext *cx, JSObject *obj, uint32_t index,
                               JSObject **objp, JSProperty **propp)
 {
     JSObject *tarray = getTypedArray(obj);
     JS_ASSERT(tarray);
@@ -1284,17 +1284,17 @@ class TypedArrayTemplate
         }
 
         return setElementTail(cx, tarray, index, vp, strict);
     }
 
     static JSBool
     obj_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
     {
-        return obj_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
+        return obj_setGeneric(cx, obj, NameToId(name), vp, strict);
     }
 
     static JSBool
     obj_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict)
     {
         RootedVarObject tarray(cx, getTypedArray(obj));
         JS_ASSERT(tarray);
 
@@ -1327,17 +1327,17 @@ class TypedArrayTemplate
         Value tmp = *v;
         return obj_setGeneric(cx, obj, id, &tmp, false);
     }
 
     static JSBool
     obj_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *v,
                        PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
-        return obj_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
+        return obj_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
     }
 
     static JSBool
     obj_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *v,
                        PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
         Value tmp = *v;
         return obj_setElement(cx, obj, index, &tmp, false);
@@ -1406,17 +1406,17 @@ class TypedArrayTemplate
           case JSENUMERATE_INIT:
             statep->setInt32(0);
             if (idp)
                 *idp = ::INT_TO_JSID(getLength(tarray));
             break;
 
           case JSENUMERATE_NEXT:
             if (statep->isTrue()) {
-                *idp = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+                *idp = NameToId(cx->runtime->atomState.lengthAtom);
                 statep->setInt32(0);
             } else {
                 uint32_t index = statep->toInt32();
                 if (index < getLength(tarray)) {
                     *idp = ::INT_TO_JSID(index);
                     statep->setInt32(index + 1);
                 } else {
                     JS_ASSERT(index == getLength(tarray));
@@ -3049,17 +3049,17 @@ static JSObject *
 InitArrayBufferClass(JSContext *cx, Handle<GlobalObject*> global)
 {
     RootedVarObject arrayBufferProto(cx, global->createBlankPrototype(cx, &ArrayBufferObject::protoClass));
     if (!arrayBufferProto)
         return NULL;
 
     RootedVarFunction ctor(cx);
     ctor = global->createConstructor(cx, ArrayBufferObject::class_constructor,
-                                     CLASS_ATOM(cx, ArrayBuffer), 1);
+                                     CLASS_NAME(cx, ArrayBuffer), 1);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, arrayBufferProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, arrayBufferProto, ArrayBufferObject::jsprops, ArrayBufferObject::jsfuncs))
         return NULL;
@@ -3136,17 +3136,17 @@ DataViewObject::initClass(JSContext *cx,
     DataViewObject &dvobj = proto->asDataView();
     dvobj.setFixedSlot(BYTEOFFSET_SLOT, Int32Value(0));
     dvobj.setFixedSlot(BYTELENGTH_SLOT, Int32Value(0));
     dvobj.setFixedSlot(BUFFER_SLOT, JSVAL_VOID);
     dvobj.setPrivate(NULL);
 
     JSFunction *ctor =
         global->createConstructor(cx, DataViewObject::class_constructor,
-                                  CLASS_ATOM(cx, DataView), 3);
+                                  CLASS_NAME(cx, DataView), 3);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, proto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, proto, DataViewObject::jsprops, DataViewObject::jsfuncs))
         return NULL;
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -81,17 +81,16 @@ WatchpointMap::init()
 {
     return map.init();
 }
 
 bool
 WatchpointMap::watch(JSContext *cx, HandleObject obj, HandleId id,
                      JSWatchPointHandler handler, HandleObject closure)
 {
-    JS_ASSERT(id.value() == js_CheckForStringIndex(id));
     JS_ASSERT(JSID_IS_STRING(id) || JSID_IS_INT(id));
 
     if (!obj->setWatched(cx))
         return false;
 
     Watchpoint w;
     w.handler = handler;
     w.closure = closure;
@@ -102,17 +101,16 @@ WatchpointMap::watch(JSContext *cx, Hand
     }
     return true;
 }
 
 void
 WatchpointMap::unwatch(JSObject *obj, jsid id,
                        JSWatchPointHandler *handlerp, JSObject **closurep)
 {
-    JS_ASSERT(id == js_CheckForStringIndex(id));
     if (Map::Ptr p = map.lookup(WatchKey(obj, id))) {
         if (handlerp)
             *handlerp = p->value.handler;
         if (closurep)
             *closurep = p->value.closure;
         map.remove(p);
     }
 }
@@ -131,17 +129,16 @@ void
 WatchpointMap::clear()
 {
     map.clear();
 }
 
 bool
 WatchpointMap::triggerWatchpoint(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
 {
-    JS_ASSERT(id.value() == js_CheckForStringIndex(id));
     Map::Ptr p = map.lookup(WatchKey(obj, id));
     if (!p || p->value.held)
         return true;
 
     AutoEntryHolder holder(cx, map, p);
 
     /* Copy the entry, since GC would invalidate p. */
     JSWatchPointHandler handler = p->value.handler;
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -395,17 +395,17 @@ js_InitWeakMapClass(JSContext *cx, JSObj
     RootedVar<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedVarObject weakMapProto(cx, global->createBlankPrototype(cx, &WeakMapClass));
     if (!weakMapProto)
         return NULL;
 
     RootedVarFunction ctor(cx);
     ctor = global->createConstructor(cx, WeakMap_construct,
-                                     CLASS_ATOM(cx, WeakMap), 0);
+                                     CLASS_NAME(cx, WeakMap), 0);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, weakMapProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, weakMapProto, NULL, weak_map_methods))
         return NULL;
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -709,17 +709,16 @@ Reify(JSContext *cx, JSCompartment *orig
     AutoIdVector keys(cx);
     if (length > 0) {
         if (!keys.reserve(length))
             return false;
         for (size_t i = 0; i < length; ++i) {
             jsid id;
             if (!ValueToId(cx, StringValue(ni->begin()[i]), &id))
                 return false;
-            id = js_CheckForStringIndex(id);
             keys.infallibleAppend(id);
             if (!origin->wrapId(cx, &keys[i]))
                 return false;
         }
     }
 
     close.clear();
     if (!CloseIterator(cx, iterObj))
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -2889,17 +2889,17 @@ GetLocalNameFromFunctionQName(JSObject *
 
 bool
 js_GetLocalNameFromFunctionQName(JSObject *obj, jsid *funidp, JSContext *cx)
 {
     if (!obj->isQName())
         return false;
     JSAtom *name;
     if (GetLocalNameFromFunctionQName(obj, &name, cx)) {
-        *funidp = ATOM_TO_JSID(name);
+        *funidp = AtomToId(name);
         return true;
     }
     return false;
 }
 
 static JSObject *
 ToXMLName(JSContext *cx, jsval v, jsid *funidp)
 {
@@ -2942,17 +2942,17 @@ ToXMLName(JSContext *cx, jsval v, jsid *
      * First, _P_ should be _s_, to refer to the given string.
      *
      * Second, why does ToXMLName applied to the string type throw TypeError
      * only for numeric literals without any leading or trailing whitespace?
      *
      * If the idea is to reject uint32_t property names, then the check needs to
      * be stricter, to exclude hexadecimal and floating point literals.
      */
-    if (js_IdIsIndex(ATOM_TO_JSID(atomizedName), &index))
+    if (js_IdIsIndex(AtomToId(atomizedName), &index))
         goto bad;
 
     if (*atomizedName->chars() == '@') {
         name = js_NewDependentString(cx, name, 1, name->length() - 1);
         if (!name)
             return NULL;
         *funidp = JSID_VOID;
         return ToAttributeName(cx, STRING_TO_JSVAL(name));
@@ -2962,17 +2962,17 @@ construct:
     v = STRING_TO_JSVAL(name);
     obj = JS_ConstructObjectWithArguments(cx, Jsvalify(&QNameClass), NULL, 1, &v);
     if (!obj)
         return NULL;
 
 out:
     JSAtom *localName;
     *funidp = GetLocalNameFromFunctionQName(obj, &localName, cx)
-              ? ATOM_TO_JSID(localName)
+              ? AtomToId(localName)
               : JSID_VOID;
     return obj;
 
 bad:
     JSAutoByteString bytes;
     if (js_ValueToPrintable(cx, StringValue(name), &bytes))
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_XML_NAME, bytes.ptr());
     return NULL;
@@ -4209,17 +4209,17 @@ PutProperty(JSContext *cx, JSObject *obj
             XMLARRAY_SET_MEMBER(&xml->xml_kids, i, vxml);
         }
 
         /* 2(h). */
         else {
             kidobj = js_GetXMLObject(cx, kid);
             if (!kidobj)
                 goto bad;
-            id = ATOM_TO_JSID(cx->runtime->atomState.starAtom);
+            id = NameToId(cx->runtime->atomState.starAtom);
             ok = PutProperty(cx, kidobj, id, strict, vp);
             if (!ok)
                 goto out;
         }
     } else {
         /*
          * ECMA-357 9.2.1.2/9.1.1.2 qname case.
          */
@@ -4783,17 +4783,17 @@ xml_lookupGeneric(JSContext *cx, JSObjec
     }
     return JS_TRUE;
 }
 
 static JSBool
 xml_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
                    JSProperty **propp)
 {
-    return xml_lookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return xml_lookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 static JSBool
 xml_lookupElement(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp,
                   JSProperty **propp)
 {
     JSXML *xml = reinterpret_cast<JSXML *>(obj->getPrivate());
     if (!HasIndexedProperty(xml, index)) {
@@ -4837,17 +4837,17 @@ xml_defineGeneric(JSContext *cx, JSObjec
     jsval tmp = *v;
     return PutProperty(cx, obj, id, false, &tmp);
 }
 
 static JSBool
 xml_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *v,
                    PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    return xml_defineGeneric(cx, obj, ATOM_TO_JSID(name), v, getter, setter, attrs);
+    return xml_defineGeneric(cx, obj, NameToId(name), v, getter, setter, attrs);
 }
 
 static JSBool
 xml_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *v,
                   PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
@@ -4871,17 +4871,17 @@ xml_getGeneric(JSContext *cx, JSObject *
     }
 
     return GetProperty(cx, obj, id, vp);
 }
 
 static JSBool
 xml_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
 {
-    return xml_getGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
+    return xml_getGeneric(cx, obj, receiver, NameToId(name), vp);
 }
 
 static JSBool
 xml_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -4898,17 +4898,17 @@ static JSBool
 xml_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     return PutProperty(cx, obj, id, strict, vp);
 }
 
 static JSBool
 xml_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict)
 {
-    return xml_setGeneric(cx, obj, ATOM_TO_JSID(name), vp, strict);
+    return xml_setGeneric(cx, obj, NameToId(name), vp, strict);
 }
 
 static JSBool
 xml_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -4930,17 +4930,17 @@ xml_getGenericAttributes(JSContext *cx, 
 
     *attrsp = found ? JSPROP_ENUMERATE : 0;
     return JS_TRUE;
 }
 
 static JSBool
 xml_getPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
 {
-    return xml_getGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return xml_getGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 static JSBool
 xml_getElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -4966,17 +4966,17 @@ xml_setGenericAttributes(JSContext *cx, 
         return false;
     }
     return true;
 }
 
 static JSBool
 xml_setPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp)
 {
-    return xml_setGenericAttributes(cx, obj, ATOM_TO_JSID(name), attrsp);
+    return xml_setGenericAttributes(cx, obj, NameToId(name), attrsp);
 }
 
 static JSBool
 xml_setElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -5030,17 +5030,17 @@ xml_deleteGeneric(JSContext *cx, JSObjec
 
     rval->setBoolean(true);
     return true;
 }
 
 static JSBool
 xml_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    return xml_deleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
+    return xml_deleteGeneric(cx, obj, NameToId(name), rval, strict);
 }
 
 static JSBool
 xml_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     JSXML *xml = reinterpret_cast<JSXML *>(obj->getPrivate());
     if (xml->xml_class != JSXML_CLASS_LIST) {
         /* See NOTE in spec: this variation is reserved for future use. */
@@ -5590,23 +5590,23 @@ xml_list_helper(JSContext *cx, JSXML *xm
 
 static JSBool
 ValueToId(JSContext *cx, jsval v, AutoIdRooter *idr)
 {
     if (JSVAL_IS_INT(v)) {
         int32_t i = JSVAL_TO_INT(v);
         if (INT_FITS_IN_JSID(i))
             *idr->addr() = INT_TO_JSID(i);
-        else if (!js_ValueToStringId(cx, v, idr->addr()))
+        else if (!ValueToId(cx, v, idr->addr()))
             return JS_FALSE;
     } else if (JSVAL_IS_STRING(v)) {
         JSAtom *atom = js_AtomizeString(cx, JSVAL_TO_STRING(v));
         if (!atom)
             return JS_FALSE;
-        *idr->addr() = ATOM_TO_JSID(atom);
+        *idr->addr() = AtomToId(atom);
     } else if (!JSVAL_IS_PRIMITIVE(v)) {
         *idr->addr() = OBJECT_TO_JSID(JSVAL_TO_OBJECT(v));
     } else {
         ReportBadXMLName(cx, v);
         return JS_FALSE;
     }
     return JS_TRUE;
 }
@@ -5722,17 +5722,17 @@ xml_childIndex(JSContext *cx, unsigned a
 
 /* XML and XMLList */
 static JSBool
 xml_children(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = ToObject(cx, &vp[1]);
     if (!obj)
         return false;
-    jsid name = ATOM_TO_JSID(cx->runtime->atomState.starAtom);
+    jsid name = NameToId(cx->runtime->atomState.starAtom);
     return GetProperty(cx, obj, name, vp);
 }
 
 /* XML and XMLList */
 static JSBool
 xml_comments_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval *vp)
 {
     JSXML *list, *kid, *vxml;
@@ -6677,17 +6677,17 @@ static JSBool
 xml_setChildren(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj;
 
     if (!StartNonListXMLMethod(cx, vp, &obj))
         return JS_FALSE;
 
     *vp = argc != 0 ? vp[2] : JSVAL_VOID;     /* local root */
-    if (!PutProperty(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.starAtom), false, vp))
+    if (!PutProperty(cx, obj, NameToId(cx->runtime->atomState.starAtom), false, vp))
         return JS_FALSE;
 
     *vp = OBJECT_TO_JSVAL(obj);
     return JS_TRUE;
 }
 
 static JSBool
 xml_setLocalName(JSContext *cx, unsigned argc, jsval *vp)
@@ -7401,17 +7401,17 @@ js_InitNamespaceClass(JSContext *cx, JSO
     JSObject *namespaceProto = global->createBlankPrototype(cx, &NamespaceClass);
     if (!namespaceProto)
         return NULL;
     JSFlatString *empty = cx->runtime->emptyString;
     namespaceProto->setNamePrefix(empty);
     namespaceProto->setNameURI(empty);
 
     const unsigned NAMESPACE_CTOR_LENGTH = 2;
-    JSFunction *ctor = global->createConstructor(cx, Namespace, CLASS_ATOM(cx, Namespace),
+    JSFunction *ctor = global->createConstructor(cx, Namespace, CLASS_NAME(cx, Namespace),
                                                  NAMESPACE_CTOR_LENGTH);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, namespaceProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, namespaceProto, namespace_props, namespace_methods))
@@ -7434,17 +7434,17 @@ js_InitQNameClass(JSContext *cx, JSObjec
     JSObject *qnameProto = global->createBlankPrototype(cx, &QNameClass);
     if (!qnameProto)
         return NULL;
     JSAtom *empty = cx->runtime->emptyString;
     if (!InitXMLQName(cx, qnameProto, empty, empty, empty))
         return NULL;
 
     const unsigned QNAME_CTOR_LENGTH = 2;
-    JSFunction *ctor = global->createConstructor(cx, QName, CLASS_ATOM(cx, QName),
+    JSFunction *ctor = global->createConstructor(cx, QName, CLASS_NAME(cx, QName),
                                                  QNAME_CTOR_LENGTH);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, qnameProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, qnameProto, NULL, qname_methods))
@@ -7475,17 +7475,17 @@ js_InitXMLClass(JSContext *cx, JSObject 
 
     /* Don't count this as a real content-created XML object. */
     if (!cx->runningWithTrustedPrincipals()) {
         JS_ASSERT(sE4XObjectsCreated > 0);
         --sE4XObjectsCreated;
     }
 
     const unsigned XML_CTOR_LENGTH = 1;
-    JSFunction *ctor = global->createConstructor(cx, XML, CLASS_ATOM(cx, XML), XML_CTOR_LENGTH);
+    JSFunction *ctor = global->createConstructor(cx, XML, CLASS_NAME(cx, XML), XML_CTOR_LENGTH);
     if (!ctor)
         return NULL;
 
     if (!LinkConstructorAndPrototype(cx, ctor, xmlProto))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, xmlProto, NULL, xml_methods) ||
         !DefinePropertiesAndBrand(cx, ctor, xml_static_props, xml_static_methods))
@@ -7742,17 +7742,17 @@ js_FindXMLProperty(JSContext *cx, const 
         JS_ASSERT(nameobj->getClass() == &AttributeNameClass ||
                   nameobj->getClass() == &QNameClass);
     }
 
     qn = nameobj;
 
     JSAtom *name;
     funid = GetLocalNameFromFunctionQName(qn, &name, cx)
-            ? ATOM_TO_JSID(name)
+            ? AtomToId(name)
             : JSID_VOID;
 
     obj = cx->stack.currentScriptedScopeChain();
     do {
         /* Skip any With object that can wrap XML. */
         target = obj;
         while (target->getClass() == &WithClass) {
              proto = target->getProto();
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -4835,17 +4835,17 @@ mjit::Compiler::jsop_getprop(PropertyNam
         }
     }
 
     /* If the access will definitely be fetching a particular value, nop it. */
     bool testObject;
     JSObject *singleton =
         (*PC == JSOP_GETPROP || *PC == JSOP_CALLPROP) ? pushedSingleton(0) : NULL;
     if (singleton && singleton->isFunction() && !hasTypeBarriers(PC) &&
-        testSingletonPropertyTypes(top, ATOM_TO_JSID(name), &testObject)) {
+        testSingletonPropertyTypes(top, NameToId(name), &testObject)) {
         if (testObject) {
             Jump notObject = frame.testObject(Assembler::NotEqual, top);
             stubcc.linkExit(notObject, Uses(1));
             stubcc.leave();
             stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
             OOL_STUBCALL(stubs::GetProp, REJOIN_FALLTHROUGH);
             testPushedType(REJOIN_FALLTHROUGH, -1);
         }
@@ -4860,17 +4860,17 @@ mjit::Compiler::jsop_getprop(PropertyNam
             stubcc.rejoin(Changes(1));
 
         return true;
     }
 
     /* Check if this is a property access we can make a loop invariant entry for. */
     if (loop && loop->generatingInvariants() && !hasTypeBarriers(PC)) {
         CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
-        if (FrameEntry *fe = loop->invariantProperty(topv, ATOM_TO_JSID(name))) {
+        if (FrameEntry *fe = loop->invariantProperty(topv, NameToId(name))) {
             if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
                 frame.learnType(fe, knownType, false);
             frame.pop();
             frame.pushCopyOf(fe);
             if (script->hasScriptCounts)
                 bumpPropCount(PC, PCCounts::PROP_STATIC);
             return true;
         }
@@ -4884,17 +4884,17 @@ mjit::Compiler::jsop_getprop(PropertyNam
 
     frame.forgetMismatchedObject(top);
 
     /*
      * Check if we are accessing a known type which always has the property
      * in a particular inline slot. Get the property directly in this case,
      * without using an IC.
      */
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     types::TypeSet *types = frame.extra(top).types;
     if (types && !types->unknownObject() &&
         types->getObjectCount() == 1 &&
         types->getTypeObject(0) != NULL &&
         !types->getTypeObject(0)->unknownProperties() &&
         id == types::MakeTypeId(cx, id)) {
         JS_ASSERT(!forPrototype);
         types::TypeObject *object = types->getTypeObject(0);
@@ -5165,17 +5165,17 @@ mjit::Compiler::jsop_getprop_dispatch(Pr
      * push is a singleton, and the pushed value is determined by the type of
      * the object being accessed. Return true if the CALLPROP has been fully
      * processed, false if no code was generated.
      */
     FrameEntry *top = frame.peek(-1);
     if (top->isNotType(JSVAL_TYPE_OBJECT))
         return false;
 
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     if (id != types::MakeTypeId(cx, id))
         return false;
 
     types::TypeSet *pushedTypes = pushedTypeSet(0);
     if (pushedTypes->unknownObject() || pushedTypes->baseFlags() != 0)
         return false;
 
     /* Check every pushed value is a singleton. */
@@ -5319,17 +5319,17 @@ mjit::Compiler::jsop_setprop(PropertyNam
     }
 
     /*
      * If this is a SETNAME to a variable of a non-reentrant outer function,
      * set the variable's slot directly for the active call object.
      */
     if (cx->typeInferenceEnabled() && js_CodeSpec[*PC].format & JOF_NAME) {
         ScriptAnalysis::NameAccess access =
-            analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
+            analysis->resolveNameAccess(cx, NameToId(name), true);
         if (access.nesting) {
             /* Use a SavedReg so it isn't clobbered by the stub call. */
             RegisterID nameReg = frame.allocReg(Registers::SavedRegs).reg();
             Address address = frame.loadNameAddress(access, nameReg);
 
 #ifdef JSGC_INCREMENTAL_MJ
             /* Write barrier. */
             if (cx->compartment->needsBarrier()) {
@@ -5353,17 +5353,17 @@ mjit::Compiler::jsop_setprop(PropertyNam
             return true;
         }
     }
 
     /*
      * Set the property directly if we are accessing a known object which
      * always has the property in a particular inline slot.
      */
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     types::TypeSet *types = frame.extra(lhs).types;
     if (JSOp(*PC) == JSOP_SETPROP && id == types::MakeTypeId(cx, id) &&
         types && !types->unknownObject() &&
         types->getObjectCount() == 1 &&
         types->getTypeObject(0) != NULL &&
         !types->getTypeObject(0)->unknownProperties()) {
         types::TypeObject *object = types->getTypeObject(0);
         types::TypeSet *propertyTypes = object->getProperty(cx, id, false);
@@ -5542,17 +5542,17 @@ mjit::Compiler::jsop_name(PropertyName *
 {
     /*
      * If this is a NAME for a variable of a non-reentrant outer function, get
      * the variable's slot directly for the active call object. We always need
      * to check for undefined, however.
      */
     if (cx->typeInferenceEnabled()) {
         ScriptAnalysis::NameAccess access =
-            analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
+            analysis->resolveNameAccess(cx, NameToId(name), true);
         if (access.nesting) {
             Address address = frame.loadNameAddress(access);
             JSValueType type = knownPushedType(0);
             BarrierState barrier = pushAddressMaybeBarrier(address, type, true,
                                                            /* testUndefined = */ true);
             finishBarrier(barrier, REJOIN_GETTER, 0);
             return;
         }
@@ -5615,17 +5615,17 @@ bool
 mjit::Compiler::jsop_xname(PropertyName *name)
 {
     /*
      * If this is a GETXPROP for a variable of a non-reentrant outer function,
      * treat in the same way as a NAME.
      */
     if (cx->typeInferenceEnabled()) {
         ScriptAnalysis::NameAccess access =
-            analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
+            analysis->resolveNameAccess(cx, NameToId(name), true);
         if (access.nesting) {
             frame.pop();
             Address address = frame.loadNameAddress(access);
             JSValueType type = knownPushedType(0);
             BarrierState barrier = pushAddressMaybeBarrier(address, type, true,
                                                            /* testUndefined = */ true);
             finishBarrier(barrier, REJOIN_GETTER, 0);
             return true;
@@ -5695,17 +5695,17 @@ void
 mjit::Compiler::jsop_bindname(PropertyName *name)
 {
     /*
      * If this is a BINDNAME for a variable of a non-reentrant outer function,
      * the object is definitely the outer function's active call object.
      */
     if (cx->typeInferenceEnabled()) {
         ScriptAnalysis::NameAccess access =
-            analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
+            analysis->resolveNameAccess(cx, NameToId(name), true);
         if (access.nesting) {
             RegisterID reg = frame.allocReg();
             JSObject **pobj = &access.nesting->activeCall;
             masm.move(ImmPtr(pobj), reg);
             masm.loadPtr(Address(reg), reg);
             frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
             return;
         }
@@ -6170,35 +6170,35 @@ mjit::Compiler::jsop_getgname(uint32_t i
     }
     if (name == cx->runtime->atomState.InfinityAtom) {
         frame.push(cx->runtime->positiveInfinityValue);
         return;
     }
 
     /* Optimize singletons like Math for JSOP_CALLPROP. */
     JSObject *obj = pushedSingleton(0);
-    if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, ATOM_TO_JSID(name))) {
+    if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, NameToId(name))) {
         frame.push(ObjectValue(*obj));
         return;
     }
 
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     JSValueType type = knownPushedType(0);
     if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
         !globalObj->getType(cx)->unknownProperties()) {
         types::TypeSet *propertyTypes = globalObj->getType(cx)->getProperty(cx, id, false);
         if (!propertyTypes)
             return;
 
         /*
          * If we are accessing a defined global which is a normal data property
          * then bake its address into the jitcode and guard against future
          * reallocation of the global object's slots.
          */
-        const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
+        const js::Shape *shape = globalObj->nativeLookup(cx, NameToId(name));
         if (shape && shape->hasDefaultGetter() && shape->hasSlot()) {
             HeapSlot *value = &globalObj->getSlotRef(shape->slot());
             if (!value->isUndefined() &&
                 !propertyTypes->isOwnProperty(cx, globalObj->getType(cx), true)) {
                 watchGlobalReallocation();
                 RegisterID reg = frame.allocReg();
                 masm.move(ImmPtr(value), reg);
 
@@ -6299,29 +6299,29 @@ void
 mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
 {
     if (monitored(PC)) {
         /* Global accesses are monitored only for a few names like __proto__. */
         jsop_setgname_slow(name);
         return;
     }
 
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
         !globalObj->getType(cx)->unknownProperties()) {
         /*
          * Note: object branding is disabled when inference is enabled. With
          * branding there is no way to ensure that a non-function property
          * can't get a function later and cause the global object to become
          * branded, requiring a shape change if it changes again.
          */
         types::TypeSet *types = globalObj->getType(cx)->getProperty(cx, id, false);
         if (!types)
             return;
-        const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
+        const js::Shape *shape = globalObj->nativeLookup(cx, NameToId(name));
         if (shape && shape->hasDefaultSetter() &&
             shape->writable() && shape->hasSlot() &&
             !types->isOwnProperty(cx, globalObj->getType(cx), true)) {
             watchGlobalReallocation();
             HeapSlot *value = &globalObj->getSlotRef(shape->slot());
             RegisterID reg = frame.allocReg();
 #ifdef JSGC_INCREMENTAL_MJ
             /* Write barrier. */
@@ -7035,17 +7035,17 @@ mjit::Compiler::constructThis()
     do {
         if (!cx->typeInferenceEnabled() ||
             !fun->hasSingletonType() ||
             fun->getType(cx)->unknownProperties())
         {
             break;
         }
 
-        jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+        jsid id = NameToId(cx->runtime->atomState.classPrototypeAtom);
         types::TypeSet *protoTypes = fun->getType(cx)->getProperty(cx, id, false);
 
         JSObject *proto = protoTypes->getSingleton(cx, true);
         if (!proto)
             break;
 
         /*
          * Generate an inline path to create a 'this' object with the given
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -2659,33 +2659,33 @@ mjit::Compiler::jsop_pos()
     stubcc.rejoin(Changes(1));
 }
 
 void
 mjit::Compiler::jsop_initprop()
 {
     FrameEntry *obj = frame.peek(-2);
     FrameEntry *fe = frame.peek(-1);
-    JSAtom *atom = script->getAtom(GET_UINT32_INDEX(PC));
+    PropertyName *name = script->getName(GET_UINT32_INDEX(PC));
 
     JSObject *baseobj = frame.extra(obj).initObject;
 
     if (!baseobj || monitored(PC)) {
         prepareStubCall(Uses(2));
-        masm.move(ImmPtr(atom), Registers::ArgReg1);
+        masm.move(ImmPtr(name), Registers::ArgReg1);
         INLINE_STUBCALL(stubs::InitProp, REJOIN_FALLTHROUGH);
         return;
     }
 
     JSObject *holder;
     JSProperty *prop = NULL;
 #ifdef DEBUG
     bool res =
 #endif
-    LookupPropertyWithFlags(cx, baseobj, ATOM_TO_JSID(atom),
+    LookupPropertyWithFlags(cx, baseobj, NameToId(name),
                             JSRESOLVE_QUALIFIED, &holder, &prop);
     JS_ASSERT(res && prop && holder == baseobj);
 
     RegisterID objReg = frame.copyDataIntoReg(obj);
 
     /* Perform the store. */
     Shape *shape = (Shape *) prop;
     Address address = masm.objPropAddress(baseobj, objReg, shape->slot());
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -912,17 +912,17 @@ LoopState::invariantLength(const CrossSS
 }
 
 FrameEntry *
 LoopState::invariantProperty(const CrossSSAValue &obj, jsid id)
 {
     if (skipAnalysis)
         return NULL;
 
-    if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))
+    if (id == NameToId(cx->runtime->atomState.lengthAtom))
         return NULL;
 
     uint32_t objSlot;
     int32_t objConstant;
     if (!getEntryValue(obj, &objSlot, &objConstant) || objSlot == UNASSIGNED || objConstant != 0)
         return NULL;
 
     for (unsigned i = 0; i < invariantEntries.length(); i++) {
@@ -1865,18 +1865,18 @@ LoopState::analyzeLoopBody(unsigned fram
             SSAValue elemValue = analysis->poppedValue(pc, 0);
 
             if (constrainedLoop && !definiteArrayAccess(objValue, elemValue))
                 constrainedLoop = false;
             break;
           }
 
           case JSOP_SETPROP: {
-            JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
-            jsid id = MakeTypeId(cx, ATOM_TO_JSID(atom));
+            PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
+            jsid id = MakeTypeId(cx, NameToId(name));
 
             TypeSet *objTypes = analysis->poppedTypes(pc, 1);
             if (objTypes->unknownObject()) {
                 unknownModset = true;
                 break;
             }
 
             objTypes->addFreeze(cx);
@@ -2179,18 +2179,18 @@ LoopState::getEntryValue(const CrossSSAV
         if (!tmp)
             return false;
         *pslot = frame.outerSlot(tmp);
         *pconstant = 0;
         return true;
       }
 
       case JSOP_GETPROP: {
-        JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
-        jsid id = ATOM_TO_JSID(atom);
+        PropertyName *name = script->getName(GET_UINT32_INDEX(pc));
+        jsid id = NameToId(name);
         CrossSSAValue objcv(cv.frame, analysis->poppedValue(v.pushedOffset(), 0));
         FrameEntry *tmp = invariantProperty(objcv, id);
         if (!tmp)
             return false;
         *pslot = frame.outerSlot(tmp);
         *pconstant = 0;
         return true;
       }
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -86,17 +86,17 @@ PatchGetFallback(VMFrame &f, ic::GetGlob
 void JS_FASTCALL
 ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
 {
     JSObject &obj = f.fp()->global();
     PropertyName *name = f.script()->getName(GET_UINT32_INDEX(f.pc()));
 
     RecompilationMonitor monitor(f.cx);
 
-    const Shape *shape = obj.nativeLookup(f.cx, js_CheckForStringIndex(ATOM_TO_JSID(name)));
+    const Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
 
     if (monitor.recompiled()) {
         stubs::Name(f);
         return;
     }
 
     if (!shape ||
         !shape->hasDefaultGetter() ||
@@ -191,17 +191,17 @@ void JS_FASTCALL
 ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
 {
     JSObject &obj = f.fp()->global();
     JSScript *script = f.script();
     PropertyName *name = script->getName(GET_UINT32_INDEX(f.pc()));
 
     RecompilationMonitor monitor(f.cx);
 
-    const Shape *shape = obj.nativeLookup(f.cx, ATOM_TO_JSID(name));
+    const Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
 
     if (!monitor.recompiled()) {
         LookupStatus status = UpdateSetGlobalName(f, ic, &obj, shape);
         if (status == Lookup_Error)
             THROW();
     }
 
     STRICT_VARIANT(stubs::SetGlobalName)(f, name);
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -465,17 +465,17 @@ class SetPropCompiler : public PICStubCo
         return Lookup_Cacheable;
     }
 
     bool updateMonitoredTypes()
     {
         JS_ASSERT(pic.typeMonitored);
 
         RecompilationMonitor monitor(cx);
-        jsid id = ATOM_TO_JSID(name);
+        jsid id = NameToId(name);
 
         if (!obj->getType(cx)->unknownProperties()) {
             types::AutoEnterTypeInference enter(cx);
             types::TypeSet *types = obj->getType(cx)->getProperty(cx, types::MakeTypeId(cx, id), true);
             if (!types)
                 return false;
             pic.rhsTypes->addSubset(cx, types);
         }
@@ -1048,17 +1048,17 @@ class GetPropCompiler : public PICStubCo
         repatcher.repatch(labels.getInlineShapeData(pic.getFastShapeGuard()), obj->lastProperty());
         repatcher.patchAddressOffsetForValueLoad(labels.getValueLoad(pic.fastPathRejoin), offset);
 
         pic.inlinePathPatched = true;
 
         return Lookup_Cacheable;
     }
 
-    void generateGetterStub(Assembler &masm, const Shape *shape,
+    void generateGetterStub(Assembler &masm, const Shape *shape, jsid userid,
                             Label start, Vector<Jump, 8> &shapeMismatches)
     {
         /*
          * Getter hook needs to be called from the stub. The state is fully
          * synced and no registers are live except the result registers.
          */
         JS_ASSERT(pic.canCallHook);
         PropertyOp getter = shape->getterOp();
@@ -1110,17 +1110,17 @@ class GetPropCompiler : public PICStubCo
 
         /* Grap vp. */
         RegisterID vpReg = t0;
         masm.addPtr(Imm32(vpOffset), JSFrameReg, vpReg);
 
         masm.restoreStackBase();
         masm.setupABICall(Registers::NormalCall, 4);
         masm.storeArg(3, vpReg);
-        masm.storeArg(2, ImmPtr((void *) JSID_BITS(shape->getUserId())));
+        masm.storeArg(2, ImmPtr((void *) JSID_BITS(userid)));
         masm.storeArg(1, holdObjReg);
         masm.storeArg(0, cxReg);
 
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, getter), false);
 
         NativeStubLinker::FinalJump done;
         if (!NativeStubEpilogue(f, masm, &done, 0, vpOffset, pic.shapeReg, pic.objReg))
             return;
@@ -1196,17 +1196,21 @@ class GetPropCompiler : public PICStubCo
                 return error();
 
             pic.secondShapeGuard = masm.distanceOf(masm.label()) - masm.distanceOf(start);
         } else {
             pic.secondShapeGuard = 0;
         }
 
         if (!shape->hasDefaultGetter()) {
-            generateGetterStub(masm, shape, start, shapeMismatches);
+            jsid userid;
+            if (!shape->getUserId(cx, &userid))
+                return error();
+
+            generateGetterStub(masm, shape, userid, start, shapeMismatches);
             if (setStubShapeOffset)
                 pic.getPropLabels().setStubShapeJump(masm, start, stubShapeJumpLabel);
             return Lookup_Cacheable;
         }
 
         /* Load the value out of the object. */
         masm.loadObjProp(holder, holderReg, shape, pic.shapeReg, pic.objReg);
         Jump done = masm.jump();
@@ -2433,17 +2437,17 @@ ic::GetElement(VMFrame &f, ic::GetElemen
         return;
     }
 #endif
 
     jsid id;
     if (idval.isInt32() && INT_FITS_IN_JSID(idval.toInt32())) {
         id = INT_TO_JSID(idval.toInt32());
     } else {
-        if (!js_InternNonIntElementId(cx, obj, idval, &id))
+        if (!InternNonIntElementId(cx, obj, idval, &id))
             THROW();
     }
 
     if (!monitor.recompiled() && ic->shouldUpdate(cx)) {
 #ifdef DEBUG
         f.regs.sp[-2] = MagicValue(JS_GENERIC_MAGIC);
 #endif
         LookupStatus status = ic->update(f, obj, idval, id, &f.regs.sp[-2]);
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1082,17 +1082,17 @@ InitPropOrMethod(VMFrame &f, PropertyNam
     Value rval;
     rval = regs.sp[-1];
 
     /* Load the object being initialized into lval/obj. */
     RootedVarObject obj(cx, &regs.sp[-2].toObject());
     JS_ASSERT(obj->isNative());
 
     /* Get the immediate property name into id. */
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
 
     if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
         ? !js_SetPropertyHelper(cx, obj, id, 0, &rval, false)
         : !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
                                 JSPROP_ENUMERATE, 0, 0, 0)) {
         THROW();
     }
 }
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -318,32 +318,31 @@ NormalArgumentsObject::optimizedGetElem(
         }
     }
 
     /* Slow path: create and canonicalize an id, then emulate args_resolve. */
 
     jsid id;
     if (!ValueToId(cx, elem, &id))
         return false;
-    id = js_CheckForStringIndex(id);
 
     if (JSID_IS_INT(id)) {
         int32_t i = JSID_TO_INT(id);
         if (i >= 0 && uint32_t(i) < fp->numActualArgs()) {
             *vp = fp->canonicalActualArg(i);
             return true;
         }
     }
 
-    if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
+    if (id == NameToId(cx->runtime->atomState.lengthAtom)) {
         *vp = Int32Value(fp->numActualArgs());
         return true;
     }
 
-    if (id == ATOM_TO_JSID(cx->runtime->atomState.calleeAtom)) {
+    if (id == NameToId(cx->runtime->atomState.calleeAtom)) {
         *vp = ObjectValue(fp->callee());
         return true;
     }
 
     JSObject *proto = fp->global().getOrCreateObjectPrototype(cx);
     if (!proto)
         return false;
 
@@ -357,19 +356,19 @@ args_enumerate(JSContext *cx, JSObject *
 
     /*
      * Trigger reflection in args_resolve using a series of js_LookupProperty
      * calls.
      */
     int argc = int(argsobj->initialLength());
     for (int i = -2; i != argc; i++) {
         jsid id = (i == -2)
-                  ? ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)
+                  ? NameToId(cx->runtime->atomState.lengthAtom)
                   : (i == -1)
-                  ? ATOM_TO_JSID(cx->runtime->atomState.calleeAtom)
+                  ? NameToId(cx->runtime->atomState.calleeAtom)
                   : INT_TO_JSID(i);
 
         JSObject *pobj;
         JSProperty *prop;
         if (!js_LookupProperty(cx, argsobj, id, &pobj, &prop))
             return false;
     }
     return true;
@@ -476,25 +475,25 @@ strictargs_enumerate(JSContext *cx, JSOb
     /*
      * Trigger reflection in strictargs_resolve using a series of
      * js_LookupProperty calls.
      */
     JSObject *pobj;
     JSProperty *prop;
 
     // length
-    if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), &pobj, &prop))
+    if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.lengthAtom), &pobj, &prop))
         return false;
 
     // callee
-    if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.calleeAtom), &pobj, &prop))
+    if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.calleeAtom), &pobj, &prop))
         return false;
 
     // caller
-    if (!js_LookupProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.callerAtom), &pobj, &prop))
+    if (!js_LookupProperty(cx, argsobj, NameToId(cx->runtime->atomState.callerAtom), &pobj, &prop))
         return false;
 
     for (uint32_t i = 0, argc = argsobj->initialLength(); i < argc; i++) {
         if (!js_LookupProperty(cx, argsobj, INT_TO_JSID(i), &pobj, &prop))
             return false;
     }
 
     return true;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -786,21 +786,21 @@ Debugger::newCompletionValue(JSContext *
      */
     assertSameCompartment(cx, object.get());
 
     RootedVarId key(cx);
     RootValue valueRoot(cx, &value);
 
     switch (status) {
       case JSTRAP_RETURN:
-        key = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
+        key = NameToId(cx->runtime->atomState.returnAtom);
         break;
 
       case JSTRAP_THROW:
-        key = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
+        key = NameToId(cx->runtime->atomState.throwAtom);
         break;
 
       case JSTRAP_ERROR:
         result->setNull();
         return true;
 
       default:
         JS_NOT_REACHED("bad status passed to Debugger::newCompletionValue");
@@ -847,18 +847,18 @@ Debugger::parseResumptionValue(AutoCompa
         ac.leave();
         return JSTRAP_ERROR;
     }
 
     /* Check that rv is {return: val} or {throw: val}. */
     JSContext *cx = ac.context;
     JSObject *obj;
     const Shape *shape;
-    jsid returnId = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
-    jsid throwId = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
+    jsid returnId = NameToId(cx->runtime->atomState.returnAtom);
+    jsid throwId = NameToId(cx->runtime->atomState.throwAtom);
     bool okResumption = rv.isObject();
     if (okResumption) {
         obj = &rv.toObject();
         okResumption = obj->isObject();
     }
     if (okResumption) {
         shape = obj->lastProperty();
         okResumption = shape->previous() &&
@@ -885,17 +885,17 @@ Debugger::parseResumptionValue(AutoCompa
 bool
 CallMethodIfPresent(JSContext *cx, HandleObject obj, const char *name, int argc, Value *argv,
                     Value *rval)
 {
     rval->setUndefined();
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     Value fval;
     return atom &&
-           js_GetMethod(cx, obj, ATOM_TO_JSID(atom), 0, &fval) &&
+           js_GetMethod(cx, obj, AtomToId(atom), 0, &fval) &&
            (!js_IsCallable(fval) ||
             Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
 }
 
 JSTrapStatus
 Debugger::fireDebuggerStatement(JSContext *cx, Value *vp)
 {
     RootedVarObject hook(cx, getHook(OnDebuggerStatement));
@@ -3207,17 +3207,17 @@ DebuggerFrame_getArguments(JSContext *cx
             return false;
         argsobj = NewObjectWithGivenProto(cx, &DebuggerArguments_class, proto, global);
         if (!argsobj)
             return false;
         SetReservedSlot(argsobj, JSSLOT_DEBUGARGUMENTS_FRAME, ObjectValue(*thisobj));
 
         JS_ASSERT(fp->numActualArgs() <= 0x7fffffff);
         int32_t fargc = int32_t(fp->numActualArgs());
-        if (!DefineNativeProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
+        if (!DefineNativeProperty(cx, argsobj, NameToId(cx->runtime->atomState.lengthAtom),
                                   Int32Value(fargc), NULL, NULL,
                                   JSPROP_PERMANENT | JSPROP_READONLY, 0, 0))
         {
             return false;
         }
 
         for (int32_t i = 0; i < fargc; i++) {
             RootedVarFunction getobj(cx);
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -169,17 +169,17 @@ GlobalObject::initFunctionAndObjectClass
 
     /* Create the Object function now that we have a [[Prototype]] for it. */
     RootedVarFunction objectCtor(cx);
     {
         JSObject *ctor = NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self);
         if (!ctor)
             return NULL;
         objectCtor = js_NewFunction(cx, ctor, js_Object, 1, JSFUN_CONSTRUCTOR, self,
-                                    CLASS_ATOM(cx, Object));
+                                    CLASS_NAME(cx, Object));
         if (!objectCtor)
             return NULL;
     }
 
     /*
      * Install |Object| and |Object.prototype| for the benefit of subsequent
      * code that looks for them.
      */
@@ -188,17 +188,17 @@ GlobalObject::initFunctionAndObjectClass
     /* Create |Function| so it and |Function.prototype| can be installed. */
     RootedVarFunction functionCtor(cx);
     {
         JSObject *ctor =
             NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self);
         if (!ctor)
             return NULL;
         functionCtor = js_NewFunction(cx, ctor, Function, 1, JSFUN_CONSTRUCTOR, self,
-                                      CLASS_ATOM(cx, Function));
+                                      CLASS_NAME(cx, Function));
         if (!functionCtor)
             return NULL;
         JS_ASSERT(ctor == functionCtor);
     }
 
     /*
      * Install |Function| and |Function.prototype| so that we can freely create
      * functions and objects without special effort.
@@ -215,27 +215,27 @@ GlobalObject::initFunctionAndObjectClass
         !LinkConstructorAndPrototype(cx, functionCtor, functionProto) ||
         !DefinePropertiesAndBrand(cx, functionProto, NULL, function_methods) ||
         !DefinePropertiesAndBrand(cx, functionCtor, NULL, NULL))
     {
         return NULL;
     }
 
     /* Add the global Function and Object properties now. */
-    jsid objectId = ATOM_TO_JSID(CLASS_ATOM(cx, Object));
+    jsid objectId = NameToId(CLASS_NAME(cx, Object));
     if (!self->addDataProperty(cx, objectId, JSProto_Object + JSProto_LIMIT * 2, 0))
         return NULL;
-    jsid functionId = ATOM_TO_JSID(CLASS_ATOM(cx, Function));
+    jsid functionId = NameToId(CLASS_NAME(cx, Function));
     if (!self->addDataProperty(cx, functionId, JSProto_Function + JSProto_LIMIT * 2, 0))
         return NULL;
 
     /* Heavy lifting done, but lingering tasks remain. */
 
     /* ES5 15.1.2.1. */
-    jsid id = ATOM_TO_JSID(cx->runtime->atomState.evalAtom);
+    jsid id = NameToId(cx->runtime->atomState.evalAtom);
     JSObject *evalobj = js_DefineFunction(cx, self, id, eval, 1, JSFUN_STUB_GSOPS);
     if (!evalobj)
         return NULL;
     self->setOriginalEval(evalobj);
 
     /* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */
     RootedVarFunction throwTypeError(cx);
     throwTypeError = js_NewFunction(cx, NULL, ThrowTypeError, 0, 0, self, NULL);
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -358,36 +358,36 @@ RegExpObject::assignInitialShape(JSConte
     JS_STATIC_ASSERT(GLOBAL_FLAG_SLOT == SOURCE_SLOT + 1);
     JS_STATIC_ASSERT(IGNORE_CASE_FLAG_SLOT == GLOBAL_FLAG_SLOT + 1);
     JS_STATIC_ASSERT(MULTILINE_FLAG_SLOT == IGNORE_CASE_FLAG_SLOT + 1);
     JS_STATIC_ASSERT(STICKY_FLAG_SLOT == MULTILINE_FLAG_SLOT + 1);
 
     RootedVarObject self(cx, this);
 
     /* The lastIndex property alone is writable but non-configurable. */
-    if (!addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom),
+    if (!addDataProperty(cx, NameToId(cx->runtime->atomState.lastIndexAtom),
                          LAST_INDEX_SLOT, JSPROP_PERMANENT))
     {
         return NULL;
     }
 
     /* Remaining instance properties are non-writable and non-configurable. */
-    if (!self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
+    if (!self->addDataProperty(cx, NameToId(cx->runtime->atomState.sourceAtom),
                                SOURCE_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
-        !self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.globalAtom),
+        !self->addDataProperty(cx, NameToId(cx->runtime->atomState.globalAtom),
                                GLOBAL_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
-        !self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.ignoreCaseAtom),
+        !self->addDataProperty(cx, NameToId(cx->runtime->atomState.ignoreCaseAtom),
                                IGNORE_CASE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY) ||
-        !self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.multilineAtom),
+        !self->addDataProperty(cx, NameToId(cx->runtime->atomState.multilineAtom),
                                MULTILINE_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY))
     {
         return NULL;
     }
 
-    return self->addDataProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.stickyAtom),
+    return self->addDataProperty(cx, NameToId(cx->runtime->atomState.stickyAtom),
                                  STICKY_FLAG_SLOT, JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 inline bool
 RegExpObject::init(JSContext *cx, HandleAtom source, RegExpFlag flags)
 {
     RootedVar<RegExpObject *> self(cx, this);
 
@@ -400,27 +400,27 @@ RegExpObject::init(JSContext *cx, Handle
             if (!shape)
                 return false;
             EmptyShape::insertInitialShape(cx, shape, self->getProto());
         }
         JS_ASSERT(!self->nativeEmpty());
     }
 
     DebugOnly<JSAtomState *> atomState = &cx->runtime->atomState;
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->lastIndexAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->lastIndexAtom))->slot() ==
               LAST_INDEX_SLOT);
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->sourceAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->sourceAtom))->slot() ==
               SOURCE_SLOT);
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->globalAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->globalAtom))->slot() ==
               GLOBAL_FLAG_SLOT);
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->ignoreCaseAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->ignoreCaseAtom))->slot() ==
               IGNORE_CASE_FLAG_SLOT);
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->multilineAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->multilineAtom))->slot() ==
               MULTILINE_FLAG_SLOT);
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(atomState->stickyAtom))->slot() ==
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(atomState->stickyAtom))->slot() ==
               STICKY_FLAG_SLOT);
 
     /*
      * If this is a re-initialization with an existing RegExpShared, 'flags'
      * may not match getShared()->flags, so forget the RegExpShared.
      */
     self->JSObject::setPrivate(NULL);
 
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -226,17 +226,17 @@ CallObject::createForFunction(JSContext 
      * object holding function's name.
      */
     RootedVarAtom lambdaName(cx, CallObjectLambdaName(fp->fun()));
     if (lambdaName) {
         scopeChain = DeclEnvObject::create(cx, fp);
         if (!scopeChain)
             return NULL;
 
-        if (!DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
+        if (!DefineNativeProperty(cx, scopeChain, AtomToId(lambdaName),
                                   ObjectValue(fp->callee()), NULL, NULL,
                                   JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) {
             return NULL;
         }
     }
 
     CallObject *callobj = create(cx, fp->script(), scopeChain, RootedVarObject(cx, &fp->callee()));
     if (!callobj)
@@ -345,17 +345,17 @@ CallObject::setVarOp(JSContext *cx, JSOb
 
     TypeScript::SetLocal(cx, script, i, *vp);
     return true;
 }
 
 bool
 CallObject::containsVarOrArg(PropertyName *name, Value *vp, JSContext *cx)
 {
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     const Shape *shape = nativeLookup(cx, id);
     if (!shape)
         return false;
 
     PropertyOp op = shape->getterOp();
     if (op != getVarOp && op != getArgOp)
         return false;
 
@@ -478,17 +478,17 @@ with_LookupGeneric(JSContext *cx, JSObje
     flags |= JSRESOLVE_WITH;
     JSAutoResolveFlags rf(cx, flags);
     return obj->asWith().object().lookupGeneric(cx, id, objp, propp);
 }
 
 static JSBool
 with_LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp, JSProperty **propp)
 {
-    return with_LookupGeneric(cx, obj, ATOM_TO_JSID(name), objp, propp);
+    return with_LookupGeneric(cx, obj, NameToId(name), objp, propp);
 }
 
 static JSBool
 with_LookupElement(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp,
                    JSProperty **propp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
@@ -506,17 +506,17 @@ static JSBool
 with_GetGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     return obj->asWith().object().getGeneric(cx, id, vp);
 }
 
 static JSBool
 with_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp)
 {
-    return with_GetGeneric(cx, obj, receiver, ATOM_TO_JSID(name), vp);
+    return with_GetGeneric(cx, obj, receiver, NameToId(name), vp);
 }
 
 static JSBool
 with_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -801,17 +801,17 @@ block_setProperty(JSContext *cx, JSObjec
      * allocated when this let binding was defined.
      */
     return true;
 }
 
 bool
 ClonedBlockObject::containsVar(PropertyName *name, Value *vp, JSContext *cx)
 {
-    jsid id = ATOM_TO_JSID(name);
+    jsid id = NameToId(name);
     const Shape *shape = nativeLookup(cx, id);
     if (!shape)
         return false;
 
     JS_ASSERT(shape->getterOp() == block_getProperty);
     JS_ALWAYS_TRUE(block_getProperty(cx, this, INT_TO_JSID(shape->shortid()), vp));
     return true;
 }
@@ -952,17 +952,17 @@ js::XDRStaticBlockObject(XDRState<mode> 
          */
         for (unsigned i = 0; i < count; i++) {
             JSAtom *atom;
             if (!XDRAtom(xdr, &atom))
                 return false;
 
             /* The empty string indicates an int id. */
             jsid id = atom != cx->runtime->emptyString
-                      ? ATOM_TO_JSID(atom)
+                      ? AtomToId(atom)
                       : INT_TO_JSID(i);
 
             bool redeclared;
             if (!obj->addVar(cx, id, i, &redeclared)) {
                 JS_ASSERT(!redeclared);
                 return false;
             }
 
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -367,17 +367,17 @@ JSDependentString::undepend(JSContext *c
 
     d.lengthAndFlags = buildLengthAndFlags(n, FIXED_FLAGS);
     d.u1.chars = s;
 
     return &this->asFixed();
 }
 
 bool
-JSFlatString::isIndex(uint32_t *indexp) const
+JSFlatString::isIndexSlow(uint32_t *indexp) const
 {
     const jschar *s = charsZ();
     jschar ch = *s;
 
     if (!JS7_ISDEC(ch))
         return false;
 
     size_t n = length();
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -39,17 +39,19 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef String_h_
 #define String_h_
 
 #include "mozilla/Attributes.h"
 
 #include "jsapi.h"
+#include "jsatom.h"
 #include "jsfriendapi.h"
+#include "jsstr.h"
 
 #include "gc/Barrier.h"
 #include "gc/Heap.h"
 
 class JSString;
 class JSDependentString;
 class JSExtensibleString;
 class JSExternalString;
@@ -505,30 +507,35 @@ class JSFlatString : public JSLinearStri
         d.s.u2.base = base;
     }
 
     /* Vacuous and therefore unimplemented. */
     JSFlatString *ensureFlat(JSContext *cx) MOZ_DELETE;
     bool isFlat() const MOZ_DELETE;
     JSFlatString &asFlat() const MOZ_DELETE;
 
+    bool isIndexSlow(uint32_t *indexp) const;
+
   public:
     JS_ALWAYS_INLINE
     const jschar *charsZ() const {
         JS_ASSERT(JSString::isFlat());
         return chars();
     }
 
     /*
      * Returns true if this string's characters store an unsigned 32-bit
      * integer value, initializing *indexp to that value if so.  (Thus if
      * calling isIndex returns true, js::IndexToString(cx, *indexp) will be a
      * string equal to this string.)
      */
-    bool isIndex(uint32_t *indexp) const;
+    inline bool isIndex(uint32_t *indexp) const {
+        const jschar *s = chars();
+        return JS7_ISDEC(*s) && isIndexSlow(indexp);
+    }
 
     /*
      * Returns a property name represented by this string, or null on failure.
      * You must verify that this is not an index per isIndex before calling
      * this method.
      */
     inline js::PropertyName *toPropertyName(JSContext *cx);
 
@@ -771,16 +778,22 @@ class StaticStrings
  *     jsids, JSID_EMPTY, JSID_VOID, E4X's default XML namespace, and maybe in
  *     the future Harmony-proposed private names).
  */
 class PropertyName : public JSAtom
 {};
 
 JS_STATIC_ASSERT(sizeof(PropertyName) == sizeof(JSString));
 
+static JS_ALWAYS_INLINE jsid
+NameToId(PropertyName *name)
+{
+    return NON_INTEGER_ATOM_TO_JSID(name);
+}
+
 } /* namespace js */
 
 /* Avoid requiring vm/String-inl.h just to call getChars. */
 
 JS_ALWAYS_INLINE const jschar *
 JSString::getChars(JSContext *cx)
 {
     if (JSLinearString *str = ensureLinear(cx))
--- a/js/src/vm/StringObject-inl.h
+++ b/js/src/vm/StringObject-inl.h
@@ -66,17 +66,17 @@ StringObject::init(JSContext *cx, Handle
         } else {
             Shape *shape = assignInitialShape(cx);
             if (!shape)
                 return false;
             EmptyShape::insertInitialShape(cx, shape, self->getProto());
         }
     }
 
-    JS_ASSERT(self->nativeLookupNoAllocation(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom))->slot()
+    JS_ASSERT(self->nativeLookupNoAllocation(cx, NameToId(cx->runtime->atomState.lengthAtom))->slot()
               == LENGTH_SLOT);
 
     self->setStringThis(str);
 
     return true;
 }
 
 inline StringObject *