Backout 1c5a8d617bff (bug 765990), 617cb36ead59, b3067d05a76a (bug 760995), 79f9a61a1e43 (bug 426163) for bustage
authorEd Morley <emorley@mozilla.com>
Thu, 21 Jun 2012 10:00:36 +0100
changeset 102047 c710654ee7474c99b34f3c646a9ab25ba4c51b63
parent 102046 1c5a8d617bff300a1b6e3e96e9b4c79fdd69d553
child 102048 fb5be2e11080b8f5cb1ae45ad7d2ca1eaf8a11f9
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs765990, 760995, 426163
milestone16.0a1
backs out1c5a8d617bff300a1b6e3e96e9b4c79fdd69d553
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
Backout 1c5a8d617bff (bug 765990), 617cb36ead59, b3067d05a76a (bug 760995), 79f9a61a1e43 (bug 426163) for bustage
dom/base/nsDOMWindowUtils.cpp
js/src/builtin/MapObject.cpp
js/src/builtin/RegExp.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/gc/Root.h
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfun.cpp
js/src/jsfuninlines.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsonparser.cpp
js/src/jsproxy.cpp
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jswrapper.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/shell/jsheaptools.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/ScopeObject.cpp
js/xpconnect/src/XPCComponents.cpp
mfbt/Assertions.h
mfbt/HashFunctions.cpp
mfbt/HashFunctions.h
mfbt/Scoped.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1820,23 +1820,23 @@ nsDOMWindowUtils::GetParent(const JS::Va
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // First argument must be an object.
   if (JSVAL_IS_PRIMITIVE(aObject)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
-  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(JSVAL_TO_OBJECT(aObject)));
+  JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(aObject));
   *aParent = OBJECT_TO_JSVAL(parent);
 
   // Outerize if necessary.
   if (parent) {
     if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
-      *aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
+      *aParent = OBJECT_TO_JSVAL(outerize(aCx, JS::RootedObject(aCx, parent)));
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetOuterWindowID(PRUint64 *aWindowID)
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -150,18 +150,18 @@ JSFunctionSpec MapObject::methods[] = {
     JS_FN("set", set, 2, 0),
     JS_FN("delete", delete_, 1, 0),
     JS_FS_END
 };
 
 JSObject *
 MapObject::initClass(JSContext *cx, JSObject *obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
-    return InitClass(cx, global, &class_, JSProto_Map, construct, methods);
+    return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
+                     &class_, JSProto_Map, construct, methods);
 }
 
 void
 MapObject::mark(JSTracer *trc, JSObject *obj)
 {
     MapObject *mapobj = static_cast<MapObject *>(obj);
     if (ValueMap *map = mapobj->getData()) {
         for (ValueMap::Enum iter(*map); !iter.empty(); iter.popFront()) {
@@ -343,18 +343,18 @@ JSFunctionSpec SetObject::methods[] = {
     JS_FN("add", add, 1, 0),
     JS_FN("delete", delete_, 1, 0),
     JS_FS_END
 };
 
 JSObject *
 SetObject::initClass(JSContext *cx, JSObject *obj)
 {
-    Rooted<GlobalObject*> global(cx, &obj->asGlobal());
-    return InitClass(cx, global, &class_, JSProto_Set, construct, methods);
+    return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
+                     &class_, JSProto_Set, construct, methods);
 }
 
 void
 SetObject::mark(JSTracer *trc, JSObject *obj)
 {
     SetObject *setobj = static_cast<SetObject *>(obj);
     if (ValueSet *set = setobj->getData()) {
         for (ValueSet::Enum iter(*set); !iter.empty(); iter.popFront())
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -18,39 +18,37 @@
 using namespace js;
 using namespace js::types;
 
 class RegExpMatchBuilder
 {
     JSContext   * const cx;
     RootedObject array;
 
-    bool setProperty(Handle<PropertyName*> name, Value v) {
-        return !!baseops::DefineProperty(cx, array, name, &v,
+    bool setProperty(JSAtom *name, Value v) {
+        return !!baseops::DefineProperty(cx, array, RootedId(cx, 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);
         return !!baseops::DefineElement(cx, array, index, &v, JS_PropertyStub, JS_StrictPropertyStub,
                                         JSPROP_ENUMERATE);
     }
 
     bool setIndex(int index) {
-        Rooted<PropertyName*> name(cx, cx->runtime->atomState.indexAtom);
-        return setProperty(name, Int32Value(index));
+        return setProperty(cx->runtime->atomState.indexAtom, Int32Value(index));
     }
 
     bool setInput(JSString *str) {
         JS_ASSERT(str);
-        Rooted<PropertyName*> name(cx, cx->runtime->atomState.inputAtom);
-        return setProperty(name, StringValue(str));
+        return setProperty(cx->runtime->atomState.inputAtom, StringValue(str));
     }
 };
 
 static bool
 CreateRegExpMatchResult(JSContext *cx, JSString *input_, const jschar *chars, size_t length,
                         MatchPairs *matchPairs, Value *rval)
 {
     RootedString input(cx, input_);
@@ -191,18 +189,18 @@ EscapeNakedForwardSlashes(JSContext *cx,
  *  _ => pattern := ToString(pattern) if defined(pattern) else ''
  *       flags := ToString(flags) if defined(flags) else ''
  */
 static bool
 CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
 {
     if (args.length() == 0) {
         RegExpStatics *res = cx->regExpStatics();
-        Rooted<PropertyName*> empty(cx, cx->runtime->emptyString);
-        RegExpObject *reobj = builder.build(empty, res->getFlags());
+        RegExpObject *reobj = builder.build(RootedAtom(cx, cx->runtime->emptyString),
+                                            res->getFlags());
         if (!reobj)
             return false;
         args.rval() = ObjectValue(*reobj);
         return true;
     }
 
     Value sourceValue = args[0];
 
@@ -239,18 +237,17 @@ CompileRegExpObject(JSContext *cx, RegEx
         /*
          * 'toSource' is a permanent read-only property, so this is equivalent
          * to executing RegExpObject::getSource on the unwrapped object.
          */
         Value v;
         if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v))
             return false;
 
-        Rooted<JSAtom*> sourceAtom(cx, &v.toString()->asAtom());
-        RegExpObject *reobj = builder.build(sourceAtom, flags);
+        RegExpObject *reobj = builder.build(RootedAtom(cx, &v.toString()->asAtom()), flags);
         if (!reobj)
             return false;
 
         args.rval() = ObjectValue(*reobj);
         return true;
     }
 
     JSAtom *source;
@@ -460,18 +457,17 @@ js_InitRegExpClass(JSContext *cx, JSObje
     Rooted<GlobalObject*> global(cx, &obj->asGlobal());
 
     RootedObject proto(cx, global->createBlankPrototype(cx, &RegExpClass));
     if (!proto)
         return NULL;
     proto->setPrivate(NULL);
 
     RegExpObjectBuilder builder(cx, &proto->asRegExp());
-    Rooted<PropertyName*> empty(cx, cx->runtime->emptyString);
-    if (!builder.build(empty, RegExpFlag(0)))
+    if (!builder.build(RootedAtom(cx, cx->runtime->emptyString), RegExpFlag(0)))
         return NULL;
 
     if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))
         return NULL;
 
     RootedFunction ctor(cx);
     ctor = global->createConstructor(cx, regexp_construct, CLASS_NAME(cx, RegExp), 2);
     if (!ctor)
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5609,18 +5609,18 @@ 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());
-                Rooted<jsid> id(cx, AtomToId(pn3->pn_atom));
-                if (!DefineNativeProperty(cx, obj, id, UndefinedValue(), NULL, NULL,
+                if (!DefineNativeProperty(cx, obj, RootedId(cx, 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
@@ -535,18 +535,17 @@ CheckStrictParameters(JSContext *cx, Par
 }
 
 static bool
 BindLocalVariable(JSContext *cx, TreeContext *tc, ParseNode *pn, BindingKind kind)
 {
     JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
 
     unsigned index = tc->sc->bindings.numVars();
-    Rooted<JSAtom*> atom(cx, pn->pn_atom);
-    if (!tc->sc->bindings.add(cx, atom, kind))
+    if (!tc->sc->bindings.add(cx, RootedAtom(cx, pn->pn_atom), kind))
         return false;
 
     if (!pn->pn_cookie.set(cx, tc->staticLevel, index))
         return false;
     pn->pn_dflags |= PND_BOUND;
     return true;
 }
 
@@ -600,17 +599,17 @@ Parser::functionBody(FunctionBodyType ty
 
     /*
      * Check CheckStrictParameters before arguments logic below adds
      * 'arguments' to bindings.
      */
     if (!CheckStrictParameters(context, this))
         return NULL;
 
-    Rooted<PropertyName*> arguments(context, context->runtime->atomState.argumentsAtom);
+    Rooted<PropertyName*> const arguments(context, context->runtime->atomState.argumentsAtom);
 
     /*
      * Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
      * operation which means it aliases any bindings with the same name.
      * Due to the implicit declaration mechanism (below), 'arguments' will not
      * have decls and, even if it did, they will not be noted as closed in the
      * emitter. Thus, in the corner case of function-statement-overridding-
      * arguments, flag the whole scope as dynamic.
@@ -6847,18 +6846,18 @@ Parser::primaryExpr(TokenKind tt, bool a
                             return NULL;
                         pn3->pn_atom = atom;
                         break;
                     }
 
                     pn->pn_xflags |= PNX_NONCONST;
 
                     /* NB: Getter function in { get x(){} } is unnamed. */
-                    Rooted<PropertyName*> funName(context, NULL);
-                    pn2 = functionDef(funName, op == JSOP_GETTER ? Getter : Setter, Expression);
+                    pn2 = functionDef(RootedPropertyName(context, NULL),
+                                      op == JSOP_GETTER ? Getter : Setter, Expression);
                     if (!pn2)
                         return NULL;
                     TokenPos pos = {begin, pn2->pn_pos.end};
                     pn2 = new_<BinaryNode>(PNK_COLON, op, pos, pn3, pn2);
                     goto skip;
                 }
               case TOK_STRING: {
                 atom = tokenStream.currentToken().atom();
--- a/js/src/gc/Root.h
+++ b/js/src/gc/Root.h
@@ -91,17 +91,17 @@ class Handle
         h.ptr = p;
         return h;
     }
 
     /*
      * Construct a handle from an explicitly rooted location. This is the
      * normal way to create a handle, and normally happens implicitly.
      */
-    template <typename S> inline Handle(Rooted<S> &root);
+    template <typename S> inline Handle(const Rooted<S> &root);
 
     const T *address() const { return ptr; }
     T value() const { return *ptr; }
 
     operator T () const { return value(); }
     T operator ->() const { return value(); }
 
   private:
@@ -158,16 +158,25 @@ class Rooted
 
         ptr = initial;
     }
 
   public:
     Rooted(JSContext *cx) { init(cx, RootMethods<T>::initial()); }
     Rooted(JSContext *cx, T initial) { init(cx, initial); }
 
+    /*
+     * This method is only necessary due to an obscure C++98 requirement (that
+     * there be an accessible, usable copy constructor when passing a temporary
+     * to an implicitly-called constructor for use with a const-ref parameter).
+     * (Head spinning yet?)  We can remove this when we build the JS engine
+     * with -std=c++11.
+     */
+    operator Handle<T> () const { return Handle<T>(*this); }
+
     ~Rooted()
     {
 #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
         JS_ASSERT(*stack == this);
         *stack = prev;
 #endif
     }
 
@@ -203,17 +212,17 @@ class Rooted
     T ptr;
 
     Rooted() MOZ_DELETE;
     Rooted(const Rooted &) MOZ_DELETE;
 };
 
 template<typename T> template <typename S>
 inline
-Handle<T>::Handle(Rooted<S> &root)
+Handle<T>::Handle(const Rooted<S> &root)
 {
     testAssign<S>();
     ptr = reinterpret_cast<const T *>(root.address());
 }
 
 typedef Rooted<JSObject*>    RootedObject;
 typedef Rooted<JSFunction*>  RootedFunction;
 typedef Rooted<JSScript*>    RootedScript;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1774,18 +1774,17 @@ JS_InitStandardClasses(JSContext *cx, JS
      * it before assertSameCompartment. (The API contract is that *after* this,
      * cx and obj must be in the same compartment.)
      */
     if (!cx->globalObject)
         JS_SetGlobalObject(cx, obj);
 
     assertSameCompartment(cx, obj);
 
-    Rooted<GlobalObject*> global(cx, &obj->global());
-    return GlobalObject::initStandardClasses(cx, global);
+    return GlobalObject::initStandardClasses(cx, Rooted<GlobalObject*>(cx, &obj->global()));
 }
 
 #define CLASP(name)                 (&name##Class)
 #define TYPED_ARRAY_CLASP(type)     (&TypedArray::classes[TypedArray::type])
 #define EAGER_ATOM(name)            NAME_OFFSET(name)
 #define EAGER_CLASS_ATOM(name)      CLASS_NAME_OFFSET(name)
 #define EAGER_ATOM_AND_CLASP(name)  EAGER_CLASS_ATOM(name), CLASP(name)
 
@@ -3139,17 +3138,17 @@ JS_ResolveStub(JSContext *cx, JSHandleOb
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ConvertStub(JSContext *cx, JSHandleObject obj, JSType type, jsval *vp)
 {
     JS_ASSERT(type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION);
     JS_ASSERT(obj);
-    return DefaultValue(cx, obj, type, vp);
+    return DefaultValue(cx, RootedObject(cx, obj), type, vp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_InitClass(JSContext *cx, JSObject *obj_, JSObject *parent_proto,
              JSClass *clasp, JSNative constructor, unsigned nargs,
              JSPropertySpec *ps, JSFunctionSpec *fs,
              JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
 {
@@ -3227,46 +3226,40 @@ JS_GetInstancePrivate(JSContext *cx, JSO
 
 JS_PUBLIC_API(JSObject *)
 JS_GetPrototype(JSObject *obj)
 {
     return obj->getProto();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_SetPrototype(JSContext *cx, JSObject *obj_, JSObject *proto_)
-{
-    AssertNoGC(cx);
-    CHECK_REQUEST(cx);
-    assertSameCompartment(cx, obj_, proto_);
-
-    Rooted<JSObject*> obj(cx, obj_);
-    Rooted<JSObject*> proto(cx, proto_);
-    return SetProto(cx, obj, proto, JS_FALSE);
+JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
+{
+    AssertNoGC(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj, proto);
+    return SetProto(cx, RootedObject(cx, obj), RootedObject(cx, proto), JS_FALSE);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetParent(JSObject *obj)
 {
     JS_ASSERT(!obj->isScope());
     return obj->getParent();
 }
 
 JS_PUBLIC_API(JSBool)
-JS_SetParent(JSContext *cx, JSObject *obj_, JSObject *parent_)
-{
-    AssertNoGC(cx);
-    CHECK_REQUEST(cx);
-    JS_ASSERT(!obj_->isScope());
-    JS_ASSERT(parent_ || !obj_->getParent());
-    assertSameCompartment(cx, obj_, parent_);
-
-    Rooted<JSObject*> obj(cx, obj_);
-    Rooted<JSObject*> parent(cx, parent_);
-    return JSObject::setParent(cx, obj, parent);
+JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
+{
+    AssertNoGC(cx);
+    CHECK_REQUEST(cx);
+    JS_ASSERT(!obj->isScope());
+    JS_ASSERT(parent || !obj->getParent());
+    assertSameCompartment(cx, obj, parent);
+    return JSObject::setParent(cx, RootedObject(cx, obj), RootedObject(cx, parent));
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetConstructor(JSContext *cx, JSObject *proto)
 {
     Value cval;
 
     AssertNoGC(cx);
@@ -3806,25 +3799,22 @@ JS_DefineUCPropertyWithTinyId(JSContext 
                               int8_t tinyid, jsval value,
                               JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
 {
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs,
                             Shape::HAS_SHORTID, tinyid);
 }
 
 JS_PUBLIC_API(JSBool)
-JS_DefineOwnProperty(JSContext *cx, JSObject *obj_, jsid id_, jsval descriptor, JSBool *bp)
-{
-    AssertNoGC(cx);
-    CHECK_REQUEST(cx);
-    assertSameCompartment(cx, obj_, id_, descriptor);
-
-    Rooted<JSObject*> obj(cx, obj_);
-    Rooted<jsid> id(cx, id_);
-    return js_DefineOwnProperty(cx, obj, id, descriptor, bp);
+JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp)
+{
+    AssertNoGC(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj, id, descriptor);
+    return js_DefineOwnProperty(cx, RootedObject(cx, obj), RootedId(cx, id), descriptor, bp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_DefineObject(JSContext *cx, JSObject *obj_, const char *name, JSClass *jsclasp,
                 JSObject *proto, unsigned attrs)
 {
     RootedObject obj(cx, obj_), nobj(cx);
 
@@ -3990,24 +3980,21 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSC
                                      JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
 {
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     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);
-
-    Rooted<JSObject*> obj(cx, obj_);
-    Rooted<jsid> id(cx, id_);
-    return GetOwnPropertyDescriptor(cx, obj, id, vp);
+JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    AssertNoGC(cx);
+    CHECK_REQUEST(cx);
+    return GetOwnPropertyDescriptor(cx, RootedObject(cx, obj), RootedId(cx, id), vp);
 }
 
 static JSBool
 SetPropertyAttributesById(JSContext *cx, JSObject *obj, HandleId id, unsigned attrs, JSBool *foundp)
 {
     JSObject *obj2;
     JSProperty *prop;
 
@@ -4026,27 +4013,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));
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
+    return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, 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));
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
+    return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, 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);
 }
 
@@ -4060,21 +4045,19 @@ JS_ForwardGetPropertyTo(JSContext *cx, J
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     assertSameCompartment(cx, onBehalfOf);
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
     return obj->getGeneric(cx, onBehalfOf, id, vp);
 }
 
 JS_PUBLIC_API(JSBool)
-JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj_, jsid id_, jsval def, jsval *vp)
-{
-    Rooted<JSObject*> obj(cx, obj_);
-    Rooted<jsid> id(cx, id_);
-    return baseops::GetPropertyDefault(cx, obj, id, def, vp);
+JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp)
+{
+    return baseops::GetPropertyDefault(cx, RootedObject(cx, obj), RootedId(cx, id), def, vp);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetElement(JSContext *cx, JSObject *obj, uint32_t index, jsval *vp)
 {
     return JS_ForwardGetElementTo(cx, obj, index, obj, vp);
 }
 
@@ -4196,20 +4179,18 @@ JS_SetUCProperty(JSContext *cx, JSObject
 JS_PUBLIC_API(JSBool)
 JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
 
-    if (JSID_IS_SPECIAL(id)) {
-        Rooted<SpecialId> sid(cx, JSID_TO_SPECIALID(id));
-        return obj->deleteSpecial(cx, sid, rval, false);
-    }
+    if (JSID_IS_SPECIAL(id))
+        return obj->deleteSpecial(cx, Rooted<SpecialId>(cx, JSID_TO_SPECIALID(id)), rval, false);
 
     return obj->deleteByValue(cx, IdToValue(id), rval, false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32_t index, jsval *rval)
 {
     AssertNoGC(cx);
@@ -4445,24 +4426,22 @@ JS_NextProperty(JSContext *cx, JSObject 
             *idp = ida->vector[--i];
             iterobj->setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
         }
     }
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewElementIterator(JSContext *cx, JSObject *obj_)
-{
-    AssertNoGC(cx);
-    CHECK_REQUEST(cx);
-    assertSameCompartment(cx, obj_);
-
-    Rooted<JSObject*> obj(cx, obj_);
-    return ElementIteratorObject::create(cx, obj);
+JS_NewElementIterator(JSContext *cx, JSObject *obj)
+{
+    AssertNoGC(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj);
+    return ElementIteratorObject::create(cx, RootedObject(cx, obj));
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_ElementIteratorStub(JSContext *cx, JSHandleObject obj, JSBool keysonly)
 {
     JS_ASSERT(!keysonly);
     return JS_NewElementIterator(cx, obj);
 }
@@ -4744,43 +4723,45 @@ JS_DefineFunctions(JSContext *cx, JSObje
     assertSameCompartment(cx, obj);
     for (; fs->name; fs++) {
         flags = fs->flags;
 
         RootedAtom atom(cx, js_Atomize(cx, fs->name, strlen(fs->name)));
         if (!atom)
             return JS_FALSE;
 
-        Rooted<jsid> id(cx, AtomToId(atom));
-
         /*
          * Define a generic arity N+1 static method for the arity N prototype
          * method if flags contains JSFUN_GENERIC_NATIVE.
          */
         if (flags & JSFUN_GENERIC_NATIVE) {
             if (!ctor) {
                 ctor = JS_GetConstructor(cx, obj);
                 if (!ctor)
                     return JS_FALSE;
             }
 
             flags &= ~JSFUN_GENERIC_NATIVE;
-            fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher,
-                                    fs->nargs + 1, flags, JSFunction::ExtendedFinalizeKind);
+            fun = js_DefineFunction(cx, ctor, RootedId(cx, 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, obj, id, fs->call, fs->nargs, flags);
+        fun = js_DefineFunction(cx, obj,
+                                RootedId(cx, 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,
@@ -4790,36 +4771,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;
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return js_DefineFunction(cx, obj, id, call, nargs, attrs);
+    return js_DefineFunction(cx, obj, RootedId(cx, 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)
 {
     RootedObject obj(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;
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return js_DefineFunction(cx, obj, id, call, nargs, attrs);
+    return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)), call, nargs, attrs);
 }
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunctionById(JSContext *cx, JSObject *obj_, jsid id_, JSNative call,
                     unsigned nargs, unsigned attrs)
 {
     RootedObject obj(cx, obj_);
     RootedId id(cx, id_);
@@ -5184,20 +5163,21 @@ CompileUCFunctionForPrincipalsCommon(JSC
         return NULL;
 
     if (!frontend::CompileFunctionBody(cx, fun, principals, NULL, &bindings,
                                        chars, length, filename, lineno, version))
     {
         return NULL;
     }
 
-    if (obj && funAtom) {
-        Rooted<jsid> id(cx, AtomToId(funAtom));
-        if (!obj->defineGeneric(cx, id, ObjectValue(*fun), NULL, NULL, JSPROP_ENUMERATE))
-            return NULL;
+    if (obj && funAtom &&
+        !obj->defineGeneric(cx, RootedId(cx, AtomToId(funAtom)), ObjectValue(*fun), NULL, NULL,
+                            JSPROP_ENUMERATE))
+    {
+        return NULL;
     }
 
     return fun;
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
                                          JSPrincipals *principals, const char *name,
@@ -5486,21 +5466,18 @@ JS_CallFunctionName(JSContext *cx, JSObj
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj_, JSValueArray(argv, argc));
     AutoLastFrameCheck lfc(cx);
 
     RootedObject obj(cx, obj_);
 
     Value v;
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    if (!atom)
-        return false;
-
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return GetMethod(cx, obj, id, 0, &v) &&
+    return atom &&
+           GetMethod(cx, obj, RootedId(cx, 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);
@@ -5869,19 +5846,17 @@ JS_NewDependentString(JSContext *cx, JSS
     return js_NewDependentString(cx, str, start, length);
 }
 
 JS_PUBLIC_API(JSString *)
 JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
-    Rooted<JSString*> lstr(cx, left);
-    Rooted<JSString*> rstr(cx, right);
-    return js_ConcatStrings(cx, lstr, rstr);
+    return js_ConcatStrings(cx, RootedString(cx, left), RootedString(cx, right));
 }
 
 JS_PUBLIC_API(const jschar *)
 JS_UndependString(JSContext *cx, JSString *str)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     return str->getCharsZ(cx);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -711,18 +711,17 @@ array_lookupGeneric(JSContext *cx, Handl
     }
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 static JSBool
 array_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject **objp,
                      JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return array_lookupGeneric(cx, obj, id, objp, propp);
+    return array_lookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 static JSBool
 array_lookupElement(JSContext *cx, HandleObject obj, uint32_t index, JSObject **objp,
                     JSProperty **propp)
 {
     if (!obj->isDenseArray())
         return baseops::LookupElement(cx, obj, index, objp, propp);
@@ -740,18 +739,17 @@ array_lookupElement(JSContext *cx, Handl
     *propp = NULL;
     return true;
 }
 
 static JSBool
 array_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSObject **objp,
                     JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return array_lookupGeneric(cx, obj, id, objp, propp);
+    return array_lookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 JSBool
 js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     JS_ASSERT(obj->isDenseArray());
 
     uint32_t i;
@@ -772,20 +770,18 @@ array_getProperty(JSContext *cx, HandleO
         return true;
     }
 
     if (name == cx->runtime->atomState.protoAtom) {
         vp->setObjectOrNull(obj->getProto());
         return true;
     }
 
-    if (!obj->isDenseArray()) {
-        Rooted<jsid> id(cx, NameToId(name));
-        return baseops::GetProperty(cx, obj, receiver, id, vp);
-    }
+    if (!obj->isDenseArray())
+        return baseops::GetProperty(cx, obj, receiver, RootedId(cx, NameToId(name)), vp);
 
     JSObject *proto = obj->getProto();
     if (!proto) {
         vp->setUndefined();
         return true;
     }
 
     return proto->getProperty(cx, receiver, name, vp);
@@ -820,42 +816,40 @@ array_getElement(JSContext *cx, HandleOb
 static JSBool
 array_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid, Value *vp)
 {
     if (obj->isDenseArray() && !obj->getProto()) {
         vp->setUndefined();
         return true;
     }
 
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return baseops::GetProperty(cx, obj, receiver, id, vp);
+    return baseops::GetProperty(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 static JSBool
 array_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, Value *vp)
 {
     Value idval = IdToValue(id);
 
     uint32_t index;
     if (IsDefinitelyIndex(idval, &index))
         return array_getElement(cx, obj, receiver, index, vp);
 
-    Rooted<SpecialId> sid(cx);
-    if (ValueIsSpecial(obj, &idval, sid.address(), cx))
-        return array_getSpecial(cx, obj, receiver, sid, vp);
+    SpecialId sid;
+    if (ValueIsSpecial(obj, &idval, &sid, cx))
+        return array_getSpecial(cx, obj, receiver, Rooted<SpecialId>(cx, sid), vp);
 
     JSAtom *atom = ToAtom(cx, idval);
     if (!atom)
         return false;
 
     if (atom->isIndex(&index))
         return array_getElement(cx, obj, receiver, index, vp);
 
-    Rooted<PropertyName*> name(cx, atom->asPropertyName());
-    return array_getProperty(cx, obj, receiver, name, vp);
+    return array_getProperty(cx, obj, receiver, RootedPropertyName(cx, atom->asPropertyName()), vp);
 }
 
 static JSBool
 slowarray_addProperty(JSContext *cx, HandleObject obj, HandleId id, Value *vp)
 {
     uint32_t index, length;
 
     if (!js_IdIsIndex(id, &index))
@@ -905,18 +899,17 @@ array_setGeneric(JSContext *cx, HandleOb
     if (!JSObject::makeDenseArraySlow(cx, obj))
         return false;
     return baseops::SetPropertyHelper(cx, obj, id, 0, vp, strict);
 }
 
 static JSBool
 array_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return array_setGeneric(cx, obj, id, vp, strict);
+    return array_setGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
 }
 
 static JSBool
 array_setElement(JSContext *cx, HandleObject obj, uint32_t index, Value *vp, JSBool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
@@ -951,18 +944,17 @@ array_setElement(JSContext *cx, HandleOb
     if (!JSObject::makeDenseArraySlow(cx, obj))
         return false;
     return baseops::SetPropertyHelper(cx, obj, id, 0, vp, strict);
 }
 
 static JSBool
 array_setSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return array_setGeneric(cx, obj, id, vp, strict);
+    return array_setGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
 }
 
 JSBool
 js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
 {
     /*
      * Walk up the prototype chain and see if this indexed element already
      * exists. If we hit the end of the prototype chain, it's safe to set the
@@ -985,17 +977,17 @@ js_PrototypeHasIndexedProperties(JSConte
 static JSBool
 array_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *value,
                     JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
         return JS_TRUE;
 
     if (!obj->isDenseArray())
-        return baseops::DefineGeneric(cx, obj, id, value, getter, setter, attrs);
+        return baseops::DefineProperty(cx, obj, id, value, getter, setter, attrs);
 
     do {
         uint32_t i = 0;       // init to shut GCC up
         bool isIndex = js_IdIsIndex(id, &i);
         if (!isIndex || attrs != JSPROP_ENUMERATE)
             break;
 
         JSObject::EnsureDenseResult result = obj->ensureDenseArrayElements(cx, i, 1);
@@ -1011,25 +1003,24 @@ array_defineGeneric(JSContext *cx, Handl
         obj->setDenseArrayElementWithType(cx, i, *value);
         return true;
     } while (false);
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
     if (!JSObject::makeDenseArraySlow(cx, obj))
         return false;
-    return baseops::DefineGeneric(cx, obj, id, value, getter, setter, attrs);
+    return baseops::DefineProperty(cx, obj, id, value, getter, setter, attrs);
 }
 
 static JSBool
 array_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, const Value *value,
                      JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return array_defineGeneric(cx, obj, id, value, getter, setter, attrs);
+    return array_defineGeneric(cx, obj, RootedId(cx, NameToId(name)), value, getter, setter, attrs);
 }
 
 namespace js {
 
 /* non-static for direct definition of array elements within the engine */
 JSBool
 array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
@@ -1067,18 +1058,18 @@ array_defineElement(JSContext *cx, Handl
 }
 
 } // namespace js
 
 static JSBool
 array_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return array_defineGeneric(cx, obj, id, value, getter, setter, attrs);
+    return array_defineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)),
+                               value, getter, setter, attrs);
 }
 
 static JSBool
 array_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     *attrsp = JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)
         ? JSPROP_PERMANENT : JSPROP_ENUMERATE;
     return true;
@@ -1159,17 +1150,17 @@ array_deleteElement(JSContext *cx, Handl
     if (!obj->isDenseArray())
         return baseops::DeleteElement(cx, obj, index, rval, strict);
 
     if (index < obj->getDenseArrayInitializedLength()) {
         obj->markDenseArrayNotPacked(cx);
         obj->setDenseArrayElement(index, MagicValue(JS_ARRAY_HOLE));
     }
 
-    if (!js_SuppressDeletedElement(cx, obj, index))
+    if (!js_SuppressDeletedElement(cx, RootedObject(cx, obj), index))
         return false;
 
     rval->setBoolean(true);
     return true;
 }
 
 } // namespace js
 
@@ -1708,18 +1699,17 @@ array_toLocaleString(JSContext *cx, unsi
     RootedObject obj(cx, ToObject(cx, &args.thisv()));
     if (!obj)
         return false;
 
     /*
      *  Passing comma here as the separator. Need a way to get a
      *  locale-specific version.
      */
-    Rooted<JSString*> none(cx, NULL);
-    return array_toString_sub(cx, obj, JS_TRUE, none, args);
+    return array_toString_sub(cx, obj, JS_TRUE, RootedString(cx), args);
 }
 
 static inline bool
 InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned count)
 {
     if (cx->typeInferenceEnabled() && !type->unknownProperties()) {
         AutoEnterTypeInference enter(cx);
 
@@ -2390,17 +2380,17 @@ NewbornArrayPushImpl(JSContext *cx, Hand
 {
     JS_ASSERT(!v.isMagic());
 
     uint32_t length = obj->getArrayLength();
     if (obj->isSlowArray()) {
         /* This can happen in one evil case. See bug 630377. */
         RootedId id(cx);
         return IndexToId(cx, length, id.address()) &&
-               baseops::DefineGeneric(cx, obj, id, &v, NULL, NULL, JSPROP_ENUMERATE);
+               baseops::DefineProperty(cx, obj, id, &v, NULL, NULL, JSPROP_ENUMERATE);
     }
 
     JS_ASSERT(obj->isDenseArray());
     JS_ASSERT(length <= obj->getDenseArrayCapacity());
 
     if (!obj->ensureElements(cx, length + 1))
         return false;
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -652,17 +652,17 @@ struct JSRuntime : js::RuntimeFriendFiel
     /* Strong references on scripts held for PCCount profiling API. */
     js::ScriptAndCountsVector *scriptAndCountsVector;
 
     /* Well-known numbers held for use by this runtime's contexts. */
     js::Value           NaNValue;
     js::Value           negativeInfinityValue;
     js::Value           positiveInfinityValue;
 
-    js::PropertyName    *emptyString;
+    JSAtom              *emptyString;
 
     /* List of active contexts sharing this runtime. */
     JSCList             contextList;
 
     bool hasContexts() const {
         return !JS_CLIST_IS_EMPTY(&contextList);
     }
 
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -162,17 +162,17 @@ JSCompartment::wrap(JSContext *cx, Value
     } else {
         global = JS_ObjectToInnerObject(cx, cx->globalObject);
         if (!global)
             return false;
     }
 
     /* Unwrap incoming objects. */
     if (vp->isObject()) {
-        Rooted<JSObject*> obj(cx, &vp->toObject());
+        JSObject *obj = &vp->toObject();
 
         if (obj->compartment() == this)
             return WrapForSameCompartment(cx, obj, vp);
 
         /* Translate StopIteration singleton. */
         if (obj->isStopIteration())
             return js_FindClassObject(cx, NULL, JSProto_StopIteration, vp);
 
@@ -189,17 +189,17 @@ JSCompartment::wrap(JSContext *cx, Value
         }
 
         if (obj->compartment() == this)
             return WrapForSameCompartment(cx, obj, vp);
         vp->setObject(*obj);
 
 #ifdef DEBUG
         {
-            JSObject *outer = GetOuterObject(cx, obj);
+            JSObject *outer = GetOuterObject(cx, RootedObject(cx, obj));
             JS_ASSERT(outer && outer == obj);
         }
 #endif
     }
 
     RootedValue key(cx, *vp);
 
     /* If we already have a wrapper for this value, use it. */
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2694,18 +2694,18 @@ js_InitDateClass(JSContext *cx, JSObject
      * Date.prototype.toUTCString.
      */
     if (!JS_DefineFunctions(cx, dateProto, date_methods))
         return NULL;
     Value toUTCStringFun;
     RootedId toUTCStringId(cx, NameToId(cx->runtime->atomState.toUTCStringAtom));
     RootedId toGMTStringId(cx, NameToId(cx->runtime->atomState.toGMTStringAtom));
     if (!baseops::GetProperty(cx, dateProto, toUTCStringId, &toUTCStringFun) ||
-        !baseops::DefineGeneric(cx, dateProto, toGMTStringId, &toUTCStringFun,
-                                JS_PropertyStub, JS_StrictPropertyStub, 0))
+        !baseops::DefineProperty(cx, dateProto, toGMTStringId, &toUTCStringFun,
+                                 JS_PropertyStub, JS_StrictPropertyStub, 0))
     {
         return NULL;
     }
 
     if (!DefineConstructorAndPrototype(cx, global, JSProto_Date, ctor, dateProto))
         return NULL;
 
     return dateProto;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -778,18 +778,17 @@ GetPropertyDesc(JSContext *cx, JSObject 
     RootedObject obj(cx, obj_);
 
     JSBool wasThrowing = cx->isExceptionPending();
     Value lastException = UndefinedValue();
     if (wasThrowing)
         lastException = cx->getPendingException();
     cx->clearPendingException();
 
-    Rooted<jsid> id(cx, shape->propid());
-    if (!baseops::GetProperty(cx, obj, id, &pd->value)) {
+    if (!baseops::GetProperty(cx, obj, RootedId(cx, shape->propid()), &pd->value)) {
         if (!cx->isExceptionPending()) {
             pd->flags = JSPD_ERROR;
             pd->value = JSVAL_VOID;
         } else {
             pd->flags = JSPD_EXCEPTION;
             pd->value = cx->getPendingException();
         }
     } else {
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -264,18 +264,17 @@ InitExnPrivate(JSContext *cx, HandleObje
 
             /*
              * 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();
                 RootedId callerid(cx, NameToId(cx->runtime->atomState.callerAtom));
-                Rooted<JSObject*> obj(cx, i.callee());
-                if (!checkAccess(cx, obj, callerid, JSACC_READ, &v))
+                if (!checkAccess(cx, RootedObject(cx, i.callee()), callerid, JSACC_READ, &v))
                     break;
             }
 
             if (!frames.growBy(1))
                 return false;
             JSStackTraceStackElem &frame = frames.back();
             if (i.isNonEvalFunctionFrame())
                 frame.funName = fp->fun()->atom ? fp->fun()->atom : cx->runtime->emptyString;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -226,18 +226,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;
 
         RootedFunction fun(cx);
-        Rooted<jsid> id(cx, AtomToId(atom));
-        fun = js_DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags);
+        fun = js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)),
+                                fs->call, fs->nargs, fs->flags);
         if (!fun)
             return false;
 
         if (fs->usage) {
             if (!DefineHelpProperty(cx, fun, "usage", fs->usage))
                 return false;
         }
 
@@ -333,18 +333,19 @@ js::DefineFunctionWithReserved(JSContext
     RootedObject obj(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;
-    Rooted<jsid> id(cx, AtomToId(atom));
-    return js_DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
+    return js_DefineFunction(cx, obj, RootedId(cx, 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)
 {
     RootedObject parent(cx, parent_);
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -421,18 +421,17 @@ js::CloneInterpretedFunction(JSContext *
     JSFunction *clone = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, parent, NULL);
     if (!clone)
         return NULL;
     if (!clone->clearParent(cx))
         return NULL;
     if (!clone->clearType(cx))
         return NULL;
 
-    Rooted<JSScript*> srcScript(cx, srcFun->script());
-    JSScript *clonedScript = CloneScript(cx, srcScript);
+    JSScript *clonedScript = CloneScript(cx, RootedScript(cx, srcFun->script()));
     if (!clonedScript)
         return NULL;
 
     clone->nargs = srcFun->nargs;
     clone->flags = srcFun->flags;
     clone->atom.init(srcFun->atom);
     clone->initScript(clonedScript);
     if (!clonedScript->typeSetFunction(cx, clone))
--- a/js/src/jsfuninlines.h
+++ b/js/src/jsfuninlines.h
@@ -201,18 +201,17 @@ CloneFunctionObjectIfNotSingleton(JSCont
     /*
      * For attempts to clone functions at a function definition opcode,
      * don't perform the clone if the function has singleton type. This
      * was called pessimistically, and we need to preserve the type's
      * property that if it is singleton there is only a single object
      * with its type in existence.
      */
     if (fun->hasSingletonType()) {
-        Rooted<JSObject*> obj(cx, SkipScopeParent(parent));
-        if (!JSObject::setParent(cx, fun, obj))
+        if (!JSObject::setParent(cx, fun, RootedObject(cx, SkipScopeParent(parent))))
             return NULL;
         fun->setEnvironment(parent);
         return fun;
     }
 
     return CloneFunctionObject(cx, fun, parent);
 }
 
@@ -226,19 +225,20 @@ CloneFunctionObject(JSContext *cx, Handl
      * objects so that fun->global() != fun->getProto()->global().
      * See ReparentWrapperIfFound.
      */
     JS_ASSERT(fun->getParent() && fun->getProto());
 
     if (fun->hasSingletonType())
         return fun;
 
-    Rooted<JSObject*> env(cx, fun->environment());
-    Rooted<JSObject*> proto(cx, fun->getProto());
-    return js_CloneFunctionObject(cx, fun, env, proto, JSFunction::ExtendedFinalizeKind);
+    return js_CloneFunctionObject(cx, fun,
+                                  RootedObject(cx, fun->environment()),
+                                  RootedObject(cx, fun->getProto()),
+                                  JSFunction::ExtendedFinalizeKind);
 }
 
 } /* namespace js */
 
 inline void
 JSFunction::setScript(JSScript *script_)
 {
     JS_ASSERT(isInterpreted());
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1677,18 +1677,18 @@ TypeSet::isOwnProperty(JSContext *cx, Ty
     /*
      * Everywhere compiled code depends on definite properties associated with
      * a type object's newScript, we need to make sure there are constraints
      * in place which will mark those properties as configured should the
      * definite properties be invalidated.
      */
     if (object->flags & OBJECT_FLAG_NEW_SCRIPT_REGENERATE) {
         if (object->newScript) {
-            Rooted<TypeObject*> typeObj(cx, object);
-            CheckNewScriptProperties(cx, typeObj, object->newScript->fun);
+            CheckNewScriptProperties(cx, RootedTypeObject(cx, object),
+                                     object->newScript->fun);
         } else {
             JS_ASSERT(object->flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED);
             object->flags &= ~OBJECT_FLAG_NEW_SCRIPT_REGENERATE;
         }
     }
 
     if (isOwnProperty(configurable))
         return true;
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -532,18 +532,17 @@ js::LooselyEqual(JSContext *cx, const Va
         }
 
         if (lval.isObject()) {
             JSObject *l = &lval.toObject();
             JSObject *r = &rval.toObject();
 
             if (JSEqualityOp eq = l->getClass()->ext.equality) {
                 JSBool res;
-                Rooted<JSObject*> lobj(cx, l);
-                if (!eq(cx, lobj, &rval, &res))
+                if (!eq(cx, RootedObject(cx, l), &rval, &res))
                     return false;
                 *result = !!res;
                 return true;
             }
 
             *result = l == r;
             return true;
         }
@@ -979,18 +978,17 @@ IteratorMore(JSContext *cx, JSObject *it
 {
     if (iterobj->isIterator()) {
         NativeIterator *ni = iterobj->getNativeIterator();
         if (ni->isKeyIter()) {
             *cond = (ni->props_cursor < ni->props_end);
             return true;
         }
     }
-    Rooted<JSObject*> iobj(cx, iterobj);
-    if (!js_IteratorMore(cx, iobj, rval))
+    if (!js_IteratorMore(cx, RootedObject(cx, iterobj), rval))
         return false;
     *cond = rval->isTrue();
     return true;
 }
 
 static inline bool
 IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
 {
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -120,18 +120,17 @@ ValuePropertyBearer(JSContext *cx, Stack
         return global.getOrCreateBooleanPrototype(cx);
 
     JS_ASSERT(v.isNull() || v.isUndefined());
     js_ReportIsNullOrUndefined(cx, spindex, v, NULL);
     return NULL;
 }
 
 inline bool
-NativeGet(JSContext *cx, Handle<JSObject*> obj, Handle<JSObject*> pobj, const Shape *shape,
-          unsigned getHow, Value *vp)
+NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, unsigned getHow, Value *vp)
 {
     if (shape->isDataDescriptor() && shape->hasDefaultGetter()) {
         /* Fast path for Object instance properties. */
         JS_ASSERT(shape->hasSlot());
         *vp = pobj->nativeGetSlot(shape->slot());
     } else {
         if (!js_NativeGet(cx, obj, pobj, shape, getHow, vp))
             return false;
@@ -207,19 +206,19 @@ GetPropertyOperation(JSContext *cx, jsby
         }
     }
 
     RootedObject obj(cx, ValueToObject(cx, lval));
     if (!obj)
         return false;
 
     PropertyCacheEntry *entry;
-    Rooted<JSObject*> obj2(cx);
+    JSObject *obj2;
     PropertyName *name;
-    JS_PROPERTY_CACHE(cx).test(cx, pc, obj.reference(), obj2.reference(), entry, name);
+    JS_PROPERTY_CACHE(cx).test(cx, pc, obj.reference(), obj2, entry, name);
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
         if (!NativeGet(cx, obj, obj2, entry->prop, JSGET_CACHE_RESULT, vp))
             return false;
         return true;
     }
 
     RootedId id(cx, NameToId(name));
@@ -332,50 +331,49 @@ NameOperation(JSContext *cx, jsbytecode 
      * accessing the global object, and the inferred behavior should match
      * the actual behavior even if the id could be found on the scope chain
      * before the global object.
      */
     if (js_CodeSpec[*pc].format & JOF_GNAME)
         obj = &obj->global();
 
     PropertyCacheEntry *entry;
-    Rooted<JSObject*> obj2(cx);
+    JSObject *obj2;
     RootedPropertyName name(cx);
-    JS_PROPERTY_CACHE(cx).test(cx, pc, obj.reference(), obj2.reference(), entry, name.reference());
+    JS_PROPERTY_CACHE(cx).test(cx, pc, obj.reference(), obj2, entry, name.reference());
     if (!name) {
         AssertValidPropertyCacheHit(cx, obj, obj2, entry);
         if (!NativeGet(cx, obj, obj2, entry->prop, 0, vp))
             return false;
         return true;
     }
 
     JSProperty *prop;
-    if (!FindPropertyHelper(cx, name, true, obj, obj.address(), obj2.address(), &prop))
+    if (!FindPropertyHelper(cx, name, true, obj, obj.address(), &obj2, &prop))
         return false;
     if (!prop) {
         /* Kludge to allow (typeof foo == "undefined") tests. */
         JSOp op2 = JSOp(pc[JSOP_NAME_LENGTH]);
         if (op2 == JSOP_TYPEOF) {
             vp->setUndefined();
             return true;
         }
         JSAutoByteString printable;
         if (js_AtomToPrintableString(cx, name, &printable))
             js_ReportIsNotDefined(cx, printable.ptr());
         return false;
     }
 
     /* Take the slow path if prop was not found in a native object. */
     if (!obj->isNative() || !obj2->isNative()) {
-        Rooted<jsid> id(cx, NameToId(name));
-        if (!obj->getGeneric(cx, id, vp))
+        if (!obj->getGeneric(cx, RootedId(cx, NameToId(name)), vp))
             return false;
     } else {
         Shape *shape = (Shape *)prop;
-        Rooted<JSObject*> normalized(cx, obj);
+        JSObject *normalized = obj;
         if (normalized->getClass() == &WithClass && !shape->hasDefaultGetter())
             normalized = &normalized->asWith().object();
         if (!NativeGet(cx, normalized, obj2, shape, 0, vp))
             return false;
     }
 
     return true;
 }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -79,31 +79,29 @@ Class js::ObjectClass = {
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
 JS_FRIEND_API(JSObject *)
-JS_ObjectToInnerObject(JSContext *cx, JSObject *obj_)
-{
-    if (!obj_) {
+JS_ObjectToInnerObject(JSContext *cx, JSObject *obj)
+{
+    if (!obj) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
         return NULL;
     }
-    Rooted<JSObject*> obj(cx, obj_);
-    return GetInnerObject(cx, obj);
+    return GetInnerObject(cx, RootedObject(cx, obj));
 }
 
 JS_FRIEND_API(JSObject *)
-JS_ObjectToOuterObject(JSContext *cx, JSObject *obj_)
-{
-    Rooted<JSObject*> obj(cx, obj_);
-    return GetOuterObject(cx, obj);
+JS_ObjectToOuterObject(JSContext *cx, JSObject *obj)
+{
+    return GetOuterObject(cx, RootedObject(cx, obj));
 }
 
 #if JS_HAS_OBJ_PROTO_PROP
 
 static JSBool
 obj_getProto(JSContext *cx, HandleObject obj, HandleId id, Value *vp);
 
 static JSBool
@@ -198,33 +196,31 @@ MarkSharpObjects(JSContext *cx, HandleOb
                 if (hasSetter)
                     setter = shape->setterValue();
             } else {
                 hasGetter = hasSetter = false;
             }
             if (hasSetter) {
                 /* Mark the getter, then set val to setter. */
                 if (hasGetter && value.isObject()) {
-                    Rooted<JSObject*> vobj(cx, &value.toObject());
-                    ok = MarkSharpObjects(cx, vobj, NULL, NULL);
+                    ok = MarkSharpObjects(cx, RootedObject(cx, &value.toObject()), NULL, NULL);
                     if (!ok)
                         break;
                 }
                 value = setter;
             } else if (!hasGetter) {
                 ok = obj->getGeneric(cx, id, &value);
                 if (!ok)
                     break;
             }
-            if (value.isObject()) {
-                Rooted<JSObject*> vobj(cx, &value.toObject());
-                if (!MarkSharpObjects(cx, vobj, NULL, NULL)) {
-                    ok = false;
-                    break;
-                }
+            if (value.isObject() &&
+                !MarkSharpObjects(cx, RootedObject(cx, &value.toObject()), NULL, NULL))
+            {
+                ok = false;
+                break;
             }
         }
         if (!ok || !idap)
             JS_DestroyIdArray(cx, ida);
         if (!ok)
             return false;
     } else {
         if (!p->value.hasGen && !p->value.isSharp) {
@@ -701,20 +697,18 @@ obj_valueOf(JSContext *cx, unsigned argc
 }
 
 /* We should be able to assert this for *any* fp->scopeChain(). */
 static void
 AssertInnerizedScopeChain(JSContext *cx, JSObject &scopeobj)
 {
 #ifdef DEBUG
     for (JSObject *o = &scopeobj; o; o = o->enclosingScope()) {
-        if (JSObjectOp op = o->getClass()->ext.innerObject) {
-            Rooted<JSObject*> obj(cx, o);
-            JS_ASSERT(op(cx, obj) == o);
-        }
+        if (JSObjectOp op = o->getClass()->ext.innerObject)
+            JS_ASSERT(op(cx, RootedObject(cx, o)) == o);
     }
 #endif
 }
 
 #ifndef EVAL_CACHE_CHAIN_LIMIT
 # define EVAL_CACHE_CHAIN_LIMIT 4
 #endif
 
@@ -1085,21 +1079,19 @@ namespace js {
  * ES5 15.1.2.1.
  *
  * NB: This method handles only indirect eval.
  */
 JSBool
 eval(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (!WarnOnTooManyArgs(cx, args))
-        return false;
-
-    Rooted<GlobalObject*> global(cx, &args.callee().global());
-    return EvalKernel(cx, args, INDIRECT_EVAL, NULL, global);
+    return WarnOnTooManyArgs(cx, args) &&
+           EvalKernel(cx, args, INDIRECT_EVAL, NULL,
+                      RootedObject(cx, &args.callee().global()));
 }
 
 bool
 DirectEval(JSContext *cx, const CallArgs &args)
 {
     /* Direct eval can assume it was called from an interpreted frame. */
     StackFrame *caller = cx->fp();
     JS_ASSERT(caller->isScriptFrame());
@@ -1289,18 +1281,17 @@ js_HasOwnProperty(JSContext *cx, LookupG
     if (!*propp)
         return true;
 
     if (*objp == obj)
         return true;
 
     JSObject *outer = NULL;
     if (JSObjectOp op = (*objp)->getClass()->ext.outerObject) {
-        Rooted<JSObject*> inner(cx, *objp);
-        outer = op(cx, inner);
+        outer = op(cx, RootedObject(cx, *objp));
         if (!outer)
             return false;
     }
 
     if (outer != *objp)
         *propp = NULL;
     return true;
 }
@@ -1974,35 +1965,35 @@ DefinePropertyOnObject(JSContext *cx, Ha
         if (!obj->isExtensible())
             return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
 
         *rval = true;
 
         if (desc.isGenericDescriptor() || desc.isDataDescriptor()) {
             JS_ASSERT(!obj->getOps()->defineProperty);
             Value v = desc.hasValue() ? desc.value() : UndefinedValue();
-            return baseops::DefineGeneric(cx, obj, id, &v,
-                                          JS_PropertyStub, JS_StrictPropertyStub,
-                                          desc.attributes());
+            return baseops::DefineProperty(cx, obj, id, &v,
+                                           JS_PropertyStub, JS_StrictPropertyStub,
+                                           desc.attributes());
         }
 
         JS_ASSERT(desc.isAccessorDescriptor());
 
         /*
          * Getters and setters are just like watchpoints from an access
          * control point of view.
          */
         Value dummy;
         unsigned dummyAttrs;
         if (!CheckAccess(cx, obj, id, JSACC_WATCH, &dummy, &dummyAttrs))
             return JS_FALSE;
 
         Value tmp = UndefinedValue();
-        return baseops::DefineGeneric(cx, obj, id, &tmp,
-                                      desc.getter(), desc.setter(), desc.attributes());
+        return baseops::DefineProperty(cx, obj, id, &tmp,
+                                       desc.getter(), desc.setter(), desc.attributes());
     }
 
     /* 8.12.9 steps 5-6 (note 5 is merely a special case of 6). */
     Value v = UndefinedValue();
 
     JS_ASSERT(obj == obj2);
 
     Rooted<const Shape *> shape(cx, reinterpret_cast<Shape *>(current));
@@ -2242,17 +2233,17 @@ DefinePropertyOnObject(JSContext *cx, Ha
      * redefining it or we had invoked its setter to change its value).
      */
     if (callDelProperty) {
         Value dummy = UndefinedValue();
         if (!CallJSPropertyOp(cx, obj2->getClass()->delProperty, obj2, id, &dummy))
             return false;
     }
 
-    return baseops::DefineGeneric(cx, obj, id, &v, getter, setter, attrs);
+    return baseops::DefineProperty(cx, obj, id, &v, getter, setter, attrs);
 }
 
 static JSBool
 DefinePropertyOnArray(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc,
                       bool throwError, bool *rval)
 {
     /*
      * We probably should optimize dense array property definitions where
@@ -2386,17 +2377,17 @@ DefineProperties(JSContext *cx, HandleOb
 {
     AutoIdVector ids(cx);
     AutoPropDescArrayRooter descs(cx);
     if (!ReadPropertyDescriptors(cx, props, true, &ids, &descs))
         return false;
 
     bool dummy;
     for (size_t i = 0, len = ids.length(); i < len; i++) {
-        if (!DefineProperty(cx, obj, Handle<jsid>::fromMarkedLocation(&ids[i]), descs[i], true, &dummy))
+        if (!DefineProperty(cx, obj, RootedId(cx, ids[i]), descs[i], true, &dummy))
             return false;
     }
 
     return true;
 }
 
 extern JSBool
 js_PopulateObject(JSContext *cx, HandleObject newborn, JSObject *props)
@@ -3177,31 +3168,30 @@ JSObject::nonNativeSetElement(JSContext 
 bool
 JSObject::deleteByValue(JSContext *cx, const Value &property, Value *rval, bool strict)
 {
     uint32_t index;
     if (IsDefinitelyIndex(property, &index))
         return deleteElement(cx, index, rval, strict);
 
     Value propval = property;
-    Rooted<SpecialId> sid(cx);
-    if (ValueIsSpecial(this, &propval, sid.address(), cx))
-        return deleteSpecial(cx, sid, rval, strict);
+    SpecialId sid;
+    if (ValueIsSpecial(this, &propval, &sid, cx))
+        return deleteSpecial(cx, Rooted<SpecialId>(cx, sid), rval, strict);
 
     RootedObject self(cx, this);
 
     JSAtom *name = ToAtom(cx, propval);
     if (!name)
         return false;
 
     if (name->isIndex(&index))
         return self->deleteElement(cx, index, rval, false);
 
-    Rooted<PropertyName*> propname(cx, name->asPropertyName());
-    return self->deleteProperty(cx, propname, rval, false);
+    return self->deleteProperty(cx, RootedPropertyName(cx, name->asPropertyName()), rval, false);
 }
 
 JS_FRIEND_API(bool)
 JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj)
 {
     // If we're not native, then we cannot copy properties.
     JS_ASSERT(target->isNative() == obj->isNative());
     if (!target->isNative())
@@ -3222,18 +3212,17 @@ JS_CopyPropertiesFrom(JSContext *cx, JSO
         AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
         if ((attrs & JSPROP_GETTER) && !cx->compartment->wrap(cx, &getter))
             return false;
         if ((attrs & JSPROP_SETTER) && !cx->compartment->wrap(cx, &setter))
             return false;
         Value v = shape->hasSlot() ? obj->getSlot(shape->slot()) : UndefinedValue();
         if (!cx->compartment->wrap(cx, &v))
             return false;
-        Rooted<jsid> id(cx, shape->propid());
-        if (!target->defineGeneric(cx, id, v, getter, setter, attrs))
+        if (!target->defineGeneric(cx, RootedId(cx, shape->propid()), v, getter, setter, attrs))
             return false;
     }
     return true;
 }
 
 static bool
 CopySlots(JSContext *cx, JSObject *from, JSObject *to)
 {
@@ -3962,26 +3951,25 @@ JSObject::growSlots(JSContext *cx, uint3
      * by calling 'new' on a particular script, bump the GC kind for that
      * type to give these objects a larger number of fixed slots when future
      * objects are constructed.
      */
     if (!hasLazyType() && !oldCount && type()->newScript) {
         gc::AllocKind kind = type()->newScript->allocKind;
         unsigned newScriptSlots = gc::GetGCKindSlots(kind);
         if (newScriptSlots == numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
-            Rooted<TypeObject*> typeObj(cx, type());
-            JSObject *obj = NewReshapedObject(cx, typeObj,
+            JSObject *obj = NewReshapedObject(cx, RootedTypeObject(cx, type()),
                                               getParent(), kind,
-                                              typeObj->newScript->shape);
+                                              type()->newScript->shape);
             if (!obj)
                 return false;
 
-            typeObj->newScript->allocKind = kind;
-            typeObj->newScript->shape = obj->lastProperty();
-            typeObj->markStateChange(cx);
+            type()->newScript->allocKind = kind;
+            type()->newScript->shape = obj->lastProperty();
+            type()->markStateChange(cx);
         }
     }
 
     if (!oldCount) {
         slots = (HeapSlot *) cx->malloc_(newCount * sizeof(HeapSlot));
         if (!slots)
             return false;
         Debug_SetSlotRangeToCrashOnTouch(slots, newCount);
@@ -4483,34 +4471,34 @@ js_AddNativeProperty(JSContext *cx, Hand
      */
     if (!js_PurgeScopeChain(cx, obj, id))
         return NULL;
 
     return obj->putProperty(cx, id, getter, setter, slot, attrs, flags, shortid);
 }
 
 JSBool
-baseops::DefineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *value,
+baseops::DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const Value *value,
                         PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
 }
 
 JSBool
 baseops::DefineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *value,
                        PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx);
     if (index <= JSID_INT_MAX) {
-        id = INT_TO_JSID(index);
-        return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
+        return !!DefineNativeProperty(cx, obj, RootedId(cx, INT_TO_JSID(index)), *value,
+                                      getter, setter, attrs, 0, 0);
     }
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
+    RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
 
     return !!DefineNativeProperty(cx, obj, id, *value, getter, setter, attrs, 0, 0);
 }
 
 /*
  * Backward compatibility requires allowing addProperty hooks to mutate the
@@ -4519,18 +4507,17 @@ baseops::DefineElement(JSContext *cx, Ha
  * both while saving cycles for classes that stub their addProperty hook.
  */
 static inline bool
 CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape shape, Value *vp)
 {
     if (clasp->addProperty != JS_PropertyStub) {
         Value nominal = *vp;
 
-        Rooted<jsid> id(cx, shape->propid());
-        if (!CallJSPropertyOp(cx, clasp->addProperty, obj, id, vp))
+        if (!CallJSPropertyOp(cx, clasp->addProperty, obj, RootedId(cx, shape->propid()), vp))
             return false;
         if (*vp != nominal) {
             if (shape->hasSlot())
                 obj->nativeSetSlotWithType(cx, shape, *vp);
         }
     }
     return true;
 }
@@ -4973,17 +4960,17 @@ js::FindIdentifierBase(JSContext *cx, Ha
         if (!parent)
             break;
         obj = parent;
     } while (!obj->isGlobal());
     return obj;
 }
 
 static JS_ALWAYS_INLINE JSBool
-js_NativeGetInline(JSContext *cx, Handle<JSObject*> receiver, JSObject *obj, JSObject *pobj,
+js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *pobj,
                    const Shape *shape, unsigned getHow, Value *vp)
 {
     JS_ASSERT(pobj->isNative());
 
     if (shape->hasSlot()) {
         *vp = pobj->nativeGetSlot(shape->slot());
         JS_ASSERT(!vp->isMagic());
         JS_ASSERT_IF(!pobj->hasSingletonType() && shape->hasDefaultGetter(),
@@ -5000,36 +4987,35 @@ js_NativeGetInline(JSContext *cx, Handle
         analyze::Bytecode *code = script->analysis()->maybeCode(pc);
         if (code)
             code->accessGetter = true;
     }
 
     Rooted<const Shape*> shapeRoot(cx, shape);
     RootedObject pobjRoot(cx, pobj);
 
-    if (!shape->get(cx, receiver, obj, pobj, vp))
+    if (!shape->get(cx, RootedObject(cx, receiver), obj, pobj, vp))
         return false;
 
     /* Update slotful shapes according to the value produced by the getter. */
     if (shapeRoot->hasSlot() && pobjRoot->nativeContains(cx, *shapeRoot))
         pobjRoot->nativeSetSlot(shapeRoot->slot(), *vp);
 
     return true;
 }
 
 JSBool
-js_NativeGet(JSContext *cx, Handle<JSObject*> obj, Handle<JSObject*> pobj, const Shape *shape,
-             unsigned getHow, Value *vp)
+js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, unsigned getHow,
+             Value *vp)
 {
     return js_NativeGetInline(cx, obj, obj, pobj, shape, getHow, vp);
 }
 
 JSBool
-js_NativeSet(JSContext *cx, Handle<JSObject*> obj, const Shape *shape, bool added, bool strict,
-             Value *vp)
+js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool strict, Value *vp)
 {
     AddTypePropertyId(cx, obj, shape->propid(), *vp);
 
     JS_ASSERT(obj->isNative());
 
     if (shape->hasSlot()) {
         uint32_t slot = shape->slot();
 
@@ -5047,17 +5033,17 @@ js_NativeSet(JSContext *cx, Handle<JSObj
          */
         if (!shape->hasGetterValue() && shape->hasDefaultSetter())
             return js_ReportGetterOnlyAssignment(cx);
     }
 
     Rooted<const Shape *> shapeRoot(cx, shape);
 
     int32_t sample = cx->runtime->propertyRemovals;
-    if (!shapeRoot->set(cx, obj, strict, vp))
+    if (!shapeRoot->set(cx, RootedObject(cx, obj), strict, vp))
         return false;
 
     /*
      * Update any slot for the shape with the value produced by the setter,
      * unless the setter deleted the shape.
      */
     if (shapeRoot->hasSlot() &&
         (JS_LIKELY(cx->runtime->propertyRemovals == sample) ||
@@ -5265,19 +5251,18 @@ JSObject::reportNotExtensible(JSContext 
                                     JSDVG_IGNORE_STACK, ObjectValue(*this),
                                     NULL, NULL, NULL);
 }
 
 bool
 JSObject::callMethod(JSContext *cx, HandleId id, unsigned argc, Value *argv, Value *vp)
 {
     Value fval;
-    Rooted<JSObject*> obj(cx, this);
-    return GetMethod(cx, obj, id, 0, &fval) &&
-           Invoke(cx, ObjectValue(*obj), fval, argc, argv, vp);
+    return GetMethod(cx, RootedObject(cx, this), id, 0, &fval) &&
+           Invoke(cx, ObjectValue(*this), fval, argc, argv, vp);
 }
 
 JSBool
 baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleId id, unsigned defineHow,
                            Value *vp, JSBool strict)
 {
     JSObject *pobj;
     JSProperty *prop;
@@ -5578,34 +5563,32 @@ baseops::DeleteGeneric(JSContext *cx, Ha
         return true;
 
     return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
 }
 
 JSBool
 baseops::DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return baseops::DeleteGeneric(cx, obj, id, rval, strict);
+    return baseops::DeleteGeneric(cx, obj, RootedId(cx, NameToId(name)), rval, strict);
 }
 
 JSBool
 baseops::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, Value *rval, JSBool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return baseops::DeleteGeneric(cx, obj, id, rval, strict);
 }
 
 JSBool
 baseops::DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return baseops::DeleteGeneric(cx, obj, id, rval, strict);
+    return baseops::DeleteGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), rval, strict);
 }
 
 namespace js {
 
 bool
 HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp)
 {
     if (const Shape *shape = obj->nativeLookup(cx, id)) {
@@ -5622,87 +5605,78 @@ HasDataProperty(JSContext *cx, HandleObj
  * Gets |obj[id]|.  If that value's not callable, returns true and stores a
  * non-primitive value in *vp.  If it's callable, calls it with no arguments
  * and |obj| as |this|, returning the result in *vp.
  *
  * This is a mini-abstraction for ES5 8.12.8 [[DefaultValue]], either steps 1-2
  * or steps 3-4.
  */
 static bool
-MaybeCallMethod(JSContext *cx, HandleObject obj, Handle<jsid> id, Value *vp)
-{
-    if (!GetMethod(cx, obj, id, 0, vp))
+MaybeCallMethod(JSContext *cx, HandleObject obj, jsid id, Value *vp)
+{
+    if (!GetMethod(cx, obj, RootedId(cx, id), 0, vp))
         return false;
     if (!js_IsCallable(*vp)) {
         *vp = ObjectValue(*obj);
         return true;
     }
     return Invoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp);
 }
 
 JSBool
 DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
 {
     JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
 #if JS_HAS_XML_SUPPORT
     JS_ASSERT(!obj->isXML());
 #endif
 
-    Rooted<jsid> id(cx);
-
     Class *clasp = obj->getClass();
     if (hint == JSTYPE_STRING) {
-        id = NameToId(cx->runtime->atomState.toStringAtom);
-
         /* Optimize (new String(...)).toString(). */
-        if (clasp == &StringClass) {
-            if (ClassMethodIsNative(cx, obj, &StringClass, id, js_str_toString)) {
-                *vp = StringValue(obj->asString().unbox());
-                return true;
-            }
+        if (clasp == &StringClass &&
+            ClassMethodIsNative(cx, obj,
+                                 &StringClass,
+                                 RootedId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
+                                 js_str_toString)) {
+            *vp = StringValue(obj->asString().unbox());
+            return true;
         }
 
-        if (!MaybeCallMethod(cx, obj, id, vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.toStringAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
-        id = NameToId(cx->runtime->atomState.valueOfAtom);
-        if (!MaybeCallMethod(cx, obj, id, 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) {
-            id = NameToId(cx->runtime->atomState.valueOfAtom);
-            if (ClassMethodIsNative(cx, obj, &StringClass, id, js_str_toString)) {
-                *vp = StringValue(obj->asString().unbox());
-                return true;
-            }
+        /* Optimize (new String(...)).valueOf(). */
+        if ((clasp == &StringClass &&
+             ClassMethodIsNative(cx, obj, &StringClass,
+                                 RootedId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
+                                 js_str_toString)) ||
+            (clasp == &NumberClass &&
+             ClassMethodIsNative(cx, obj, &NumberClass,
+                                 RootedId(cx, NameToId(cx->runtime->atomState.valueOfAtom)),
+                                 js_num_valueOf))) {
+            *vp = obj->isString()
+                  ? StringValue(obj->asString().unbox())
+                  : NumberValue(obj->asNumber().unbox());
+            return true;
         }
 
-        /* Optimize new Number(...).valueOf(). */
-        if (clasp == &NumberClass) {
-            id = NameToId(cx->runtime->atomState.valueOfAtom);
-            if (ClassMethodIsNative(cx, obj, &NumberClass, id, js_num_valueOf)) {
-                *vp = NumberValue(obj->asNumber().unbox());
-                return true;
-            }
-        }
-
-        id = NameToId(cx->runtime->atomState.valueOfAtom);
-        if (!MaybeCallMethod(cx, obj, id, vp))
+        if (!MaybeCallMethod(cx, obj, NameToId(cx->runtime->atomState.valueOfAtom), vp))
             return false;
         if (vp->isPrimitive())
             return true;
 
-        id = NameToId(cx->runtime->atomState.toStringAtom);
-        if (!MaybeCallMethod(cx, obj, id, 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) {
@@ -5889,20 +5863,18 @@ js_GetClassPrototype(JSContext *cx, JSOb
     }
 
     return FindClassPrototype(cx, scopeobj, protoKey, protop, clasp);
 }
 
 JSObject *
 PrimitiveToObject(JSContext *cx, const Value &v)
 {
-    if (v.isString()) {
-        Rooted<JSString*> str(cx, v.toString());
-        return StringObject::create(cx, str);
-    }
+    if (v.isString())
+        return StringObject::create(cx, RootedString(cx, v.toString()));
     if (v.isNumber())
         return NumberObject::create(cx, v.toNumber());
 
     JS_ASSERT(v.isBoolean());
     return BooleanObject::create(cx, v.toBoolean());
 }
 
 JSBool
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -100,36 +100,27 @@ namespace baseops {
 extern JS_FRIEND_API(JSBool)
 LookupProperty(JSContext *cx, HandleObject obj, HandleId id, JSObject **objp,
                JSProperty **propp);
 
 inline bool
 LookupProperty(JSContext *cx, HandleObject obj, PropertyName *name,
                JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return LookupProperty(cx, obj, id, objp, propp);
+    return LookupProperty(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 extern JS_FRIEND_API(JSBool)
 LookupElement(JSContext *cx, HandleObject obj, uint32_t index,
               JSObject **objp, JSProperty **propp);
 
 extern JSBool
-DefineGeneric(JSContext *cx, HandleObject obj, HandleId id, const js::Value *value,
+DefineProperty(JSContext *cx, HandleObject obj, HandleId id, const js::Value *value,
                JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
 
-inline JSBool
-DefineProperty(JSContext *cx, HandleObject obj, PropertyName *name, const js::Value *value,
-               JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
-{
-    Rooted<jsid> id(cx, NameToId(name));
-    return DefineGeneric(cx, obj, id, value, getter, setter, attrs);
-}
-
 extern JSBool
 DefineElement(JSContext *cx, HandleObject obj, uint32_t index, const js::Value *value,
               JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
 
 extern JSBool
 GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, js::Value *vp);
 
 extern JSBool
@@ -153,18 +144,17 @@ GetPropertyDefault(JSContext *cx, Handle
 extern JSBool
 SetPropertyHelper(JSContext *cx, HandleObject obj, HandleId id, unsigned defineHow,
                   Value *vp, JSBool strict);
 
 inline bool
 SetPropertyHelper(JSContext *cx, HandleObject obj, PropertyName *name, unsigned defineHow,
                   Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return SetPropertyHelper(cx, obj, id, defineHow, vp, strict);
+    return SetPropertyHelper(cx, obj, RootedId(cx, NameToId(name)), defineHow, vp, strict);
 }
 
 extern JSBool
 SetElementHelper(JSContext *cx, HandleObject obj, uint32_t index, unsigned defineHow,
                  Value *vp, JSBool strict);
 
 extern JSType
 TypeOf(JSContext *cx, HandleObject obj);
@@ -1146,34 +1136,33 @@ 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)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, flags,
+    return DefineNativeProperty(cx, obj, RootedId(cx, NameToId(name)),
+                                value, getter, setter, attrs, flags,
                                 shortid, defineHow);
 }
 
 /*
  * Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
  */
 extern bool
 LookupPropertyWithFlags(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
                         JSObject **objp, JSProperty **propp);
 
 inline bool
 LookupPropertyWithFlags(JSContext *cx, HandleObject obj, PropertyName *name, unsigned flags,
                         JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return LookupPropertyWithFlags(cx, obj, id, flags, objp, propp);
+    return LookupPropertyWithFlags(cx, obj, RootedId(cx, 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.
@@ -1227,21 +1216,21 @@ const unsigned JSGET_CACHE_RESULT = 1; /
 
 /*
  * NB: js_NativeGet and js_NativeSet are called with the scope containing shape
  * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
  * scope is again locked.  But on failure, both functions return false with the
  * scope containing shape unlocked.
  */
 extern JSBool
-js_NativeGet(JSContext *cx, js::Handle<JSObject*> obj, js::Handle<JSObject*> pobj,
-             const js::Shape *shape, unsigned getHow, js::Value *vp);
+js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const js::Shape *shape, unsigned getHow,
+             js::Value *vp);
 
 extern JSBool
-js_NativeSet(JSContext *cx, js::Handle<JSObject*> obj, const js::Shape *shape, bool added,
+js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
              bool strict, js::Value *vp);
 
 namespace js {
 
 bool
 GetPropertyHelper(JSContext *cx, HandleObject obj, jsid id, uint32_t getHow, Value *vp);
 
 inline bool
@@ -1260,18 +1249,17 @@ bool
 NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value *vp);
 
 extern JSBool
 GetMethod(JSContext *cx, HandleObject obj, HandleId id, unsigned getHow, Value *vp);
 
 inline bool
 GetMethod(JSContext *cx, HandleObject obj, PropertyName *name, unsigned getHow, Value *vp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return GetMethod(cx, obj, id, getHow, vp);
+    return GetMethod(cx, obj, RootedId(cx, NameToId(name)), getHow, vp);
 }
 
 /*
  * If obj has an already-resolved data property for id, return true and
  * store the property value in *vp.
  */
 extern bool
 HasDataProperty(JSContext *cx, HandleObject obj, jsid id, Value *vp);
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -49,18 +49,17 @@
 #include "vm/ObjectImpl-inl.h"
 #include "vm/RegExpStatics-inl.h"
 #include "vm/String-inl.h"
 
 inline bool
 JSObject::enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp)
 {
     JSNewEnumerateOp op = getOps()->enumerate;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : JS_EnumerateState)(cx, obj, iterop, statep, idp);
+    return (op ? op : JS_EnumerateState)(cx, js::RootedObject(cx, this), iterop, statep, idp);
 }
 
 inline bool
 JSObject::defaultValue(JSContext *cx, JSType hint, js::Value *vp)
 {
     js::RootedObject self(cx, this);
 
     JSConvertOp op = getClass()->convert;
@@ -72,89 +71,81 @@ JSObject::defaultValue(JSContext *cx, JS
     JS_ASSERT_IF(ok, vp->isPrimitive());
     return ok;
 }
 
 inline JSType
 JSObject::typeOf(JSContext *cx)
 {
     js::TypeOfOp op = getOps()->typeOf;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::TypeOf)(cx, obj);
+    return (op ? op : js::baseops::TypeOf)(cx, js::RootedObject(cx, this));
 }
 
 inline JSObject *
 JSObject::thisObject(JSContext *cx)
 {
     JSObjectOp op = getOps()->thisObject;
-    js::Rooted<JSObject*> obj(cx, this);
-    return op ? op(cx, obj) : this;
+    return op ? op(cx, js::RootedObject(cx, this)) : this;
 }
 
 inline JSBool
 JSObject::setGeneric(JSContext *cx, js::HandleId id, js::Value *vp, JSBool strict)
 {
     if (getOps()->setGeneric)
         return nonNativeSetProperty(cx, id, vp, strict);
-    js::Rooted<JSObject*> obj(cx, this);
-    return js::baseops::SetPropertyHelper(cx, obj, id, 0, vp, strict);
+    return js::baseops::SetPropertyHelper(cx,
+                                          js::RootedObject(cx, this),
+                                          id, 0, vp, strict);
 }
 
 inline JSBool
 JSObject::setProperty(JSContext *cx, js::PropertyName *name, js::Value *vp, JSBool strict)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return setGeneric(cx, id, vp, strict);
+    return setGeneric(cx, js::RootedId(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);
-    js::Rooted<JSObject*> obj(cx, this);
-    return js::baseops::SetElementHelper(cx, obj, index, 0, vp, strict);
+    return js::baseops::SetElementHelper(cx, js::RootedObject(cx, this), index, 0, vp, strict);
 }
 
 inline JSBool
 JSObject::setSpecial(JSContext *cx, js::SpecialId sid, js::Value *vp, JSBool strict)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return setGeneric(cx, id, vp, strict);
+    return setGeneric(cx, js::RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
 }
 
 inline JSBool
 JSObject::setGenericAttributes(JSContext *cx, js::HandleId id, unsigned *attrsp)
 {
     js::types::MarkTypePropertyConfigured(cx, this, id);
     js::GenericAttributesOp op = getOps()->setGenericAttributes;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::SetAttributes)(cx, obj, id, attrsp);
+    return (op ? op : js::baseops::SetAttributes)(cx, js::RootedObject(cx, this), id, attrsp);
 }
 
 inline JSBool
 JSObject::setPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return setGenericAttributes(cx, id, attrsp);
+    return setGenericAttributes(cx, js::RootedId(cx, js::NameToId(name)), attrsp);
 }
 
 inline JSBool
 JSObject::setElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
 {
     js::ElementAttributesOp op = getOps()->setElementAttributes;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::SetElementAttributes)(cx, obj, index, attrsp);
+    return (op ? op : js::baseops::SetElementAttributes)(cx, js::RootedObject(cx, this), index, attrsp);
 }
 
 inline JSBool
 JSObject::setSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return setGenericAttributes(cx, id, attrsp);
+    return setGenericAttributes(cx, js::RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 inline bool
 JSObject::changePropertyAttributes(JSContext *cx, js::Shape *shape, unsigned attrs)
 {
     return !!changeProperty(cx, shape, attrs, 0, shape->getter(), shape->setter());
 }
 
@@ -172,43 +163,39 @@ JSObject::getGeneric(JSContext *cx, js::
             return false;
     }
     return true;
 }
 
 inline JSBool
 JSObject::getProperty(JSContext *cx, js::HandleObject receiver, js::PropertyName *name, js::Value *vp)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return getGeneric(cx, receiver, id, vp);
+    return getGeneric(cx, receiver, js::RootedId(cx, js::NameToId(name)), vp);
 }
 
 inline JSBool
 JSObject::getGeneric(JSContext *cx, js::HandleId id, js::Value *vp)
 {
-    js::Rooted<JSObject*> obj(cx, this);
-    return getGeneric(cx, obj, id, vp);
+    return getGeneric(cx, js::RootedObject(cx, this), id, vp);
 }
 
 inline JSBool
 JSObject::getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return getGeneric(cx, id, vp);
+    return getGeneric(cx, js::RootedId(cx, js::NameToId(name)), vp);
 }
 
 inline bool
 JSObject::deleteProperty(JSContext *cx, js::HandlePropertyName name, js::Value *rval, bool strict)
 {
     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;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::DeleteProperty)(cx, obj, name, rval, strict);
+    return (op ? op : js::baseops::DeleteProperty)(cx, js::RootedObject(cx, this), name, rval, strict);
 }
 
 inline bool
 JSObject::deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict)
 {
     js::RootedObject self(cx, this);
 
     jsid id;
@@ -222,18 +209,17 @@ JSObject::deleteElement(JSContext *cx, u
 
 inline bool
 JSObject::deleteSpecial(JSContext *cx, js::HandleSpecialId sid, js::Value *rval, bool strict)
 {
     jsid id = SPECIALID_TO_JSID(sid);
     js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
     js::types::MarkTypePropertyConfigured(cx, this, id);
     js::DeleteSpecialOp op = getOps()->deleteSpecial;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::DeleteSpecial)(cx, obj, sid, rval, strict);
+    return (op ? op : js::baseops::DeleteSpecial)(cx, js::RootedObject(cx, this), sid, rval, strict);
 }
 
 inline void
 JSObject::finalize(js::FreeOp *fop)
 {
     js::Probes::finalizeObject(this);
 
     if (!fop->onBackgroundThread()) {
@@ -1035,41 +1021,39 @@ JSObject::lookupGeneric(JSContext *cx, j
     if (op)
         return op(cx, self, id, objp, propp);
     return js::baseops::LookupProperty(cx, self, id, objp, propp);
 }
 
 inline JSBool
 JSObject::lookupProperty(JSContext *cx, js::PropertyName *name, JSObject **objp, JSProperty **propp)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return lookupGeneric(cx, id, objp, propp);
+    return lookupGeneric(cx, js::RootedId(cx, js::NameToId(name)), objp, propp);
 }
 
 inline JSBool
 JSObject::defineGeneric(JSContext *cx, js::HandleId id, const js::Value &value,
                         JSPropertyOp getter /* = JS_PropertyStub */,
                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
                         unsigned attrs /* = JSPROP_ENUMERATE */)
 {
     js::RootedObject self(cx, this);
 
     JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
     js::DefineGenericOp op = getOps()->defineGeneric;
-    return (op ? op : js::baseops::DefineGeneric)(cx, self, id, &value, getter, setter, attrs);
+    return (op ? op : js::baseops::DefineProperty)(cx, self, id, &value, getter, setter, attrs);
 }
 
 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 */)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return defineGeneric(cx, id, value, getter, setter, attrs);
+    return defineGeneric(cx, js::RootedId(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 */)
 {
@@ -1080,34 +1064,32 @@ JSObject::defineElement(JSContext *cx, u
 }
 
 inline JSBool
 JSObject::defineSpecial(JSContext *cx, js::SpecialId sid, const js::Value &value,
                         JSPropertyOp getter /* = JS_PropertyStub */,
                         JSStrictPropertyOp setter /* = JS_StrictPropertyStub */,
                         unsigned attrs /* = JSPROP_ENUMERATE */)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return defineGeneric(cx, id, value, getter, setter, attrs);
+    return defineGeneric(cx, js::RootedId(cx, SPECIALID_TO_JSID(sid)), value, getter, setter, attrs);
 }
 
 inline JSBool
 JSObject::lookupElement(JSContext *cx, uint32_t index, JSObject **objp, JSProperty **propp)
 {
     js::RootedObject self(cx, this);
 
     js::LookupElementOp op = getOps()->lookupElement;
     return (op ? op : js::baseops::LookupElement)(cx, self, index, objp, propp);
 }
 
 inline JSBool
 JSObject::lookupSpecial(JSContext *cx, js::SpecialId sid, JSObject **objp, JSProperty **propp)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return lookupGeneric(cx, id, objp, propp);
+    return lookupGeneric(cx, js::RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 inline JSBool
 JSObject::getElement(JSContext *cx, js::HandleObject receiver, uint32_t index, js::Value *vp)
 {
     js::RootedObject self(cx, this);
 
     js::ElementIdOp op = getOps()->getElement;
@@ -1118,18 +1100,17 @@ JSObject::getElement(JSContext *cx, js::
     if (!js::IndexToId(cx, index, id.address()))
         return false;
     return self->getGeneric(cx, receiver, id, vp);
 }
 
 inline JSBool
 JSObject::getElement(JSContext *cx, uint32_t index, js::Value *vp)
 {
-    js::Rooted<JSObject*> obj(cx, this);
-    return getElement(cx, obj, index, vp);
+    return getElement(cx, js::RootedObject(cx, this), index, vp);
 }
 
 inline JSBool
 JSObject::getElementIfPresent(JSContext *cx, js::HandleObject receiver, uint32_t index, js::Value *vp,
                               bool *present)
 {
     js::RootedObject self(cx, this);
 
@@ -1159,49 +1140,45 @@ JSObject::getElementIfPresent(JSContext 
 
     *present = true;
     return self->getGeneric(cx, receiver, id, vp);
 }
 
 inline JSBool
 JSObject::getSpecial(JSContext *cx, js::HandleObject receiver, js::SpecialId sid, js::Value *vp)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return getGeneric(cx, receiver, id, vp);
+    return getGeneric(cx, receiver, js::RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 inline JSBool
 JSObject::getGenericAttributes(JSContext *cx, js::HandleId id, unsigned *attrsp)
 {
     js::GenericAttributesOp op = getOps()->getGenericAttributes;
-    js::Rooted<JSObject*> obj(cx, this);
-    return (op ? op : js::baseops::GetAttributes)(cx, obj, id, attrsp);
+    return (op ? op : js::baseops::GetAttributes)(cx, js::RootedObject(cx, this), id, attrsp);
 }
 
 inline JSBool
 JSObject::getPropertyAttributes(JSContext *cx, js::PropertyName *name, unsigned *attrsp)
 {
-    js::Rooted<jsid> id(cx, js::NameToId(name));
-    return getGenericAttributes(cx, id, attrsp);
+    return getGenericAttributes(cx, js::RootedId(cx, js::NameToId(name)), attrsp);
 }
 
 inline JSBool
 JSObject::getElementAttributes(JSContext *cx, uint32_t index, unsigned *attrsp)
 {
     js::RootedId id(cx);
     if (!js::IndexToId(cx, index, id.address()))
         return false;
     return getGenericAttributes(cx, id, attrsp);
 }
 
 inline JSBool
 JSObject::getSpecialAttributes(JSContext *cx, js::SpecialId sid, unsigned *attrsp)
 {
-    js::Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return getGenericAttributes(cx, id, attrsp);
+    return getGenericAttributes(cx, js::RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 inline bool
 JSObject::isProxy() const
 {
     return js::IsProxy(this);
 }
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -275,18 +275,17 @@ static bool
 PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, StringifyContext *scx)
 {
     JSString *keyStr = NULL;
 
     /* Step 2. */
     if (vp->isObject()) {
         Value toJSON;
         RootedId id(cx, NameToId(cx->runtime->atomState.toJSONAtom));
-        Rooted<JSObject*> obj(cx, &vp->toObject());
-        if (!GetMethod(cx, obj, id, 0, &toJSON))
+        if (!GetMethod(cx, RootedObject(cx, &vp->toObject()), id, 0, &toJSON))
             return false;
 
         if (js_IsCallable(toJSON)) {
             keyStr = KeyStringifier<KeyType>::toString(cx, key);
             if (!keyStr)
                 return false;
 
             InvokeArgsGuard args;
@@ -851,18 +850,17 @@ Revive(JSContext *cx, const Value &reviv
 {
     RootedObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass));
     if (!obj)
         return false;
 
     if (!obj->defineProperty(cx, cx->runtime->atomState.emptyAtom, *vp))
         return false;
 
-    Rooted<jsid> id(cx, NameToId(cx->runtime->atomState.emptyAtom));
-    return Walk(cx, obj, id, reviver, vp);
+    return Walk(cx, obj, RootedId(cx, 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 */)
 {
--- a/js/src/jsonparser.cpp
+++ b/js/src/jsonparser.cpp
@@ -544,18 +544,17 @@ JSONParser::parse(Value *vp)
             if (token == OOM)
                 return false;
             if (token != Error)
                 error("property names must be double-quoted strings");
             return errorReturn();
 
           case FinishArrayElement: {
             Value v = valueStack.popCopy();
-            Rooted<JSObject*> obj(cx, &valueStack.back().toObject());
-            if (!js_NewbornArrayPush(cx, obj, v))
+            if (!js_NewbornArrayPush(cx, RootedObject(cx, &valueStack.back().toObject()), v))
                 return false;
             token = advanceAfterArrayElement();
             if (token == Comma) {
                 if (!stateStack.append(FinishArrayElement))
                     return false;
                 goto JSONValue;
             }
             if (token == ArrayClose)
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -305,18 +305,17 @@ BaseProxyHandler::regexp_toShared(JSCont
     JS_NOT_REACHED("This should have been a wrapped regexp");
     return false;
 }
 
 bool
 BaseProxyHandler::defaultValue(JSContext *cx, JSObject *proxy, JSType hint,
                                Value *vp)
 {
-    Rooted<JSObject*> obj(cx, proxy);
-    return DefaultValue(cx, obj, hint, vp);
+    return DefaultValue(cx, RootedObject(cx, proxy), hint, vp);
 }
 
 bool
 BaseProxyHandler::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp)
 {
     vp->setMagic(JS_NO_ITER_VALUE);
     return true;
 }
@@ -393,24 +392,24 @@ IndirectProxyHandler::getOwnPropertyDesc
                                                jsid id, bool set,
                                                PropertyDescriptor *desc)
 {
     return GetOwnPropertyDescriptor(cx, GetProxyTargetObject(proxy), id,
                                     JSRESOLVE_QUALIFIED, desc);
 }
 
 bool
-IndirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
+IndirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id,
                                      PropertyDescriptor *desc)
 {
     RootedObject obj(cx, GetProxyTargetObject(proxy));
-    Rooted<jsid> id(cx, id_);
-    Rooted<Value> v(cx, desc->value);
-    return CheckDefineProperty(cx, obj, id, v, desc->getter, desc->setter, desc->attrs) &&
-           JS_DefinePropertyById(cx, obj, id, v, desc->getter, desc->setter, desc->attrs);
+    return CheckDefineProperty(cx, obj, RootedId(cx, id), RootedValue(cx, desc->value),
+                               desc->getter, desc->setter, desc->attrs) &&
+           JS_DefinePropertyById(cx, obj, id, desc->value, desc->getter, desc->setter,
+                                 desc->attrs);
 }
 
 bool
 IndirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                           AutoIdVector &props)
 {
     return GetPropertyNames(cx, GetProxyTargetObject(proxy),
                             JSITER_OWNONLY | JSITER_HIDDEN, &props);
@@ -519,35 +518,35 @@ IndirectProxyHandler::defaultValue(JSCon
     if (hint == JSTYPE_VOID)
         return ToPrimitive(cx, vp);
     return ToPrimitive(cx, hint, vp);
 }
 
 bool
 IndirectProxyHandler::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp)
 {
-    Rooted<JSObject*> target(cx, GetProxyTargetObject(proxy));
-    if (!js_IteratorMore(cx, target, vp))
+    if (!js_IteratorMore(cx, RootedObject(cx, GetProxyTargetObject(proxy)),
+                         vp))
         return false;
     if (vp->toBoolean()) {
         *vp = cx->iterValue;
-        cx->iterValue = UndefinedValue();
-    } else {
-        *vp = MagicValue(JS_NO_ITER_VALUE);
-    }
+        cx->iterValue.setUndefined();
+    } else
+        vp->setMagic(JS_NO_ITER_VALUE);
     return true;
 }
 
-DirectProxyHandler::DirectProxyHandler(void *family)
-  : IndirectProxyHandler(family)
+DirectProxyHandler::DirectProxyHandler(void *family) :
+        IndirectProxyHandler(family)
 {
 }
 
 bool
-DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
+DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id,
+                        bool *bp)
 {
     JSBool found;
     if (!JS_HasPropertyById(cx, GetProxyTargetObject(proxy), id, &found))
         return false;
     *bp = !!found;
     return true;
 }
 
@@ -586,27 +585,26 @@ DirectProxyHandler::keys(JSContext *cx, 
     return GetPropertyNames(cx, GetProxyTargetObject(proxy), JSITER_OWNONLY,
                             &props);
 }
 
 bool
 DirectProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags,
                             Value *vp)
 {
-    Rooted<JSObject*> target(cx, GetProxyTargetObject(proxy));
-    return GetIterator(cx, target, flags, vp);
+    return GetIterator(cx, RootedObject(cx, GetProxyTargetObject(proxy)),
+                       flags, vp);
 }
 
 static bool
 GetTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
 {
     JS_CHECK_RECURSION(cx, return false);
 
-    Rooted<PropertyName*> propname(cx, name);
-    return handler->getProperty(cx, propname, fvalp);
+    return handler->getGeneric(cx, RootedId(cx, NameToId(name)), fvalp);
 }
 
 static bool
 GetFundamentalTrap(JSContext *cx, JSObject *handler, PropertyName *name, Value *fvalp)
 {
     if (!GetTrap(cx, handler, name, fvalp))
         return false;
 
@@ -1240,35 +1238,33 @@ proxy_LookupGeneric(JSContext *cx, Handl
     }
     return true;
 }
 
 static JSBool
 proxy_LookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject **objp,
                      JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_LookupGeneric(cx, obj, id, objp, propp);
+    return proxy_LookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 static JSBool
 proxy_LookupElement(JSContext *cx, HandleObject obj, uint32_t index, JSObject **objp,
                     JSProperty **propp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_LookupGeneric(cx, obj, id, objp, propp);
 }
 
 static JSBool
 proxy_LookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_LookupGeneric(cx, obj, id, objp, propp);
+    return proxy_LookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 static JSBool
 proxy_DefineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     AutoPropertyDescriptorRooter desc(cx);
     desc.obj = obj;
@@ -1279,49 +1275,47 @@ proxy_DefineGeneric(JSContext *cx, Handl
     desc.shortid = 0;
     return Proxy::defineProperty(cx, obj, id, &desc);
 }
 
 static JSBool
 proxy_DefineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, const Value *value,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_DefineGeneric(cx, obj, id, value, getter, setter, attrs);
+    return proxy_DefineGeneric(cx, obj, RootedId(cx, NameToId(name)), value, getter, setter, attrs);
 }
 
 static JSBool
 proxy_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_DefineGeneric(cx, obj, id, value, getter, setter, attrs);
 }
 
 static JSBool
 proxy_DefineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *value,
                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_DefineGeneric(cx, obj, id, value, getter, setter, attrs);
+    return proxy_DefineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)),
+                               value, getter, setter, attrs);
 }
 
 static JSBool
 proxy_GetGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, Value *vp)
 {
     return Proxy::get(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 proxy_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, Value *vp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_GetGeneric(cx, obj, receiver, id, vp);
+    return proxy_GetGeneric(cx, obj, receiver, RootedId(cx, NameToId(name)), vp);
 }
 
 static JSBool
 proxy_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, Value *vp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
@@ -1333,148 +1327,139 @@ proxy_GetElementIfPresent(JSContext *cx,
                           Value *vp, bool *present)
 {
     return Proxy::getElementIfPresent(cx, obj, receiver, index, vp, present);
 }
 
 static JSBool
 proxy_GetSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid, Value *vp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_GetGeneric(cx, obj, receiver, id, vp);
+    return proxy_GetGeneric(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 static JSBool
 proxy_SetGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool strict)
 {
     return Proxy::set(cx, obj, obj, id, strict, vp);
 }
 
 static JSBool
 proxy_SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_SetGeneric(cx, obj, id, vp, strict);
+    return proxy_SetGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
 }
 
 static JSBool
 proxy_SetElement(JSContext *cx, HandleObject obj, uint32_t index, Value *vp, JSBool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_SetGeneric(cx, obj, id, vp, strict);
 }
 
 static JSBool
 proxy_SetSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_SetGeneric(cx, obj, id, vp, strict);
+    return proxy_SetGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
 }
 
 static JSBool
 proxy_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     AutoPropertyDescriptorRooter desc(cx);
     if (!Proxy::getOwnPropertyDescriptor(cx, obj, id, false, &desc))
         return false;
     *attrsp = desc.attrs;
     return true;
 }
 
 static JSBool
 proxy_GetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_GetGenericAttributes(cx, obj, id, attrsp);
+    return proxy_GetGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 static JSBool
 proxy_GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_GetGenericAttributes(cx, obj, id, attrsp);
 }
 
 static JSBool
 proxy_GetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_GetGenericAttributes(cx, obj, id, attrsp);
+    return proxy_GetGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 static JSBool
 proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     /* 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, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_SetGenericAttributes(cx, obj, id, attrsp);
+    return proxy_SetGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 static JSBool
 proxy_SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_SetGenericAttributes(cx, obj, id, attrsp);
 }
 
 static JSBool
 proxy_SetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_SetGenericAttributes(cx, obj, id, attrsp);
+    return proxy_SetGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 static JSBool
 proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *rval, JSBool strict)
 {
     // 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, HandleObject obj, HandlePropertyName name, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return proxy_DeleteGeneric(cx, obj, id, rval, strict);
+    return proxy_DeleteGeneric(cx, obj, RootedId(cx, NameToId(name)), rval, strict);
 }
 
 static JSBool
 proxy_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, Value *rval, JSBool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_DeleteGeneric(cx, obj, id, rval, strict);
 }
 
 static JSBool
 proxy_DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return proxy_DeleteGeneric(cx, obj, id, rval, strict);
+    return proxy_DeleteGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), rval, strict);
 }
 
 static void
 proxy_TraceObject(JSTracer *trc, JSObject *obj)
 {
 #ifdef DEBUG
     if (!trc->runtime->gcDisableStrictProxyCheckingCount && obj->isWrapper()) {
         JSObject *referent = &GetProxyPrivate(obj).toObject();
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -1008,19 +1008,17 @@ bool
 JSObject::shadowingShapeChange(JSContext *cx, const Shape &shape)
 {
     return generateOwnShape(cx);
 }
 
 bool
 JSObject::clearParent(JSContext *cx)
 {
-    Rooted<JSObject*> obj(cx, this);
-    Rooted<JSObject*> newParent(cx, NULL);
-    return setParent(cx, obj, newParent);
+    return setParent(cx, RootedObject(cx, this), RootedObject(cx));
 }
 
 /* static */ bool
 JSObject::setParent(JSContext *cx, HandleObject obj, HandleObject parent)
 {
     if (parent && !parent->setDelegate(cx))
         return false;
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1740,18 +1740,17 @@ js::CloneScript(JSContext *cx, HandleScr
     Bindings bindings(cx);
     Bindings::AutoRooter bindingsRoot(cx, &bindings);
     BindingNames names(cx);
     if (!src->bindings.getLocalNameArray(cx, &names))
         return NULL;
 
     for (unsigned i = 0; i < names.length(); ++i) {
         if (JSAtom *atom = names[i].maybeAtom) {
-            Rooted<JSAtom*> root(cx, atom);
-            if (!bindings.add(cx, root, names[i].kind))
+            if (!bindings.add(cx, RootedAtom(cx, atom), names[i].kind))
                 return NULL;
         } else {
             uint16_t _;
             if (!bindings.addDestructuring(cx, &_))
                 return NULL;
         }
     }
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -170,18 +170,17 @@ class Bindings
     }
     bool addArgument(JSContext *cx, HandleAtom name, uint16_t *slotp) {
         JS_ASSERT(name != NULL); /* not destructuring */
         *slotp = nargs;
         return add(cx, name, ARGUMENT);
     }
     bool addDestructuring(JSContext *cx, uint16_t *slotp) {
         *slotp = nargs;
-        Rooted<JSAtom*> atom(cx, NULL);
-        return add(cx, atom, ARGUMENT);
+        return add(cx, RootedAtom(cx), ARGUMENT);
     }
 
     void noteDup() { hasDup_ = true; }
     bool hasDup() const { return hasDup_; }
 
     /*
      * Look up an argument or variable name, returning its kind when found or
      * NONE when no such name exists. When indexp is not null and the name
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -423,23 +423,25 @@ ThisToStringForStringProto(JSContext *cx
 {
     JS_CHECK_RECURSION(cx, return NULL);
 
     if (call.thisv().isString())
         return call.thisv().toString();
 
     if (call.thisv().isObject()) {
         RootedObject obj(cx, &call.thisv().toObject());
-        if (obj->isString()) {
-            Rooted<jsid> id(cx, NameToId(cx->runtime->atomState.toStringAtom));
-            if (ClassMethodIsNative(cx, obj, &StringClass, id, js_str_toString)) {
-                JSString *str = obj->asString().unbox();
-                call.thisv().setString(str);
-                return str;
-            }
+        if (obj->isString() &&
+            ClassMethodIsNative(cx, obj,
+                                &StringClass,
+                                RootedId(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,
                              call.thisv().isNull() ? "null" : "undefined", "object");
         return NULL;
     }
 
     JSString *str = ToStringSlow(cx, call.thisv());
@@ -1977,17 +1979,17 @@ BuildFlatReplacement(JSContext *cx, Hand
                 if (strEnd > matchEnd) {
                     RootedString rightSide(cx);
                     rightSide = js_NewDependentString(cx, str, matchEnd - pos,
                                                       strEnd - matchEnd);
                     if (!rightSide || !builder.append(rightSide))
                         return false;
                 }
             } else {
-                if (!builder.append(str))
+                if (!builder.append(RootedString(cx, str)))
                     return false;
             }
             pos += str->length();
             if (!r.popFront())
                 return false;
         }
     } else {
         RootedString leftSide(cx);
@@ -3058,19 +3060,18 @@ StringObject::assignInitialShape(JSConte
 
 JSObject *
 js_InitStringClass(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isNative());
 
     Rooted<GlobalObject*> global(cx, &obj->asGlobal());
 
-    Rooted<JSString*> empty(cx, cx->runtime->emptyString);
     RootedObject proto(cx, global->createBlankPrototype(cx, &StringClass));
-    if (!proto || !proto->asString().init(cx, empty))
+    if (!proto || !proto->asString().init(cx, RootedString(cx, cx->runtime->emptyString)))
         return NULL;
 
     /* Now create the String function. */
     RootedFunction ctor(cx);
     ctor = global->createConstructor(cx, js_String, CLASS_NAME(cx, String), 1);
     if (!ctor)
         return NULL;
 
@@ -3280,18 +3281,17 @@ js_ValueToSource(JSContext *cx, const Va
             return js_NewStringCopyN(cx, js_negzero_ucNstr, 2);
         }
         return ToString(cx, v);
     }
 
     Value rval = NullValue();
     Value fval;
     RootedId id(cx, NameToId(cx->runtime->atomState.toSourceAtom));
-    Rooted<JSObject*> obj(cx, &v.toObject());
-    if (!GetMethod(cx, obj, id, 0, &fval))
+    if (!GetMethod(cx, RootedObject(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
@@ -344,18 +344,17 @@ ArrayBufferObject::obj_lookupGeneric(JSC
 
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 JSBool
 ArrayBufferObject::obj_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                                       JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_lookupGeneric(cx, obj, id, objp, propp);
+    return obj_lookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 JSBool
 ArrayBufferObject::obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
                                      JSObject **objp, JSProperty **propp)
 {
     RootedObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
@@ -383,42 +382,40 @@ ArrayBufferObject::obj_lookupElement(JSC
     *propp = NULL;
     return true;
 }
 
 JSBool
 ArrayBufferObject::obj_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
                                      JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_lookupGeneric(cx, obj, id, objp, propp);
+    return obj_lookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 JSBool
 ArrayBufferObject::obj_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v,
                                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
         return true;
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
     RootedObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
         return false;
-    return baseops::DefineGeneric(cx, delegate, id, v, getter, setter, attrs);
+    return baseops::DefineProperty(cx, delegate, id, v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_defineProperty(JSContext *cx, HandleObject obj,
                                       HandlePropertyName name, const Value *v,
                                       PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+    return obj_defineGeneric(cx, obj, RootedId(cx, NameToId(name)), v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_defineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *v,
                                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
@@ -427,18 +424,18 @@ ArrayBufferObject::obj_defineElement(JSC
         return false;
     return baseops::DefineElement(cx, delegate, index, v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *v,
                                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+    return obj_defineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)),
+                             v, getter, setter, attrs);
 }
 
 JSBool
 ArrayBufferObject::obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver,
                                   HandleId id, Value *vp)
 {
     RootedObject nobj(cx, getArrayBuffer(obj));
     JS_ASSERT(nobj);
@@ -472,18 +469,17 @@ ArrayBufferObject::obj_getProperty(JSCon
     if (name == cx->runtime->atomState.byteLengthAtom) {
         vp->setInt32(nobj->asArrayBuffer().byteLength());
         return true;
     }
 
     nobj = DelegateObject(cx, nobj);
     if (!nobj)
         return false;
-    Rooted<jsid> id(cx, NameToId(name));
-    return baseops::GetProperty(cx, nobj, receiver, id, vp);
+    return baseops::GetProperty(cx, nobj, receiver, RootedId(cx, NameToId(name)), vp);
 }
 
 JSBool
 ArrayBufferObject::obj_getElement(JSContext *cx, HandleObject obj,
                                   HandleObject receiver, uint32_t index, Value *vp)
 {
     RootedObject buffer(cx, getArrayBuffer(obj));
     RootedObject delegate(cx, DelegateObject(cx, buffer));
@@ -502,18 +498,17 @@ ArrayBufferObject::obj_getElementIfPrese
         return false;
     return delegate->getElementIfPresent(cx, receiver, index, vp, present);
 }
 
 JSBool
 ArrayBufferObject::obj_getSpecial(JSContext *cx, HandleObject obj,
                                   HandleObject receiver, HandleSpecialId sid, Value *vp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_getGeneric(cx, obj, receiver, id, vp);
+    return obj_getGeneric(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 JSBool
 ArrayBufferObject::obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool strict)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
         return true;
 
@@ -548,36 +543,34 @@ ArrayBufferObject::obj_setGeneric(JSCont
 
         if (delegate->getProto() != oldDelegateProto) {
             // actual __proto__ was set and not a plain property called
             // __proto__
             if (!obj->isExtensible()) {
                 obj->reportNotExtensible(cx);
                 return false;
             }
-            Rooted<JSObject*> newProto(cx, vp->toObjectOrNull());
-            if (!SetProto(cx, obj, newProto, true)) {
+            if (!SetProto(cx, obj, RootedObject(cx, vp->toObjectOrNull()), true)) {
                 // this can be caused for example by setting x.__proto__ = x
                 // restore delegate prototype chain
                 SetProto(cx, delegate, oldDelegateProto, true);
                 return false;
             }
         }
         return true;
     }
 
     return baseops::SetPropertyHelper(cx, delegate, id, 0, vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_setProperty(JSContext *cx, HandleObject obj,
                                    HandlePropertyName name, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_setGeneric(cx, obj, id, vp, strict);
+    return obj_setGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_setElement(JSContext *cx, HandleObject obj,
                                   uint32_t index, Value *vp, JSBool strict)
 {
     RootedObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
@@ -585,18 +578,17 @@ ArrayBufferObject::obj_setElement(JSCont
 
     return baseops::SetElementHelper(cx, delegate, index, 0, vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_setSpecial(JSContext *cx, HandleObject obj,
                                   HandleSpecialId sid, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_setGeneric(cx, obj, id, vp, strict);
+    return obj_setGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
 }
 
 JSBool
 ArrayBufferObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
                                             HandleId id, unsigned *attrsp)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
         *attrsp = JSPROP_PERMANENT | JSPROP_READONLY;
@@ -608,36 +600,34 @@ ArrayBufferObject::obj_getGenericAttribu
         return false;
     return baseops::GetAttributes(cx, delegate, id, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
                                              HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_getGenericAttributes(cx, obj, id, attrsp);
+    return obj_getGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_getElementAttributes(JSContext *cx, HandleObject obj,
                                             uint32_t index, unsigned *attrsp)
 {
     RootedObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
         return false;
     return baseops::GetElementAttributes(cx, delegate, index, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
                                             HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_getGenericAttributes(cx, obj, id, attrsp);
+    return obj_getGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
                                             HandleId id, unsigned *attrsp)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@@ -650,36 +640,34 @@ ArrayBufferObject::obj_setGenericAttribu
         return false;
     return baseops::SetAttributes(cx, delegate, id, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
                                              HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_setGenericAttributes(cx, obj, id, attrsp);
+    return obj_setGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setElementAttributes(JSContext *cx, HandleObject obj,
                                             uint32_t index, unsigned *attrsp)
 {
     RootedObject delegate(cx, DelegateObject(cx, obj));
     if (!delegate)
         return false;
     return baseops::SetElementAttributes(cx, delegate, index, attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
                                             HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_setGenericAttributes(cx, obj, id, attrsp);
+    return obj_setGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 JSBool
 ArrayBufferObject::obj_deleteProperty(JSContext *cx, HandleObject obj,
                                       HandlePropertyName name, Value *rval, JSBool strict)
 {
     if (name == cx->runtime->atomState.byteLengthAtom) {
         rval->setBoolean(false);
@@ -866,18 +854,17 @@ TypedArray::obj_lookupGeneric(JSContext 
 
     return proto->lookupGeneric(cx, id, objp, propp);
 }
 
 JSBool
 TypedArray::obj_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                                JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return obj_lookupGeneric(cx, obj, id, objp, propp);
+    return obj_lookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 JSBool
 TypedArray::obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
                               JSObject **objp, JSProperty **propp)
 {
     JSObject *tarray = getTypedArray(obj);
     JS_ASSERT(tarray);
@@ -895,18 +882,17 @@ TypedArray::obj_lookupElement(JSContext 
     *propp = NULL;
     return true;
 }
 
 JSBool
 TypedArray::obj_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
                               JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_lookupGeneric(cx, obj, id, objp, propp);
+    return obj_lookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 JSBool
 TypedArray::obj_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     *attrsp = (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
               ? JSPROP_PERMANENT | JSPROP_READONLY
               : JSPROP_PERMANENT | JSPROP_ENUMERATE;
@@ -925,18 +911,17 @@ TypedArray::obj_getElementAttributes(JSC
 {
     *attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE;
     return true;
 }
 
 JSBool
 TypedArray::obj_getSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return obj_getGenericAttributes(cx, obj, id, attrsp);
+    return obj_getGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 JSBool
 TypedArray::obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS);
     return false;
 }
@@ -1116,29 +1101,28 @@ class TypedArrayTemplate
     obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, Value *vp)
     {
         Value idval = IdToValue(id);
 
         uint32_t index;
         if (IsDefinitelyIndex(idval, &index))
             return obj_getElement(cx, obj, receiver, index, vp);
 
-        Rooted<SpecialId> sid(cx);
-        if (ValueIsSpecial(obj, &idval, sid.address(), cx))
-            return obj_getSpecial(cx, obj, receiver, sid, vp);
+        SpecialId sid;
+        if (ValueIsSpecial(obj, &idval, &sid, cx))
+            return obj_getSpecial(cx, obj, receiver, Rooted<SpecialId>(cx, sid), vp);
 
         JSAtom *atom = ToAtom(cx, idval);
         if (!atom)
             return false;
 
         if (atom->isIndex(&index))
             return obj_getElement(cx, obj, receiver, index, vp);
 
-        Rooted<PropertyName*> name(cx, atom->asPropertyName());
-        return obj_getProperty(cx, obj, receiver, name, vp);
+        return obj_getProperty(cx, obj, receiver, RootedPropertyName(cx, atom->asPropertyName()), vp);
     }
 
     static JSBool
     obj_getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, Value *vp, bool *present)
     {
         // Fast-path the common case of index < length
         JSObject *tarray = getTypedArray(obj);
 
@@ -1246,18 +1230,17 @@ class TypedArrayTemplate
         }
 
         return setElementTail(cx, tarray, index, vp, strict);
     }
 
     static JSBool
     obj_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *vp, JSBool strict)
     {
-        Rooted<jsid> id(cx, NameToId(name));
-        return obj_setGeneric(cx, obj, id, vp, strict);
+        return obj_setGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
     }
 
     static JSBool
     obj_setElement(JSContext *cx, HandleObject obj, uint32_t index, Value *vp, JSBool strict)
     {
         RootedObject tarray(cx, getTypedArray(obj));
         JS_ASSERT(tarray);
 
@@ -1272,18 +1255,17 @@ class TypedArrayTemplate
         }
 
         return setElementTail(cx, tarray, index, vp, strict);
     }
 
     static JSBool
     obj_setSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *vp, JSBool strict)
     {
-        Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-        return obj_setGeneric(cx, obj, id, vp, strict);
+        return obj_setGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
     }
 
     static JSBool
     obj_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v,
                       PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
         if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
             return true;
@@ -1291,34 +1273,32 @@ class TypedArrayTemplate
         Value tmp = *v;
         return obj_setGeneric(cx, obj, id, &tmp, false);
     }
 
     static JSBool
     obj_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, const Value *v,
                        PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
-        Rooted<jsid> id(cx, NameToId(name));
-        return obj_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+        return obj_defineGeneric(cx, obj, RootedId(cx, NameToId(name)), v, getter, setter, attrs);
     }
 
     static JSBool
     obj_defineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *v,
                        PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
         Value tmp = *v;
         return obj_setElement(cx, obj, index, &tmp, false);
     }
 
     static JSBool
     obj_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *v,
                       PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
     {
-        Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-        return obj_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+        return obj_defineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), v, getter, setter, attrs);
     }
 
     static JSBool
     obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *rval, JSBool strict)
     {
         if (name == cx->runtime->atomState.lengthAtom) {
             rval->setBoolean(false);
             return true;
@@ -1552,18 +1532,17 @@ class TypedArrayTemplate
                 if (length < 0) {
                     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                          JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "2");
                     return NULL;
                 }
             }
         }
 
-        Rooted<JSObject*> proto(cx, NULL);
-        return fromBuffer(cx, dataObj, byteOffset, length, proto);
+        return fromBuffer(cx, dataObj, byteOffset, length, RootedObject(cx));
     }
 
     /* subarray(start[, end]) */
     static JSBool
     fun_subarray(JSContext *cx, unsigned argc, Value *vp)
     {
         CallArgs args = CallArgsFromVp(argc, vp);
 
@@ -2909,29 +2888,25 @@ JSFunctionSpec _typedArray::jsfuncs[] = 
 }
 
 #define IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Name,NativeType)                                 \
   JS_FRIEND_API(JSObject *) JS_New ## Name ## Array(JSContext *cx, uint32_t nelements)       \
   {                                                                                          \
       MOZ_ASSERT(nelements <= INT32_MAX);                                                    \
       return TypedArrayTemplate<NativeType>::fromLength(cx, nelements);                      \
   }                                                                                          \
-  JS_FRIEND_API(JSObject *) JS_New ## Name ## ArrayFromArray(JSContext *cx, JSObject *other_)\
+  JS_FRIEND_API(JSObject *) JS_New ## Name ## ArrayFromArray(JSContext *cx, JSObject *other) \
   {                                                                                          \
-      Rooted<JSObject*> other(cx, other_);                                                   \
-      return TypedArrayTemplate<NativeType>::fromArray(cx, other);                           \
+      return TypedArrayTemplate<NativeType>::fromArray(cx, RootedObject(cx, other));      \
   }                                                                                          \
   JS_FRIEND_API(JSObject *) JS_New ## Name ## ArrayWithBuffer(JSContext *cx,                 \
-                               JSObject *arrayBuffer_, uint32_t byteoffset, int32_t length)  \
+                               JSObject *arrayBuffer, uint32_t byteoffset, int32_t length)   \
   {                                                                                          \
       MOZ_ASSERT(byteoffset <= INT32_MAX);                                                   \
-      Rooted<JSObject*> arrayBuffer(cx, arrayBuffer_);                                       \
-      Rooted<JSObject*> proto(cx, NULL);                                                     \
-      return TypedArrayTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteoffset, length, \
-                                                        proto);                              \
+      return TypedArrayTemplate<NativeType>::fromBuffer(cx, RootedObject(cx, arrayBuffer), byteoffset, length, RootedObject(cx)); \
   }                                                                                          \
   JS_FRIEND_API(JSBool) JS_Is ## Name ## Array(JSObject *obj, JSContext *cx)                 \
   {                                                                                          \
       if (!(obj = UnwrapObjectChecked(cx, obj)))                                             \
           return false;                                                                      \
       Class *clasp = obj->getClass();                                                        \
       return (clasp == &TypedArray::classes[TypedArrayTemplate<NativeType>::ArrayTypeID()]); \
   }
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -172,47 +172,43 @@ DirectWrapper::hasOwn(JSContext *cx, JSO
     *bp = false; // default result if we refuse to perform this action
     PropertyDescriptor desc;
     JSObject *wobj = wrappedObject(wrapper);
     GET(JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, &desc) &&
         Cond(desc.obj == wobj, bp));
 }
 
 bool
-DirectWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver_, jsid id_, Value *vp)
+DirectWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp)
 {
     vp->setUndefined(); // default result if we refuse to perform this action
-    Rooted<JSObject*> receiver(cx, receiver_);
-    Rooted<jsid> id(cx, id_);
-    GET(wrappedObject(wrapper)->getGeneric(cx, receiver, id, vp));
+    GET(wrappedObject(wrapper)->getGeneric(cx, RootedObject(cx, receiver), RootedId(cx, id), vp));
 }
 
 bool
-DirectWrapper::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id_, bool strict,
+DirectWrapper::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
                Value *vp)
 {
-    Rooted<jsid> id(cx, id_);
-    SET(wrappedObject(wrapper)->setGeneric(cx, id, vp, strict));
+    SET(wrappedObject(wrapper)->setGeneric(cx, RootedId(cx, id), vp, strict));
 }
 
 bool
 DirectWrapper::keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
 {
     // if we refuse to perform this action, props remains empty
     const jsid id = JSID_VOID;
     GET(GetPropertyNames(cx, wrappedObject(wrapper), JSITER_OWNONLY, &props));
 }
 
 bool
 DirectWrapper::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp)
 {
     vp->setUndefined(); // default result if we refuse to perform this action
     const jsid id = JSID_VOID;
-    Rooted<JSObject*> wrapped(cx, wrappedObject(wrapper));
-    GET(GetIterator(cx, wrapped, flags, vp));
+    GET(GetIterator(cx, RootedObject(cx, wrappedObject(wrapper)), flags, vp));
 }
 
 bool
 DirectWrapper::call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp)
 {
     vp->setUndefined(); // default result if we refuse to perform this action
     const jsid id = JSID_VOID;
     CHECKED(IndirectProxyHandler::call(cx, wrapper, argc, vp), CALL);
@@ -414,18 +410,17 @@ ErrorCopier::~ErrorCopier()
     if (cx->compartment == ac.destination &&
         ac.origin != ac.destination &&
         cx->isExceptionPending())
     {
         Value exc = cx->getPendingException();
         if (exc.isObject() && exc.toObject().isError() && exc.toObject().getPrivate()) {
             cx->clearPendingException();
             ac.leave();
-            Rooted<JSObject*> errObj(cx, &exc.toObject());
-            JSObject *copyobj = js_CopyErrorObject(cx, errObj, scope);
+            JSObject *copyobj = js_CopyErrorObject(cx, RootedObject(cx, &exc.toObject()), scope);
             if (copyobj)
                 cx->setPendingException(ObjectValue(*copyobj));
         }
     }
 }
 
 /* Cross compartment wrappers. */
 
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -381,18 +381,17 @@ ConvertQNameToString(JSContext *cx, JSOb
         /* Empty string for uri means localName is in no namespace. */
         str = cx->runtime->emptyString;
     } else {
         RootedString qualstr(cx, cx->runtime->atomState.qualifierAtom);
         str = js_ConcatStrings(cx, uri, qualstr);
         if (!str)
             return NULL;
     }
-    Rooted<JSString*> localName(cx, obj->getQNameLocalName());
-    str = js_ConcatStrings(cx, str, localName);
+    str = js_ConcatStrings(cx, str, RootedString(cx, obj->getQNameLocalName()));
     if (!str)
         return NULL;
 
     if (obj->getClass() == &AttributeNameClass) {
         JS::Anchor<JSString *> anchor(str);
         size_t length = str->length();
         jschar *chars = (jschar *) cx->malloc_((length + 2) * sizeof(jschar));
         if (!chars)
@@ -3995,18 +3994,17 @@ PutProperty(JSContext *cx, HandleObject 
             } else {
                 nameobj = targetprop;
                 if (nameobj->getClass() == &AttributeNameClass) {
                     /*
                      * 2(c)(iii)(1-3).
                      * Note that rxml can't be null here, because target
                      * and targetprop are non-null.
                      */
-                    Rooted<JSObject*> robj(cx, rxml->object);
-                    ok = GetProperty(cx, robj, id, &attrval);
+                    ok = GetProperty(cx, RootedObject(cx, rxml->object), id, &attrval);
                     if (!ok)
                         goto out;
                     if (JSVAL_IS_PRIMITIVE(attrval))    /* no such attribute */
                         goto out;
                     attrobj = JSVAL_TO_OBJECT(attrval);
                     attr = (JSXML *) attrobj->getPrivate();
                     if (JSXML_LENGTH(attr) != 0)
                         goto out;
@@ -4560,30 +4558,29 @@ ResolveValue(JSContext *cx, JSXML *list,
     if (!base) {
         *result = NULL;
         return JS_TRUE;
     }
     if (!js_GetXMLObject(cx, base))
         return JS_FALSE;
 
     RootedId id(cx, OBJECT_TO_JSID(targetprop));
-    Rooted<JSObject*> baseObj(cx, base->object);
-    if (!GetProperty(cx, baseObj, id, &tv))
+    if (!GetProperty(cx, RootedObject(cx, base->object), id, &tv))
         return JS_FALSE;
     target = (JSXML *) JSVAL_TO_OBJECT(tv)->getPrivate();
 
     if (JSXML_LENGTH(target) == 0) {
         if (base->xml_class == JSXML_CLASS_LIST && JSXML_LENGTH(base) > 1) {
             *result = NULL;
             return JS_TRUE;
         }
         tv = STRING_TO_JSVAL(cx->runtime->emptyString);
-        if (!PutProperty(cx, baseObj, id, false, &tv))
+        if (!PutProperty(cx, RootedObject(cx, base->object), id, false, &tv))
             return JS_FALSE;
-        if (!GetProperty(cx, baseObj, id, &tv))
+        if (!GetProperty(cx, RootedObject(cx, base->object), id, &tv))
             return JS_FALSE;
         target = (JSXML *) JSVAL_TO_OBJECT(tv)->getPrivate();
     }
 
     *result = target;
     return JS_TRUE;
 }
 
@@ -4635,28 +4632,27 @@ HasIndexedProperty(JSXML *xml, uint32_t 
 
     return JS_FALSE;
 }
 
 static JSBool
 HasSimpleContent(JSXML *xml);
 
 static JSBool
-HasFunctionProperty(JSContext *cx, JSObject *obj_, jsid funid_, JSBool *found)
+HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid_, JSBool *found)
 {
     JSObject *pobj;
     JSProperty *prop;
     JSXML *xml;
 
-    JS_ASSERT(obj_->getClass() == &XMLClass);
+    JS_ASSERT(obj->getClass() == &XMLClass);
 
     RootedId funid(cx, funid_);
 
-    Rooted<JSObject*> obj(cx, obj_);
-    if (!baseops::LookupProperty(cx, obj, funid, &pobj, &prop))
+    if (!baseops::LookupProperty(cx, RootedObject(cx, obj), funid, &pobj, &prop))
         return false;
     if (!prop) {
         xml = (JSXML *) obj->getPrivate();
         if (HasSimpleContent(xml)) {
             /*
              * Search in String.prototype to set found whenever
              * GetXMLFunction returns existing function.
              */
@@ -4789,18 +4785,17 @@ xml_lookupGeneric(JSContext *cx, HandleO
     }
     return JS_TRUE;
 }
 
 static JSBool
 xml_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject **objp,
                    JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_lookupGeneric(cx, obj, id, objp, propp);
+    return xml_lookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 static JSBool
 xml_lookupElement(JSContext *cx, HandleObject obj, uint32_t index, JSObject **objp,
                   JSProperty **propp)
 {
     JSXML *xml = reinterpret_cast<JSXML *>(obj->getPrivate());
     if (!HasIndexedProperty(xml, index)) {
@@ -4809,168 +4804,160 @@ xml_lookupElement(JSContext *cx, HandleO
         return true;
     }
 
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
 
     const Shape *shape =
-        js_AddNativeProperty(cx, obj, id, GetProperty, PutProperty, SHAPE_INVALID_SLOT,
-                             JSPROP_ENUMERATE, 0, 0);
+        js_AddNativeProperty(cx, RootedObject(cx, obj), id, GetProperty, PutProperty,
+                             SHAPE_INVALID_SLOT, JSPROP_ENUMERATE,
+                             0, 0);
     if (!shape)
         return false;
 
     *objp = obj;
     *propp = (JSProperty *) shape;
     return true;
 }
 
 static JSBool
 xml_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_lookupGeneric(cx, obj, id, objp, propp);
+    return xml_lookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 static JSBool
 xml_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v,
                   PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     if (IsFunctionObject(*v) || getter || setter ||
         (attrs & JSPROP_ENUMERATE) == 0 ||
         (attrs & (JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED))) {
-        return baseops::DefineGeneric(cx, obj, id, v, getter, setter, attrs);
+        return baseops::DefineProperty(cx, obj, id, v, getter, setter, attrs);
     }
 
     jsval tmp = *v;
     return PutProperty(cx, obj, id, false, &tmp);
 }
 
 static JSBool
 xml_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, const Value *v,
                    PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+    return xml_defineGeneric(cx, obj, RootedId(cx, NameToId(name)), v, getter, setter, attrs);
 }
 
 static JSBool
 xml_defineElement(JSContext *cx, HandleObject obj, uint32_t index, const Value *v,
                   PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return xml_defineGeneric(cx, obj, id, v, getter, setter, attrs);
 }
 
 static JSBool
 xml_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *v,
                   PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_defineGeneric(cx, obj, id, v, getter, setter, attrs);
+    return xml_defineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), v, getter, setter, attrs);
 }
 
 static JSBool
 xml_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, Value *vp)
 {
     if (JSID_IS_DEFAULT_XML_NAMESPACE(id)) {
         vp->setUndefined();
         return JS_TRUE;
     }
 
     return GetProperty(cx, obj, id, vp);
 }
 
 static JSBool
 xml_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, Value *vp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_getGeneric(cx, obj, receiver, id, vp);
+    return xml_getGeneric(cx, obj, receiver, RootedId(cx, NameToId(name)), vp);
 }
 
 static JSBool
 xml_getElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, Value *vp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return xml_getGeneric(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 xml_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid, Value *vp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_getGeneric(cx, obj, receiver, id, vp);
+    return xml_getGeneric(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 static JSBool
 xml_setGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool strict)
 {
     return PutProperty(cx, obj, id, strict, vp);
 }
 
 static JSBool
 xml_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_setGeneric(cx, obj, id, vp, strict);
+    return xml_setGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
 }
 
 static JSBool
 xml_setElement(JSContext *cx, HandleObject obj, uint32_t index, Value *vp, JSBool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return xml_setGeneric(cx, obj, id, vp, strict);
 }
 
 static JSBool
 xml_setSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *vp, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_setGeneric(cx, obj, id, vp, strict);
+    return xml_setGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
 }
 
 static JSBool
 xml_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     JSBool found;
     if (!HasProperty(cx, obj, IdToJsval(id), &found))
         return false;
 
     *attrsp = found ? JSPROP_ENUMERATE : 0;
     return JS_TRUE;
 }
 
 static JSBool
 xml_getPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_getGenericAttributes(cx, obj, id, attrsp);
+    return xml_getGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 static JSBool
 xml_getElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return xml_getGenericAttributes(cx, obj, id, attrsp);
 }
 
 static JSBool
 xml_getSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_getGenericAttributes(cx, obj, id, attrsp);
+    return xml_getGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 static JSBool
 xml_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     JSBool found;
     if (!HasProperty(cx, obj, IdToJsval(id), &found))
         return false;
@@ -4981,34 +4968,32 @@ xml_setGenericAttributes(JSContext *cx, 
         return false;
     }
     return true;
 }
 
 static JSBool
 xml_setPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_setGenericAttributes(cx, obj, id, attrsp);
+    return xml_setGenericAttributes(cx, obj, RootedId(cx, NameToId(name)), attrsp);
 }
 
 static JSBool
 xml_setElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return xml_setGenericAttributes(cx, obj, id, attrsp);
 }
 
 static JSBool
 xml_setSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_setGenericAttributes(cx, obj, id, attrsp);
+    return xml_setGenericAttributes(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), attrsp);
 }
 
 static JSBool
 xml_deleteGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *rval, JSBool strict)
 {
     uint32_t index;
     JSObject *nameqn;
     RootedId funid(cx);
@@ -5047,18 +5032,17 @@ xml_deleteGeneric(JSContext *cx, HandleO
 
     rval->setBoolean(true);
     return true;
 }
 
 static JSBool
 xml_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return xml_deleteGeneric(cx, obj, id, rval, strict);
+    return xml_deleteGeneric(cx, obj, RootedId(cx, NameToId(name)), rval, strict);
 }
 
 static JSBool
 xml_deleteElement(JSContext *cx, HandleObject 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. */
@@ -5081,18 +5065,17 @@ xml_deleteElement(JSContext *cx, HandleO
 
     rval->setBoolean(true);
     return true;
 }
 
 static JSBool
 xml_deleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *rval, JSBool strict)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return xml_deleteGeneric(cx, obj, id, rval, strict);
+    return xml_deleteGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), rval, strict);
 }
 
 static JSString *
 xml_toString_helper(JSContext *cx, JSXML *xml);
 
 JSBool
 xml_convert(JSContext *cx, HandleObject obj, JSType hint, Value *rval)
 {
@@ -5223,30 +5206,29 @@ again:
         return simple;
     }
 }
 
 /*
  * 11.2.2.1 Step 3(d) onward.
  */
 JSBool
-js_GetXMLMethod(JSContext *cx, HandleObject obj, jsid id_, Value *vp)
+js_GetXMLMethod(JSContext *cx, HandleObject obj, jsid id, Value *vp)
 {
     JS_ASSERT(obj->isXML());
 
-    Rooted<jsid> id(cx, id_);
     if (JSID_IS_OBJECT(id))
-        js_GetLocalNameFromFunctionQName(JSID_TO_OBJECT(id), id.address(), cx);
+        js_GetLocalNameFromFunctionQName(JSID_TO_OBJECT(id), &id, cx);
 
     /*
      * As our callers have a bad habit of passing a pointer to an unrooted
      * local value as vp, we use a proper root here.
      */
     AutoValueRooter tvr(cx);
-    JSBool ok = GetXMLFunction(cx, obj, id, tvr.addr());
+    JSBool ok = GetXMLFunction(cx, obj, RootedId(cx, id), tvr.addr());
     *vp = tvr.value();
     return ok;
 }
 
 JSBool
 js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp)
 {
     JSXML *xml, *vxml;
@@ -5515,40 +5497,43 @@ xml_addNamespace(JSContext *cx, unsigned
   done:
     *vp = OBJECT_TO_JSVAL(obj);
     return JS_TRUE;
 }
 
 static JSBool
 xml_appendChild(JSContext *cx, unsigned argc, jsval *vp)
 {
+    jsval v;
+    JSObject *vobj;
+    JSXML *vxml;
+
     NON_LIST_XML_METHOD_PROLOG;
     xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
     if (!xml)
         return JS_FALSE;
 
     RootedId name(cx);
     if (!js_GetAnyName(cx, name.address()))
         return JS_FALSE;
 
-    Value v;
     if (!GetProperty(cx, obj, name, &v))
         return JS_FALSE;
 
     JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
-    Rooted<JSObject*> vobj(cx, &v.toObject());
+    vobj = JSVAL_TO_OBJECT(v);
     JS_ASSERT(vobj->isXML());
-    JSXML *vxml = (JSXML *) vobj->getPrivate();
+    vxml = (JSXML *) vobj->getPrivate();
     JS_ASSERT(vxml->xml_class == JSXML_CLASS_LIST);
 
     if (!IndexToId(cx, vxml->xml_kids.length, name.address()))
         return JS_FALSE;
     *vp = (argc != 0) ? vp[2] : JSVAL_VOID;
 
-    if (!PutProperty(cx, vobj, name, false, vp))
+    if (!PutProperty(cx, RootedObject(cx, JSVAL_TO_OBJECT(v)), name, false, vp))
         return JS_FALSE;
 
     *vp = OBJECT_TO_JSVAL(obj);
     return JS_TRUE;
 }
 
 /* XML and XMLList */
 static JSBool
@@ -5624,29 +5609,27 @@ ValueToIdForXML(JSContext *cx, jsval v, 
     } else {
         ReportBadXMLName(cx, v);
         return JS_FALSE;
     }
     return JS_TRUE;
 }
 
 static JSBool
-xml_child_helper(JSContext *cx, JSObject *obj_, JSXML *xml, jsval name,
+xml_child_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval name,
                  jsval *rval)
 {
     bool isIndex;
     uint32_t index;
     JSXML *kid;
     JSObject *kidobj;
 
     /* ECMA-357 13.4.4.6 */
     JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
 
-    Rooted<JSObject*> obj(cx, obj_);
-
     if (!IdValIsIndex(cx, name, &index, &isIndex))
         return JS_FALSE;
 
     if (isIndex) {
         if (index >= JSXML_LENGTH(xml)) {
             *rval = JSVAL_VOID;
         } else {
             kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
@@ -5661,17 +5644,17 @@ xml_child_helper(JSContext *cx, JSObject
         }
         return JS_TRUE;
     }
 
     RootedId id(cx);
     if (!ValueToIdForXML(cx, name, id.address()))
         return JS_FALSE;
 
-    return GetProperty(cx, obj, id, rval);
+    return GetProperty(cx, RootedObject(cx, obj), id, rval);
 }
 
 /* XML and XMLList */
 static JSBool
 xml_child(JSContext *cx, unsigned argc, jsval *vp)
 {
     jsval v;
     JSXML *list, *vxml;
@@ -6346,21 +6329,19 @@ xml_normalize_helper(JSContext *cx, JSOb
             continue;
         if (kid->xml_class == JSXML_CLASS_ELEMENT) {
             kidobj = js_GetXMLObject(cx, kid);
             if (!kidobj || !xml_normalize_helper(cx, kidobj, kid))
                 return JS_FALSE;
         } else if (kid->xml_class == JSXML_CLASS_TEXT) {
             while (i + 1 < n &&
                    (kid2 = XMLARRAY_MEMBER(&xml->xml_kids, i + 1, JSXML)) &&
-                   kid2->xml_class == JSXML_CLASS_TEXT)
-            {
-                Rooted<JSString*> lstr(cx, kid->xml_value);
-                Rooted<JSString*> rstr(cx, kid2->xml_value);
-                str = js_ConcatStrings(cx, lstr, rstr);
+                   kid2->xml_class == JSXML_CLASS_TEXT) {
+                str = js_ConcatStrings(cx, RootedString(cx, kid->xml_value),
+                                       RootedString(cx, kid2->xml_value));
                 if (!str)
                     return JS_FALSE;
                 NormalizingDelete(cx, xml, i + 1);
                 n = xml->xml_kids.length;
                 kid->xml_value = str;
             }
             if (kid->xml_value->empty()) {
                 NormalizingDelete(cx, xml, i);
@@ -6697,19 +6678,18 @@ xml_replace(JSContext *cx, unsigned argc
 static JSBool
 xml_setChildren(JSContext *cx, unsigned argc, jsval *vp)
 {
     RootedObject obj(cx);
 
     if (!StartNonListXMLMethod(cx, vp, obj.address()))
         return JS_FALSE;
 
-    Rooted<jsid> id(cx, NameToId(cx->runtime->atomState.starAtom));
     *vp = argc != 0 ? vp[2] : JSVAL_VOID;     /* local root */
-    if (!PutProperty(cx, obj, id, false, vp))
+    if (!PutProperty(cx, obj, RootedId(cx, 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)
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -4817,39 +4817,37 @@ mjit::Compiler::jsop_getprop(PropertyNam
             return true;
         }
     }
 
     /* 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)) {
-        Rooted<jsid> id(cx, NameToId(name));
-        if (testSingletonPropertyTypes(top, id, &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);
-            }
-
-            frame.pop();
-            frame.push(ObjectValue(*singleton));
-
-            if (script->hasScriptCounts && cx->typeInferenceEnabled())
-                bumpPropCount(PC, PCCounts::PROP_STATIC);
-
-            if (testObject)
-                stubcc.rejoin(Changes(1));
-
-            return true;
+    if (singleton && singleton->isFunction() && !hasTypeBarriers(PC) &&
+        testSingletonPropertyTypes(top, RootedId(cx, 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);
         }
+
+        frame.pop();
+        frame.push(ObjectValue(*singleton));
+
+        if (script->hasScriptCounts && cx->typeInferenceEnabled())
+            bumpPropCount(PC, PCCounts::PROP_STATIC);
+
+        if (testObject)
+            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, NameToId(name))) {
             if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
                 frame.learnType(fe, knownType, false);
@@ -5116,18 +5114,17 @@ mjit::Compiler::testSingletonPropertyTyp
         break;
 
       case JSVAL_TYPE_OBJECT:
       case JSVAL_TYPE_UNKNOWN:
         if (types->getObjectCount() == 1 && !top->isNotType(JSVAL_TYPE_OBJECT)) {
             JS_ASSERT_IF(top->isTypeKnown(), top->isType(JSVAL_TYPE_OBJECT));
             types::TypeObject *object = types->getTypeObject(0);
             if (object && object->proto) {
-                Rooted<JSObject*> proto(cx, object->proto);
-                if (!testSingletonProperty(proto, id))
+                if (!testSingletonProperty(RootedObject(cx, object->proto), id))
                     return false;
                 types->addFreeze(cx);
 
                 /* If we don't know this is an object, we will need a test. */
                 *testObject = (type != JSVAL_TYPE_OBJECT) && !top->isTypeKnown();
                 return true;
             }
         }
@@ -5194,23 +5191,22 @@ mjit::Compiler::jsop_getprop_dispatch(Pr
             continue;
         }
         if (object->unknownProperties() || !object->proto)
             return false;
         types::TypeSet *ownTypes = object->getProperty(cx, id, false);
         if (ownTypes->isOwnProperty(cx, object, false))
             return false;
 
-        Rooted<JSObject*> proto(cx, object->proto);
-        if (!testSingletonProperty(proto, id))
+        if (!testSingletonProperty(RootedObject(cx, object->proto), id))
             return false;
 
-        if (proto->getType(cx)->unknownProperties())
+        if (object->proto->getType(cx)->unknownProperties())
             return false;
-        types::TypeSet *protoTypes = proto->type()->getProperty(cx, id, false);
+        types::TypeSet *protoTypes = object->proto->type()->getProperty(cx, id, false);
         if (!protoTypes)
             return false;
         JSObject *singleton = protoTypes->getSingleton(cx);
         if (!singleton)
             return false;
 
         results.append(singleton);
         last = i;
@@ -6254,22 +6250,19 @@ mjit::Compiler::jsop_getgname(uint32_t i
     }
     if (name == cx->runtime->atomState.InfinityAtom) {
         frame.push(cx->runtime->positiveInfinityValue);
         return true;
     }
 
     /* Optimize singletons like Math for JSOP_CALLPROP. */
     JSObject *obj = pushedSingleton(0);
-    if (obj && !hasTypeBarriers(PC)) {
-        Rooted<jsid> id(cx, NameToId(name));
-        if (testSingletonProperty(globalObj, id)) {
-            frame.push(ObjectValue(*obj));
-            return true;
-        }
+    if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, RootedId(cx, NameToId(name)))) {
+        frame.push(ObjectValue(*obj));
+        return true;
     }
 
     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)
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -2650,21 +2650,21 @@ mjit::Compiler::jsop_initprop()
         prepareStubCall(Uses(2));
         masm.move(ImmPtr(name), Registers::ArgReg1);
         INLINE_STUBCALL(stubs::InitProp, REJOIN_FALLTHROUGH);
         return;
     }
 
     JSObject *holder;
     JSProperty *prop = NULL;
-    Rooted<jsid> id(cx, NameToId(name));
 #ifdef DEBUG
     bool res =
 #endif
-    LookupPropertyWithFlags(cx, baseobj, id, JSRESOLVE_QUALIFIED, &holder, &prop);
+    LookupPropertyWithFlags(cx, baseobj, RootedId(cx, 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());
     frame.storeTo(fe, address);
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1660,17 +1660,17 @@ class ScopeNameCompiler : public PICStub
             return generateGlobalStub(obj);
 
         return disable("scope object not handled yet");
     }
 
     bool retrieve(Value *vp, PICInfo::Kind kind)
     {
         JSObject *obj = getprop.obj;
-        Rooted<JSObject*> holder(cx, getprop.holder);
+        JSObject *holder = getprop.holder;
         const JSProperty *prop = getprop.prop;
 
         if (!prop) {
             /* Kludge to allow (typeof foo == "undefined") tests. */
             if (kind == ic::PICInfo::NAME) {
                 JSOp op2 = JSOp(f.pc()[JSOP_NAME_LENGTH]);
                 if (op2 == JSOP_TYPEOF) {
                     vp->setUndefined();
@@ -1685,17 +1685,17 @@ class ScopeNameCompiler : public PICStub
         // take a slow path and do a full property fetch.
         if (!getprop.shape) {
             if (!obj->getProperty(cx, name, vp))
                 return false;
             return true;
         }
 
         const Shape *shape = getprop.shape;
-        Rooted<JSObject*> normalized(cx, obj);
+        JSObject *normalized = obj;
         if (obj->isWith() && !shape->hasDefaultGetter())
             normalized = &obj->asWith().object();
         NATIVE_GET(cx, normalized, holder, shape, 0, vp, return false);
         return true;
     }
 };
 
 class BindNameCompiler : public PICStubCompiler
@@ -2432,18 +2432,17 @@ GetElementIC::attachTypedArray(VMFrame &
     // In the future, it might make sense to attach multiple typed array stubs.
     // For simplicitly, they are currently monomorphic.
     if (stubsGenerated == MAX_GETELEM_IC_STUBS)
         disable(f, "max stubs reached");
 
     disable(f, "generated typed array stub");
 
     // Fetch the value as expected of Lookup_Cacheable for GetElement.
-    Rooted<jsid> idRoot(cx, id);
-    if (!obj->getGeneric(cx, idRoot, vp))
+    if (!obj->getGeneric(cx, RootedId(cx, id), vp))
         return Lookup_Error;
 
     return Lookup_Cacheable;
 }
 #endif /* JS_METHODJIT_TYPED_ARRAY */
 
 LookupStatus
 GetElementIC::update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp)
@@ -2500,21 +2499,21 @@ ic::GetElement(VMFrame &f, ic::GetElemen
     // context, so we fall back to stubs::GetElem.
     if (obj->isXML()) {
         ic->disable(f, "XML object");
         stubs::GetElem(f);
         return;
     }
 #endif
 
-    Rooted<jsid> id(cx);
+    jsid id;
     if (idval.isInt32() && INT_FITS_IN_JSID(idval.toInt32())) {
         id = INT_TO_JSID(idval.toInt32());
     } else {
-        if (!InternNonIntElementId(cx, obj, idval, id.address()))
+        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]);
@@ -2523,17 +2522,17 @@ ic::GetElement(VMFrame &f, ic::GetElemen
                 THROW();
 
             // If the result can be cached, the value was already retrieved.
             JS_ASSERT(!f.regs.sp[-2].isMagic());
             return;
         }
     }
 
-    if (!obj->getGeneric(cx, id, &f.regs.sp[-2]))
+    if (!obj->getGeneric(cx, RootedId(cx, id), &f.regs.sp[-2]))
         THROW();
 
 #if JS_HAS_NO_SUCH_METHOD
     if (*f.pc() == JSOP_CALLELEM && JS_UNLIKELY(f.regs.sp[-2].isPrimitive())) {
         if (!OnUnknownMethod(cx, obj, idval, &f.regs.sp[-2]))
             THROW();
     }
 #endif
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -47,20 +47,20 @@
 #include "jsautooplen.h"
 
 using namespace js;
 using namespace js::mjit;
 using namespace js::types;
 using namespace JSC;
 
 void JS_FASTCALL
-stubs::BindName(VMFrame &f, PropertyName *name_)
+stubs::BindName(VMFrame &f, PropertyName *name)
 {
-    Rooted<PropertyName*> name(f.cx, name_);
-    JSObject *obj = FindIdentifierBase(f.cx, f.fp()->scopeChain(), name);
+    JSObject *obj = FindIdentifierBase(f.cx, f.fp()->scopeChain(),
+                                       RootedPropertyName(f.cx, name));
     if (!obj)
         THROW();
     f.regs.sp[0].setObject(*obj);
 }
 
 JSObject * JS_FASTCALL
 stubs::BindGlobalName(VMFrame &f)
 {
@@ -500,18 +500,17 @@ StubEqualityOp(VMFrame &f)
             if (EQ)
                 cond = (l == r);
             else
                 cond = (l != r);
         } else if (lval.isObject()) {
             JSObject *l = &lval.toObject(), *r = &rval.toObject();
             if (JSEqualityOp eq = l->getClass()->ext.equality) {
                 JSBool equal;
-                Rooted<JSObject*> lobj(cx, l);
-                if (!eq(cx, lobj, &rval, &equal))
+                if (!eq(cx, RootedObject(cx, l), &rval, &equal))
                     return false;
                 cond = !!equal == EQ;
             } else {
                 cond = (l == r) == EQ;
             }
         } else if (lval.isNullOrUndefined()) {
             cond = EQ;
         } else {
@@ -882,18 +881,17 @@ void JS_FASTCALL
 stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
 {
     JSContext *cx = f.cx;
     TypeObject *type = (TypeObject *) f.scratch;
 
     JSObject *obj;
 
     if (baseobj) {
-        Rooted<JSObject*> base(cx, baseobj);
-        obj = CopyInitializerObject(cx, base);
+        obj = CopyInitializerObject(cx, RootedObject(cx, baseobj));
     } else {
         gc::AllocKind kind = GuessObjectGCKind(0);
         obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
     }
 
     if (!obj)
         THROW();
 
@@ -1062,18 +1060,18 @@ stubs::IterNext(VMFrame &f, int32_t offs
 
 JSBool JS_FASTCALL
 stubs::IterMore(VMFrame &f)
 {
     JS_ASSERT(f.regs.stackDepth() >= 1);
     JS_ASSERT(f.regs.sp[-1].isObject());
 
     Value v;
-    Rooted<JSObject*> iterobj(f.cx, &f.regs.sp[-1].toObject());
-    if (!js_IteratorMore(f.cx, iterobj, &v))
+    JSObject *iterobj = &f.regs.sp[-1].toObject();
+    if (!js_IteratorMore(f.cx, RootedObject(f.cx, iterobj), &v))
         THROWV(JS_FALSE);
 
     return v.toBoolean();
 }
 
 void JS_FASTCALL
 stubs::EndIter(VMFrame &f)
 {
@@ -1397,18 +1395,19 @@ void JS_FASTCALL
 stubs::DefVarOrConst(VMFrame &f, PropertyName *dn)
 {
     unsigned attrs = JSPROP_ENUMERATE;
     if (!f.fp()->isEvalFrame())
         attrs |= JSPROP_PERMANENT;
     if (JSOp(*f.regs.pc) == JSOP_DEFCONST)
         attrs |= JSPROP_READONLY;
 
-    Rooted<JSObject*> varobj(f.cx, &f.fp()->varObj());
-    if (!DefVarOrConstOperation(f.cx, varobj, dn, attrs))
+    JSObject &obj = f.fp()->varObj();
+
+    if (!DefVarOrConstOperation(f.cx, RootedObject(f.cx, &obj), dn, attrs))
         THROW();
 }
 
 void JS_FASTCALL
 stubs::SetConst(VMFrame &f, PropertyName *name)
 {
     JSContext *cx = f.cx;
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2777,33 +2777,30 @@ CopyProperty(JSContext *cx, HandleObject
     return !!DefineNativeProperty(cx, obj, id, desc.value, desc.getter, desc.setter,
                                   desc.attrs, propFlags, desc.shortid);
 }
 
 static JSBool
 resolver_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags, JSObject **objp)
 {
     jsval v = JS_GetReservedSlot(obj, 0);
-    Rooted<JSObject*> vobj(cx, &v.toObject());
-    return CopyProperty(cx, obj, vobj, id, flags, objp);
+    return CopyProperty(cx, obj, RootedObject(cx, JSVAL_TO_OBJECT(v)), id, flags, objp);
 }
 
 static JSBool
 resolver_enumerate(JSContext *cx, HandleObject obj)
 {
     jsval v = JS_GetReservedSlot(obj, 0);
     RootedObject referent(cx, JSVAL_TO_OBJECT(v));
 
     AutoIdArray ida(cx, JS_Enumerate(cx, referent));
     bool ok = !!ida;
     JSObject *ignore;
-    for (size_t i = 0; ok && i < ida.length(); i++) {
-        Rooted<jsid> id(cx, ida[i]);
-        ok = CopyProperty(cx, obj, referent, id, JSRESOLVE_QUALIFIED, &ignore);
-    }
+    for (size_t i = 0; ok && i < ida.length(); i++)
+        ok = CopyProperty(cx, obj, referent, RootedId(cx, ida[i]), JSRESOLVE_QUALIFIED, &ignore);
     return ok;
 }
 
 static JSClass resolver_class = {
     "resolver",
     JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1),
     JS_PropertyStub,   JS_PropertyStub,
     JS_PropertyStub,   JS_StrictPropertyStub,
@@ -3145,23 +3142,23 @@ Parent(JSContext *cx, unsigned argc, jsv
     }
 
     jsval v = JS_ARGV(cx, vp)[0];
     if (JSVAL_IS_PRIMITIVE(v)) {
         JS_ReportError(cx, "Only objects have parents!");
         return false;
     }
 
-    Rooted<JSObject*> parent(cx, JS_GetParent(&v.toObject()));
+    JSObject *parent = JS_GetParent(JSVAL_TO_OBJECT(v));
     *vp = OBJECT_TO_JSVAL(parent);
 
     /* Outerize if necessary.  Embrace the ugliness! */
     if (parent) {
         if (JSObjectOp op = parent->getClass()->ext.outerObject)
-            *vp = OBJECT_TO_JSVAL(op(cx, parent));
+            *vp = OBJECT_TO_JSVAL(op(cx, RootedObject(cx, parent)));
     }
 
     return true;
 }
 
 #ifdef XP_UNIX
 
 #include <fcntl.h>
--- a/js/src/shell/jsheaptools.cpp
+++ b/js/src/shell/jsheaptools.cpp
@@ -547,18 +547,17 @@ FindReferences(JSContext *cx, unsigned a
 
     /* Walk the JSRuntime, producing a reversed map of the heap. */
     HeapReverser reverser(cx);
     if (!reverser.init() || !reverser.reverseHeap())
         return false;
 
     /* Given the reversed map, find the referents of target. */
     ReferenceFinder finder(cx, reverser);
-    Rooted<JSObject*> targetObj(cx, &target.toObject());
-    JSObject *references = finder.findReferences(targetObj);
+    JSObject *references = finder.findReferences(RootedObject(cx, &target.toObject()));
     if (!references)
         return false;
 
     JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(references));
     return true;
 }
 
 #endif /* DEBUG */
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -198,17 +198,17 @@ ArgSetter(JSContext *cx, HandleObject ob
      * backed by the default Object getter and setter. Note that we rely on
      * args_delProperty to clear the corresponding reserved slot so the GC can
      * collect its value. Note also that we must define the property instead
      * of setting it in case the user has changed the prototype to an object
      * that has a setter for this id.
      */
     RootedValue value(cx);
     return baseops::DeleteGeneric(cx, obj, id, value.address(), false) &&
-           baseops::DefineGeneric(cx, obj, id, vp, NULL, NULL, JSPROP_ENUMERATE);
+           baseops::DefineProperty(cx, obj, id, vp, NULL, NULL, JSPROP_ENUMERATE);
 }
 
 static JSBool
 args_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
              JSObject **objp)
 {
     *objp = NULL;
 
@@ -228,17 +228,17 @@ args_resolve(JSContext *cx, HandleObject
         if (!JSID_IS_ATOM(id, cx->runtime->atomState.calleeAtom))
             return true;
 
         if (argsobj->callee().isMagic(JS_OVERWRITTEN_CALLEE))
             return true;
     }
 
     Value undef = UndefinedValue();
-    if (!baseops::DefineGeneric(cx, argsobj, id, &undef, ArgGetter, ArgSetter, attrs))
+    if (!baseops::DefineProperty(cx, argsobj, id, &undef, ArgGetter, ArgSetter, attrs))
         return JS_FALSE;
 
     *objp = argsobj;
     return true;
 }
 
 bool
 NormalArgumentsObject::optimizedGetElem(JSContext *cx, StackFrame *fp, const Value &elem, Value *vp)
@@ -277,18 +277,17 @@ NormalArgumentsObject::optimizedGetElem(
         *vp = ObjectValue(fp->callee());
         return true;
     }
 
     JSObject *proto = fp->global().getOrCreateObjectPrototype(cx);
     if (!proto)
         return false;
 
-    Rooted<jsid> root(cx, id);
-    return proto->getGeneric(cx, root, vp);
+    return proto->getGeneric(cx, RootedId(cx, id), vp);
 }
 
 static JSBool
 args_enumerate(JSContext *cx, HandleObject obj)
 {
     Rooted<NormalArgumentsObject*> argsobj(cx, &obj->asNormalArguments());
     RootedId id(cx);
 
@@ -392,17 +391,17 @@ strictargs_resolve(JSContext *cx, Handle
         }
 
         attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
         getter = CastAsPropertyOp(argsobj->global().getThrowTypeError());
         setter = CastAsStrictPropertyOp(argsobj->global().getThrowTypeError());
     }
 
     Value undef = UndefinedValue();
-    if (!baseops::DefineGeneric(cx, argsobj, id, &undef, getter, setter, attrs))
+    if (!baseops::DefineProperty(cx, argsobj, id, &undef, getter, setter, attrs))
         return false;
 
     *objp = argsobj;
     return true;
 }
 
 static JSBool
 strictargs_enumerate(JSContext *cx, HandleObject obj)
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -835,17 +835,17 @@ Debugger::parseResumptionValue(AutoCompa
     }
     if (rv.isNull()) {
         ac.leave();
         return JSTRAP_ERROR;
     }
 
     /* Check that rv is {return: val} or {throw: val}. */
     JSContext *cx = ac.context;
-    Rooted<JSObject*> obj(cx);
+    JSObject *obj;
     const Shape *shape;
     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();
     }
@@ -873,23 +873,21 @@ 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));
-    if (!atom)
-        return false;
-
-    Rooted<jsid> id(cx, AtomToId(atom));
     Value fval;
-    return GetMethod(cx, obj, id, 0, &fval) &&
-           (!js_IsCallable(fval) || Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
+    return atom &&
+           GetMethod(cx, obj, RootedId(cx, AtomToId(atom)), 0, &fval) &&
+           (!js_IsCallable(fval) ||
+            Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
 }
 
 JSTrapStatus
 Debugger::fireDebuggerStatement(JSContext *cx, Value *vp)
 {
     RootedObject hook(cx, getHook(OnDebuggerStatement));
     JS_ASSERT(hook);
     JS_ASSERT(hook->isCallable());
@@ -1125,18 +1123,17 @@ Debugger::onTrap(JSContext *cx, Value *v
             AutoCompartment ac(cx, dbg->object);
             if (!ac.enter())
                 return JSTRAP_ERROR;
 
             Value argv[1];
             if (!dbg->getScriptFrame(cx, fp, &argv[0]))
                 return dbg->handleUncaughtException(ac, vp, false);
             Value rv;
-            Rooted<JSObject*> handler(cx, bp->handler);
-            bool ok = CallMethodIfPresent(cx, handler, "hit", 1, argv, &rv);
+            bool ok = CallMethodIfPresent(cx, RootedObject(cx, bp->handler), "hit", 1, argv, &rv);
             JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rv, vp, true);
             if (st != JSTRAP_CONTINUE)
                 return st;
 
             /* Calling JS code invalidates site. Reload it. */
             site = script->getBreakpointSite(pc);
         }
     }
@@ -2317,18 +2314,17 @@ Debugger::findScripts(JSContext *cx, uns
 
     RootedObject result(cx, NewDenseAllocatedArray(cx, scripts.length(), NULL));
     if (!result)
         return false;
 
     result->ensureDenseArrayInitializedLength(cx, 0, scripts.length());
 
     for (size_t i = 0; i < scripts.length(); i++) {
-        JSObject *scriptObject =
-            dbg->wrapScript(cx, Handle<JSScript*>::fromMarkedLocation(&scripts[i]));
+        JSObject *scriptObject = dbg->wrapScript(cx, Rooted<JSScript*>(cx, scripts[i]));
         if (!scriptObject)
             return false;
         result->setDenseArrayElement(i, ObjectValue(*scriptObject));
     }
 
     args.rval().setObject(*result);
     return true;
 }
@@ -2536,23 +2532,21 @@ DebuggerScript_getChildScripts(JSContext
         return false;
     if (script->hasObjects()) {
         /*
          * script->savedCallerFun indicates that this is a direct eval script
          * and the calling function is stored as script->objects()->vector[0].
          * It is not really a child script of this script, so skip it.
          */
         ObjectArray *objects = script->objects();
-        Rooted<JSScript*> script(cx);
         for (uint32_t i = script->savedCallerFun ? 1 : 0; i < objects->length; i++) {
             JSObject *obj = objects->vector[i];
             if (obj->isFunction()) {
                 JSFunction *fun = static_cast<JSFunction *>(obj);
-                script = fun->script();
-                JSObject *s = dbg->wrapScript(cx, script);
+                JSObject *s = dbg->wrapScript(cx, Rooted<JSScript*>(cx, fun->script()));
                 if (!s || !js_NewbornArrayPush(cx, result, ObjectValue(*s)))
                     return false;
             }
         }
     }
     args.rval().setObject(*result);
     return true;
 }
@@ -3209,34 +3203,30 @@ DebuggerFrame_getArguments(JSContext *cx
         if (!proto)
             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);
-        unsigned fargc = fp->numActualArgs();
+        int32_t fargc = int32_t(fp->numActualArgs());
         if (!DefineNativeProperty(cx, argsobj, cx->runtime->atomState.lengthAtom,
                                   Int32Value(fargc), NULL, NULL,
                                   JSPROP_PERMANENT | JSPROP_READONLY, 0, 0))
         {
             return false;
         }
 
-        Rooted<jsid> id(cx);
-        for (unsigned i = 0; i < fargc; i++) {
+        for (int32_t i = 0; i < fargc; i++) {
             RootedFunction getobj(cx);
             getobj = js_NewFunction(cx, NULL, DebuggerArguments_getArg, 0, 0, global, NULL,
                                     JSFunction::ExtendedFinalizeKind);
-            if (!getobj)
-                return false;
-            id = INT_TO_JSID(i);
             if (!getobj ||
-                !DefineNativeProperty(cx, argsobj, id, UndefinedValue(),
+                !DefineNativeProperty(cx, argsobj, RootedId(cx, INT_TO_JSID(i)), UndefinedValue(),
                                       JS_DATA_TO_FUNC_PTR(PropertyOp, getobj.reference()), NULL,
                                       JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_GETTER, 0, 0))
             {
                 return false;
             }
             getobj->setExtendedSlot(0, Int32Value(i));
         }
     } else {
@@ -3252,28 +3242,27 @@ DebuggerFrame_getScript(JSContext *cx, u
 {
     THIS_FRAME(cx, argc, vp, "get script", args, thisobj, fp);
     Debugger *debug = Debugger::fromChildJSObject(thisobj);
 
     JSObject *scriptObject = NULL;
     if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
         JSFunction &callee = fp->callee();
         if (callee.isInterpreted()) {
-            Rooted<JSScript*> script(cx, callee.script());
-            scriptObject = debug->wrapScript(cx, script);
+            scriptObject = debug->wrapScript(cx, Rooted<JSScript*>(cx, callee.script()));
             if (!scriptObject)
                 return false;
         }
     } else if (fp->isScriptFrame()) {
         /*
          * We got eval, JS_Evaluate*, or JS_ExecuteScript non-function script
          * frames.
          */
-        Rooted<JSScript*> script(cx, fp->script());
-        scriptObject = debug->wrapScript(cx, script);
+        JSScript *script = fp->script();
+        scriptObject = debug->wrapScript(cx, Rooted<JSScript*>(cx, script));
         if (!scriptObject)
             return false;
     }
     args.rval().setObjectOrNull(scriptObject);
     return true;
 }
 
 static JSBool
@@ -3453,18 +3442,17 @@ DebuggerFrameEval(JSContext *cx, unsigne
         if (!bindingsobj ||
             !GetPropertyNames(cx, bindingsobj, JSITER_OWNONLY, &keys) ||
             !values.growBy(keys.length()))
         {
             return false;
         }
         for (size_t i = 0; i < keys.length(); i++) {
             Value *valp = &values[i];
-            if (!bindingsobj->getGeneric(cx, bindingsobj,
-                                         Handle<jsid>::fromMarkedLocation(&keys[i]), valp) ||
+            if (!bindingsobj->getGeneric(cx, bindingsobj, RootedId(cx, keys[i]), valp) ||
                 !dbg->unwrapDebuggeeValue(cx, valp))
             {
                 return false;
             }
         }
     }
 
     AutoCompartment ac(cx, fp->scopeChain());
@@ -3723,18 +3711,17 @@ DebuggerObject_getScript(JSContext *cx, 
     }
 
     JSFunction *fun = obj->toFunction();
     if (!fun->isInterpreted()) {
         args.rval().setUndefined();
         return true;
     }
 
-    Rooted<JSScript*> script(cx, fun->script());
-    JSObject *scriptObject = dbg->wrapScript(cx, script);
+    JSObject *scriptObject = dbg->wrapScript(cx, Rooted<JSScript*>(cx, fun->script()));
     if (!scriptObject)
         return false;
 
     args.rval().setObject(*scriptObject);
     return true;
 }
 
 static JSBool
@@ -3927,21 +3914,18 @@ DebuggerObject_defineProperties(JSContex
                 return false;
             if (!unwrappedDescs[i].wrapInto(cx, obj, ids[i], &rewrappedIds[i], &rewrappedDescs[i]))
                 return false;
         }
 
         ErrorCopier ec(ac, dbg->toJSObject());
         for (size_t i = 0; i < n; i++) {
             bool dummy;
-            if (!DefineProperty(cx, obj, Handle<jsid>::fromMarkedLocation(&rewrappedIds[i]),
-                                rewrappedDescs[i], true, &dummy))
-            {
+            if (!DefineProperty(cx, obj, RootedId(cx, rewrappedIds[i]), rewrappedDescs[i], true, &dummy))
                 return false;
-            }
         }
     }
 
     args.rval().setUndefined();
     return true;
 }
 
 /*
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -92,26 +92,24 @@ RegExpObjectBuilder::clone(Handle<RegExp
      * the clone -- if the |RegExpStatics| provides more flags we'll
      * need a different |RegExpShared|.
      */
     RegExpStatics *res = cx->regExpStatics();
     RegExpFlag origFlags = other->getFlags();
     RegExpFlag staticsFlags = res->getFlags();
     if ((origFlags & staticsFlags) != staticsFlags) {
         RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags);
-        Rooted<JSAtom *> source(cx, other->getSource());
-        return build(source, newFlags);
+        return build(Rooted<JSAtom *>(cx, other->getSource()), newFlags);
     }
 
     RegExpGuard g;
     if (!other->getShared(cx, &g))
         return NULL;
 
-    Rooted<JSAtom *> source(cx, other->getSource());
-    return build(source, *g);
+    return build(RootedAtom(cx, other->getSource()), *g);
 }
 
 /* MatchPairs */
 
 MatchPairs *
 MatchPairs::create(LifoAlloc &alloc, size_t pairCount, size_t backingPairCount)
 {
     void *mem = alloc.alloc(calculateSize(backingPairCount));
@@ -615,22 +613,24 @@ RegExpCompartment::get(JSContext *cx, JS
         return false;
 
     return get(cx, atom, flags, g);
 }
 
 /* Functions */
 
 JSObject *
-js::CloneRegExpObject(JSContext *cx, JSObject *obj_, JSObject *proto_)
+js::CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto)
 {
+    JS_ASSERT(obj->isRegExp());
+    JS_ASSERT(proto->isRegExp());
+
     RegExpObjectBuilder builder(cx);
-    Rooted<RegExpObject*> regex(cx, &obj_->asRegExp());
-    Rooted<RegExpObject*> proto(cx, &proto_->asRegExp());
-    return builder.clone(regex, proto);
+    return builder.clone(Rooted<RegExpObject*>(cx, &obj->asRegExp()),
+                         Rooted<RegExpObject*>(cx, &proto->asRegExp()));
 }
 
 bool
 js::ParseRegExpFlags(JSContext *cx, JSString *flagStr, RegExpFlag *flagsOut)
 {
     size_t n = flagStr->length();
     const jschar *s = flagStr->getChars(cx);
     if (!s)
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -114,18 +114,17 @@ CallObject::create(JSContext *cx, JSScri
 
     /*
      * Update the parent for bindings associated with non-compileAndGo scripts,
      * whose call objects do not have a consistent global variable and need
      * to be updated dynamically.
      */
     if (&enclosing->global() != obj->getParent()) {
         JS_ASSERT(obj->getParent() == NULL);
-        Rooted<GlobalObject*> global(cx, &enclosing->global());
-        if (!JSObject::setParent(cx, obj, global))
+        if (!JSObject::setParent(cx, obj, RootedObject(cx, &enclosing->global())))
             return NULL;
     }
 
     if (!obj->asScope().setEnclosingScope(cx, enclosing))
         return NULL;
 
     obj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
 
@@ -154,18 +153,17 @@ CallObject::createForFunction(JSContext 
      */
     if (js_IsNamedLambda(fp->fun())) {
         scopeChain = DeclEnvObject::create(cx, fp);
         if (!scopeChain)
             return NULL;
     }
 
     RootedScript script(cx, fp->script());
-    Rooted<JSFunction*> callee(cx, &fp->callee());
-    CallObject *callobj = create(cx, script, scopeChain, callee);
+    CallObject *callobj = create(cx, script, scopeChain, RootedFunction(cx, &fp->callee()));
     if (!callobj)
         return NULL;
 
     /* Copy in the closed-over formal arguments. */
     if (script->bindingsAccessedDynamically) {
         Value *formals = fp->formals();
         for (unsigned slot = 0, n = fp->fun()->nargs; slot < n; ++slot)
             callobj->setArg(slot, formals[slot]);
@@ -209,18 +207,17 @@ CallObject::copyUnaliasedValues(StackFra
 
 CallObject *
 CallObject::createForStrictEval(JSContext *cx, StackFrame *fp)
 {
     JS_ASSERT(fp->isStrictEvalFrame());
     JS_ASSERT(cx->fp() == fp);
     JS_ASSERT(cx->regs().pc == fp->script()->code);
 
-    Rooted<JSFunction*> callee(cx, NULL);
-    return create(cx, fp->script(), fp->scopeChain(), callee);
+    return create(cx, fp->script(), fp->scopeChain(), RootedFunction(cx));
 }
 
 JSBool
 CallObject::setArgOp(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, Value *vp)
 {
     CallObject &callobj = obj->asCall();
 
     JS_ASSERT((int16_t) JSID_TO_INT(id) == JSID_TO_INT(id));
@@ -301,18 +298,18 @@ DeclEnvObject::create(JSContext *cx, Sta
     RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, emptyDeclEnvShape, type, NULL));
     if (!obj)
         return NULL;
 
     if (!obj->asScope().setEnclosingScope(cx, fp->scopeChain()))
         return NULL;
 
 
-    Rooted<jsid> id(cx, AtomToId(fp->fun()->atom));
-    if (!DefineNativeProperty(cx, obj, id, ObjectValue(fp->callee()), NULL, NULL,
+    if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(fp->fun()->atom)),
+                              ObjectValue(fp->callee()), NULL, NULL,
                               JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY,
                               0, 0)) {
         return NULL;
     }
 
     return &obj->asDeclEnv();
 }
 
@@ -352,64 +349,60 @@ static JSBool
 with_LookupGeneric(JSContext *cx, HandleObject obj, HandleId id, JSObject **objp, JSProperty **propp)
 {
     return obj->asWith().object().lookupGeneric(cx, id, objp, propp);
 }
 
 static JSBool
 with_LookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return with_LookupGeneric(cx, obj, id, objp, propp);
+    return with_LookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
 }
 
 static JSBool
 with_LookupElement(JSContext *cx, HandleObject obj, uint32_t index, JSObject **objp,
                    JSProperty **propp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return with_LookupGeneric(cx, obj, id, objp, propp);
 }
 
 static JSBool
 with_LookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSObject **objp, JSProperty **propp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return with_LookupGeneric(cx, obj, id, objp, propp);
+    return with_LookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
 }
 
 static JSBool
 with_GetGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id, Value *vp)
 {
     return obj->asWith().object().getGeneric(cx, id, vp);
 }
 
 static JSBool
 with_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name, Value *vp)
 {
-    Rooted<jsid> id(cx, NameToId(name));
-    return with_GetGeneric(cx, obj, receiver, id, vp);
+    return with_GetGeneric(cx, obj, receiver, RootedId(cx, NameToId(name)), vp);
 }
 
 static JSBool
 with_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index, Value *vp)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return with_GetGeneric(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 with_GetSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid, Value *vp)
 {
-    Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
-    return with_GetGeneric(cx, obj, receiver, id, vp);
+    return with_GetGeneric(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
 }
 
 static JSBool
 with_SetGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool strict)
 {
     return obj->asWith().object().setGeneric(cx, id, vp, strict);
 }
 
@@ -589,18 +582,17 @@ ClonedBlockObject::create(JSContext *cx,
 
     RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, shape, type, slots));
     if (!obj)
         return NULL;
 
     /* Set the parent if necessary, as for call objects. */
     if (&fp->global() != obj->getParent()) {
         JS_ASSERT(obj->getParent() == NULL);
-        Rooted<GlobalObject*> global(cx, &fp->global());
-        if (!JSObject::setParent(cx, obj, global))
+        if (!JSObject::setParent(cx, obj, RootedObject(cx, &fp->global())))
             return NULL;
     }
 
     JS_ASSERT(!obj->inDictionaryMode());
     JS_ASSERT(obj->slotSpan() >= block->slotCount() + RESERVED_SLOTS);
 
     obj->setReservedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*fp->scopeChain()));
     obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(block->stackDepth()));
@@ -1328,31 +1320,28 @@ class DebugScopeProxy : public BaseProxy
         if (maybeArgsObj) {
             *vp = ObjectValue(*maybeArgsObj);
             return true;
         }
 
         if (handleUnaliasedAccess(cx, scope, id, GET, vp))
             return true;
 
-        Rooted<ScopeObject*> scopeObj(cx, &scope);
-        Rooted<jsid> idRoot(cx, id);
-        return scope.getGeneric(cx, scopeObj, idRoot, vp);
+        return scope.getGeneric(cx, RootedObject(cx, &scope), RootedId(cx, id), vp);
     }
 
-    bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id_, bool strict,
+    bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict,
                      Value *vp) MOZ_OVERRIDE
     {
         ScopeObject &scope = proxy->asDebugScope().scope();
 
-        if (handleUnaliasedAccess(cx, scope, id_, SET, vp))
+        if (handleUnaliasedAccess(cx, scope, id, SET, vp))
             return true;
 
-        Rooted<jsid> id(cx, id_);
-        return scope.setGeneric(cx, id, vp, strict);
+        return scope.setGeneric(cx, RootedId(cx, id), vp, strict);
     }
 
     bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) MOZ_OVERRIDE
     {
         bool found;
         if (!has(cx, proxy, id, &found))
             return false;
         if (found)
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -4077,30 +4077,30 @@ nsXPCComponents_Utils::GetGlobalForObjec
   if (JSVAL_IS_PRIMITIVE(object))
     return NS_ERROR_XPC_BAD_CONVERT_JS;
 
   // Wrappers are parented to their the global in their home compartment. But
   // when getting the global for a cross-compartment wrapper, we really want
   // a wrapper for the foreign global. So we need to unwrap before getting the
   // parent, enter the compartment for the duration of the call, and wrap the
   // result.
-  JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
+  JSObject *obj = JSVAL_TO_OBJECT(object);
   obj = js::UnwrapObject(obj);
   {
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
       return NS_ERROR_FAILURE;
     obj = JS_GetGlobalForObject(cx, obj);
   }
-  JS_WrapObject(cx, obj.address());
+  JS_WrapObject(cx, &obj);
   *retval = OBJECT_TO_JSVAL(obj);
 
   // Outerize if necessary.
   if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
-      *retval = OBJECT_TO_JSVAL(outerize(cx, obj));
+      *retval = OBJECT_TO_JSVAL(outerize(cx, JS::RootedObject(cx, obj)));
 
   return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::CreateObjectIn(const jsval &vobj, JSContext *cx, jsval *rval)
 {
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -4,37 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Implementations of runtime and static assertion macros for C and C++. */
 
 #ifndef mozilla_Assertions_h_
 #define mozilla_Assertions_h_
 
 #include "mozilla/Attributes.h"
+#include "mozilla/Types.h"
 
-#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef WIN32
-   /*
-    * TerminateProcess and GetCurrentProcess are defined in <winbase.h>, which
-    * further depends on <windef.h>.  We hardcode these few definitions manually
-    * because those headers clutter the global namespace with a significant
-    * number of undesired macros and symbols.
-    */
-#  ifdef __cplusplus
-   extern "C" {
-#  endif
-   __declspec(dllimport) int __stdcall
-   TerminateProcess(void* hProcess, unsigned int uExitCode);
-   __declspec(dllimport) void* __stdcall GetCurrentProcess(void);
-#  ifdef __cplusplus
-   }
-#  endif
-#else
+#ifndef WIN32
 #  include <signal.h>
 #endif
 #ifdef ANDROID
 #  include <android/log.h>
 #endif
 
 /*
  * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time*.  This
@@ -131,40 +115,32 @@ extern "C" {
  * in release builds as well as debug builds.  But if the failure is one that
  * should be debugged and fixed, MOZ_ASSERT is generally preferable.
  */
 #if defined(_MSC_VER)
    /*
     * On MSVC use the __debugbreak compiler intrinsic, which produces an inline
     * (not nested in a system function) breakpoint.  This distinctively invokes
     * Breakpad without requiring system library symbols on all stack-processing
-    * machines, as a nested breakpoint would require.  We use TerminateProcess
-    * with the exit code aborting would generate because we don't want to invoke
-    * atexit handlers, destructors, library unload handlers, and so on when our
-    * process might be in a compromised state.  We don't use abort() because
-    * it'd cause Windows to annoyingly pop up the process error dialog multiple
-    * times.  See bug 345118 and bug 426163.
-    *
-    * (Technically these are Windows requirements, not MSVC requirements.  But
-    * practically you need MSVC for debugging, and we only ship builds created
-    * by MSVC, so doing it this way reduces complexity.)
+    * machines, as a nested breakpoint would require.  (Technically all Windows
+    * compilers would require this, but practically only MSVC matters.)
     */
 #  ifdef __cplusplus
 #    define MOZ_CRASH() \
        do { \
          __debugbreak(); \
          *((volatile int*) NULL) = 123; \
-         ::TerminateProcess(::GetCurrentProcess(), 3); \
+         ::exit(3); \
        } while (0)
 #  else
 #    define MOZ_CRASH() \
        do { \
          __debugbreak(); \
          *((volatile int*) NULL) = 123; \
-         TerminateProcess(GetCurrentProcess(), 3); \
+         exit(3); \
        } while (0)
 #  endif
 #else
 #  ifdef __cplusplus
 #    define MOZ_CRASH() \
        do { \
          *((volatile int*) NULL) = 123; \
          ::abort(); \
--- a/mfbt/HashFunctions.cpp
+++ b/mfbt/HashFunctions.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Implementations of hash functions. */
 
 #include "mozilla/HashFunctions.h"
-#include "mozilla/Types.h"
 
 #include <string.h>
 
 namespace mozilla {
 
 MFBT_API(uint32_t)
 HashBytes(const void* bytes, size_t length)
 {
--- a/mfbt/HashFunctions.h
+++ b/mfbt/HashFunctions.h
@@ -43,17 +43,16 @@
  */
 
 #ifndef mozilla_HashFunctions_h_
 #define mozilla_HashFunctions_h_
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/StandardInteger.h"
-#include "mozilla/Types.h"
 
 #ifdef __cplusplus
 namespace mozilla {
 
 /**
  * The golden ratio as a 32-bit fixed-point value.
  */
 static const uint32_t GoldenRatioU32 = 0x9E3779B9U;
--- a/mfbt/Scoped.h
+++ b/mfbt/Scoped.h
@@ -30,35 +30,33 @@
  * // ... In this scope, |foo| is defined. Use |foo.get()| or |foo.rwget()|
  *        to access the value.
  * // ... In case of |return| or |throw|, |foo| is deallocated automatically.
  * // ... If |foo| needs to be returned or stored, use |foo.forget()|
  *
  * Note that the RAII classes defined in this header do _not_ perform any form
  * of reference-counting or garbage-collection. These classes have exactly two
  * behaviors:
- *
  * - if |forget()| has not been called, the resource is always deallocated at
  *   the end of the scope;
  * - if |forget()| has been called, any control on the resource is unbound
  *   and the resource is not deallocated by the class.
  *
+ *
  * Extension:
  *
  * In addition, this header provides class |Scoped| and macro |SCOPED_TEMPLATE|
  * to simplify the definition of RAII classes for other scenarios. These macros
  * have been used to automatically close file descriptors/file handles when
  * reaching the end of the scope, graphics contexts, etc.
  */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
 
-namespace mozilla {
-
 /*
  * Scoped is a helper to create RAII wrappers
  * Type argument |Traits| is expected to have the following structure:
  *
  *   struct Traits {
  *     // Define the type of the value stored in the wrapper
  *     typedef value_type type;
  *     // Returns the value corresponding to the uninitialized or freed state
@@ -156,19 +154,19 @@ class Scoped
  * This allows to implement templates such as ScopedFreePtr.
  *
  * @param name The name of the class to define.
  * @param Traits A struct implementing clean-up. See the implementations
  * for more details.
  */
 #define SCOPED_TEMPLATE(name, Traits)                          \
 template<typename Type>                                        \
-struct name : public mozilla::Scoped<Traits<Type> >            \
+struct name : public Scoped<Traits<Type> >                     \
 {                                                              \
-    typedef mozilla::Scoped<Traits<Type> > Super;              \
+    typedef Scoped<Traits<Type> > Super;                       \
     typedef typename Super::Resource Resource;                 \
     name& operator=(Resource ptr) {                            \
       Super::operator=(ptr);                                   \
       return *this;                                            \
     }                                                          \
     explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)        \
       : Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT)  \
     {}                                                         \
@@ -218,11 +216,9 @@ SCOPED_TEMPLATE(ScopedDeletePtr, ScopedD
  */
 template<typename T>
 struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
 {
     static void release(T* ptr) { delete [] ptr; }
 };
 SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
 
-} /* namespace mozilla */
-
 #endif // mozilla_Scoped_h_