Bug 858107 - GC: Some more rooting in XPConnect - misc rooting r=bholley
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 03 Apr 2013 13:43:04 +0100
changeset 139257 a2fbe8dc1ee1f7056372b144b561bd73df4f69b1
parent 139256 53f30efb50b05d2c14ee61a2398366563e9c206a
child 139258 1348d28d70fcbceeaaf366c36962ecab1d79ffa9
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs858107
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 858107 - GC: Some more rooting in XPConnect - misc rooting r=bholley
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCStack.cpp
js/xpconnect/src/XPCString.cpp
js/xpconnect/src/XPCThrower.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedNativeProto.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/XPCWrapper.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCCallContext.cpp
+++ b/js/xpconnect/src/XPCCallContext.cpp
@@ -9,42 +9,36 @@
 #include "mozilla/Util.h"
 #include "AccessCheck.h"
 
 #include "xpcprivate.h"
 
 using namespace mozilla;
 using namespace xpc;
 
-static inline JSContext *
-GetSafeJSContext()
-{
-    return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContext();
-}
-
 XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
                                JSContext* cx    /* = nullptr    */,
                                JSObject* obj    /* = nullptr    */,
                                JSObject* funobj /* = nullptr    */,
                                jsid name        /* = JSID_VOID */,
                                unsigned argc    /* = NO_ARGS   */,
                                jsval *argv      /* = nullptr    */,
                                jsval *rval      /* = nullptr    */)
     :   mState(INIT_FAILED),
         mXPC(nsXPConnect::GetXPConnect()),
         mXPCContext(nullptr),
         mJSContext(cx),
         mContextPopRequired(false),
         mDestroyJSContextInDestructor(false),
         mCallerLanguage(callerLanguage),
-        mScopeForNewJSObjects(GetSafeJSContext()),
-        mFlattenedJSObject(GetSafeJSContext()),
+        mScopeForNewJSObjects(xpc_GetSafeJSContext()),
+        mFlattenedJSObject(xpc_GetSafeJSContext()),
         mWrapper(nullptr),
         mTearOff(nullptr),
-        mName(GetSafeJSContext())
+        mName(xpc_GetSafeJSContext())
 {
     Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj,
          INIT_SHOULD_LOOKUP_WRAPPER, name, argc, argv, rval);
 }
 
 XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
                                JSContext* cx,
                                JSBool callBeginRequest,
@@ -54,21 +48,21 @@ XPCCallContext::XPCCallContext(XPCContex
                                XPCWrappedNativeTearOff* tearOff)
     :   mState(INIT_FAILED),
         mXPC(nsXPConnect::GetXPConnect()),
         mXPCContext(nullptr),
         mJSContext(cx),
         mContextPopRequired(false),
         mDestroyJSContextInDestructor(false),
         mCallerLanguage(callerLanguage),
-        mScopeForNewJSObjects(GetSafeJSContext()),
-        mFlattenedJSObject(GetSafeJSContext(), flattenedJSObject),
+        mScopeForNewJSObjects(xpc_GetSafeJSContext()),
+        mFlattenedJSObject(xpc_GetSafeJSContext(), flattenedJSObject),
         mWrapper(wrapper),
         mTearOff(tearOff),
-        mName(GetSafeJSContext())
+        mName(xpc_GetSafeJSContext())
 {
     Init(callerLanguage, callBeginRequest, obj, nullptr,
          WRAPPER_PASSED_TO_CONSTRUCTOR, JSID_VOID, NO_ARGS,
          nullptr, nullptr);
 }
 
 #define IS_TEAROFF_CLASS(clazz) ((clazz) == &XPC_WN_Tearoff_JSClass)
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3330,17 +3330,17 @@ xpc_CreateSandboxObject(JSContext *cx, j
       AccessCheck::isChrome(sandbox) ? false : options.wantXrays;
 
     JS::AutoObjectRooter tvr(cx, sandbox);
 
     {
         JSAutoCompartment ac(cx, sandbox);
 
         if (options.proto) {
-            bool ok = JS_WrapObject(cx, &options.proto);
+            bool ok = JS_WrapObject(cx, options.proto.address());
             if (!ok)
                 return NS_ERROR_XPC_UNEXPECTED;
 
             if (xpc::WrapperFactory::IsXrayWrapper(options.proto) && !options.wantXrays) {
                 jsval v = OBJECT_TO_JSVAL(options.proto);
                 if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v))
                     return NS_ERROR_FAILURE;
                 options.proto = JSVAL_TO_OBJECT(v);
@@ -3645,17 +3645,17 @@ GetStringPropFromOptions(JSContext *cx, 
 
 // helper that parsing the sandbox options object (from) and sets the fields of the incoming options struct (options)
 nsresult
 ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options)
 {
     NS_ENSURE_TRUE(from.isObject(), NS_ERROR_INVALID_ARG);
     JSObject &optionsObject = from.toObject();
     nsresult rv = GetObjPropFromOptions(cx, optionsObject,
-                                        "sandboxPrototype", &options.proto);
+                                        "sandboxPrototype", options.proto.address());
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = GetBoolPropFromOptions(cx, optionsObject,
                                 "wantXrays", &options.wantXrays);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = GetBoolPropFromOptions(cx, optionsObject,
                                 "wantComponents", &options.wantComponents);
@@ -3665,17 +3665,17 @@ ParseOptionsObject(JSContext *cx, jsval 
                                 "wantXHRConstructor", &options.wantXHRConstructor);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = GetStringPropFromOptions(cx, optionsObject,
                                   "sandboxName", options.sandboxName);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = GetObjPropFromOptions(cx, optionsObject,
-                               "sameZoneAs", &options.sameZoneAs);
+                               "sameZoneAs", options.sameZoneAs.address());
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 static nsresult
 AssembleSandboxMemoryReporterName(JSContext *cx, nsCString &sandboxName)
 {
@@ -3741,17 +3741,17 @@ nsXPCComponents_utils_Sandbox::CallOrCon
         }
     } else {
         return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
     }
 
     if (NS_FAILED(rv))
         return ThrowAndFail(rv, cx, _retval);
 
-    SandboxOptions options;
+    SandboxOptions options(cx);
 
     if (argc > 1 && NS_FAILED(ParseOptionsObject(cx, argv[1], options)))
         return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
 
     if (NS_FAILED(AssembleSandboxMemoryReporterName(cx, options.sandboxName)))
         return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
 
     rv = xpc_CreateSandboxObject(cx, vp, prinOrSop, options);
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -168,17 +168,17 @@ XPCJSContextStack::GetSafeJSContext()
     JSRuntime *rt = xpcrt->GetJSRuntime();
     if (!rt)
         return NULL;
 
     mSafeJSContext = JS_NewContext(rt, 8192);
     if (!mSafeJSContext)
         return NULL;
 
-    JSObject *glob;
+    JS::RootedObject glob(mSafeJSContext);
     {
         // scoped JS Request
         JSAutoRequest req(mSafeJSContext);
 
         JS_SetErrorReporter(mSafeJSContext, mozJSLoaderErrorReporter);
 
         glob = xpc::CreateGlobalObject(mSafeJSContext, &global_class, principal, JS::SystemZone);
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -3016,17 +3016,17 @@ XPCJSRuntime::RemoveGCCallback(JSGCCallb
 }
 
 JSObject *
 XPCJSRuntime::GetJunkScope()
 {
     if (!mJunkScope) {
         JS::Value v;
         SafeAutoJSContext cx;
-        SandboxOptions options;
+        SandboxOptions options(cx);
         options.sandboxName.AssignASCII("XPConnect Junk Compartment");
         JSAutoRequest ac(cx);
         nsresult rv = xpc_CreateSandboxObject(cx, &v,
                                               nsContentUtils::GetSystemPrincipal(),
                                               options);
 
         NS_ENSURE_SUCCESS(rv, nullptr);
 
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -16,38 +16,38 @@ NS_IMPL_ISUPPORTS1(xpcJSWeakReference, x
 
 nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
 {
     JSAutoRequest ar(cx);
 
     if (!object.isObject())
         return NS_OK;
 
-    JSObject& obj = object.toObject();
+    JS::RootedObject obj(cx, &object.toObject());
 
     XPCCallContext ccx(NATIVE_CALLER, cx);
 
     // See if the object is a wrapped native that supports weak references.
     nsISupports* supports =
-        nsXPConnect::GetXPConnect()->GetNativeOfWrapper(cx, &obj);
+        nsXPConnect::GetXPConnect()->GetNativeOfWrapper(cx, obj);
     nsCOMPtr<nsISupportsWeakReference> supportsWeakRef =
         do_QueryInterface(supports);
     if (supportsWeakRef) {
         supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent));
         if (mReferent) {
             return NS_OK;
         }
     }
     // If it's not a wrapped native, or it is a wrapped native that does not
     // support weak references, fall back to getting a weak ref to the object.
 
     // See if object is a wrapped JSObject.
     nsRefPtr<nsXPCWrappedJS> wrapped;
     nsresult rv = nsXPCWrappedJS::GetNewOrUsed(ccx,
-                                               &obj,
+                                               obj,
                                                NS_GET_IID(nsISupports),
                                                nullptr,
                                                getter_AddRefs(wrapped));
     if (!wrapped) {
         NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
         return rv;
     }
 
@@ -72,26 +72,26 @@ xpcJSWeakReference::Get(JSContext* aCx, 
     if (!wrappedObj) {
         // We have a generic XPCOM object that supports weak references here.
         // Wrap it and pass it out.
         return nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
                                           supports, &NS_GET_IID(nsISupports),
                                           aRetval);
     }
 
-    JSObject *obj;
-    wrappedObj->GetJSObject(&obj);
+    JS::RootedObject obj(aCx);
+    wrappedObj->GetJSObject(obj.address());
     if (!obj) {
         return NS_OK;
     }
 
     // Most users of XPCWrappedJS don't need to worry about
     // re-wrapping because things are implicitly rewrapped by
     // xpcconvert. However, because we're doing this directly
     // through the native call context, we need to call
     // JS_WrapObject().
-    if (!JS_WrapObject(aCx, &obj)) {
+    if (!JS_WrapObject(aCx, obj.address())) {
         return NS_ERROR_FAILURE;
     }
 
     *aRetval = OBJECT_TO_JSVAL(obj);
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCStack.cpp
+++ b/js/xpconnect/src/XPCStack.cpp
@@ -111,17 +111,17 @@ XPCJSStackFrame::CreateStack(JSContext* 
                 nsMemory::Clone(filename,
                                 sizeof(char)*(strlen(filename)+1));
         }
 
         self->mLineno = desc->frames[i].lineno;
 
         JSFunction* fun = desc->frames[i].fun;
         if (fun) {
-            JSString *funid = JS_GetFunctionDisplayId(fun);
+            JS::RootedString funid(cx, JS_GetFunctionDisplayId(fun));
             if (funid) {
                 size_t length = JS_GetStringEncodingLength(cx, funid);
                 if (length != size_t(-1)) {
                     self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
                     if (self->mFunname) {
                         JS_EncodeStringToBuffer(cx, funid, self->mFunname, length);
                         self->mFunname[length] = '\0';
                     }
--- a/js/xpconnect/src/XPCString.cpp
+++ b/js/xpconnect/src/XPCString.cpp
@@ -61,19 +61,19 @@ XPCStringConvert::ReadableToJSVal(JSCont
 
     uint32_t length = readable.Length();
 
     if (length == 0)
         return JS_GetEmptyStringValue(cx);
 
     nsStringBuffer *buf = nsStringBuffer::FromString(readable);
     if (buf) {
-        JS::Value val;
+        JS::RootedValue val(cx);
         bool shared;
-        bool ok = StringBufferToJSVal(cx, buf, length, &val, &shared);
+        bool ok = StringBufferToJSVal(cx, buf, length, val.address(), &shared);
         if (!ok) {
             return JS::NullValue();
         }
 
         if (shared) {
             *sharedBuffer = buf;
         }
         return val;
--- a/js/xpconnect/src/XPCThrower.cpp
+++ b/js/xpconnect/src/XPCThrower.cpp
@@ -223,41 +223,41 @@ IsCallerChrome(JSContext* cx)
 
 // static
 JSBool
 XPCThrower::ThrowExceptionObject(JSContext* cx, nsIException* e)
 {
     JSBool success = false;
     if (e) {
         nsCOMPtr<nsIXPCException> xpcEx;
-        jsval thrown;
+        JS::RootedValue thrown(cx);
         nsXPConnect* xpc;
 
         // If we stored the original thrown JS value in the exception
         // (see XPCConvert::ConstructException) and we are in a web
         // context (i.e., not chrome), rethrow the original value.
         if (!IsCallerChrome(cx) &&
             (xpcEx = do_QueryInterface(e)) &&
-            NS_SUCCEEDED(xpcEx->StealJSVal(&thrown))) {
-            if (!JS_WrapValue(cx, &thrown))
+            NS_SUCCEEDED(xpcEx->StealJSVal(thrown.address()))) {
+            if (!JS_WrapValue(cx, thrown.address()))
                 return false;
             JS_SetPendingException(cx, thrown);
             success = true;
         } else if ((xpc = nsXPConnect::GetXPConnect())) {
-            JSObject* glob = JS_GetGlobalForScopeChain(cx);
+            JS::RootedObject glob(cx, JS_GetGlobalForScopeChain(cx));
             if (!glob)
                 return false;
 
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             nsresult rv = xpc->WrapNative(cx, glob, e,
                                           NS_GET_IID(nsIException),
                                           getter_AddRefs(holder));
             if (NS_SUCCEEDED(rv) && holder) {
-                JSObject* obj;
-                if (NS_SUCCEEDED(holder->GetJSObject(&obj))) {
+                JS::RootedObject obj(cx);
+                if (NS_SUCCEEDED(holder->GetJSObject(obj.address()))) {
                     JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
                     success = true;
                 }
             }
         }
     }
     return success;
 }
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -272,18 +272,18 @@ CheckMainThreadOnly(nsXPCWrappedJS *aWra
 // static
 nsresult
 nsXPCWrappedJS::GetNewOrUsed(JSContext* cx,
                              JSObject* aJSObj,
                              REFNSIID aIID,
                              nsISupports* aOuter,
                              nsXPCWrappedJS** wrapperResult)
 {
+    JS::RootedObject jsObj(cx, aJSObj);
     JSObject2WrappedJSMap* map;
-    JSObject* rootJSObj;
     nsXPCWrappedJS* root = nullptr;
     nsXPCWrappedJS* wrapper = nullptr;
     nsXPCWrappedJSClass* clazz = nullptr;
     XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
     JSBool release_root = false;
 
     map = rt->GetWrappedJSMap();
     if (!map) {
@@ -292,17 +292,17 @@ nsXPCWrappedJS::GetNewOrUsed(JSContext* 
     }
 
     nsXPCWrappedJSClass::GetNewOrUsed(cx, aIID, &clazz);
     if (!clazz)
         return NS_ERROR_FAILURE;
     // from here on we need to return through 'return_wrapper'
 
     // always find the root JSObject
-    rootJSObj = clazz->GetRootJSObject(cx, aJSObj);
+    JS::RootedObject rootJSObj(cx, clazz->GetRootJSObject(cx, jsObj));
     if (!rootJSObj)
         goto return_wrapper;
 
     // look for the root wrapper, and if found, hold the map lock until
     // we've added our ref to prevent another thread from destroying it
     // under us
     {   // scoped lock
         XPCAutoLock lock(rt->GetMapLock());
@@ -313,27 +313,27 @@ nsXPCWrappedJS::GetNewOrUsed(JSContext* 
                 NS_ADDREF(wrapper);
                 goto return_wrapper;
             }
         }
     }
 
     if (!root) {
         // build the root wrapper
-        if (rootJSObj == aJSObj) {
+        if (rootJSObj == jsObj) {
             // the root will do double duty as the interface wrapper
-            wrapper = root = new nsXPCWrappedJS(cx, aJSObj, clazz, nullptr,
+            wrapper = root = new nsXPCWrappedJS(cx, jsObj, clazz, nullptr,
                                                 aOuter);
             if (!root)
                 goto return_wrapper;
 
             {   // scoped lock
 #if DEBUG_xpc_leaks
                 printf("Created nsXPCWrappedJS %p, JSObject is %p\n",
-                       (void*)wrapper, (void*)aJSObj);
+                       (void*)wrapper, (void*)jsObj);
 #endif
                 XPCAutoLock lock(rt->GetMapLock());
                 map->Add(root);
             }
 
             if (!CheckMainThreadOnly(root)) {
                 XPCAutoLock lock(rt->GetMapLock());
                 map->Remove(root);
@@ -376,22 +376,22 @@ nsXPCWrappedJS::GetNewOrUsed(JSContext* 
         }
     }
 
     // at this point we have a root and may need to build the specific wrapper
     NS_ASSERTION(root,"bad root");
     NS_ASSERTION(clazz,"bad clazz");
 
     if (!wrapper) {
-        wrapper = new nsXPCWrappedJS(cx, aJSObj, clazz, root, aOuter);
+        wrapper = new nsXPCWrappedJS(cx, jsObj, clazz, root, aOuter);
         if (!wrapper)
             goto return_wrapper;
 #if DEBUG_xpc_leaks
         printf("Created nsXPCWrappedJS %p, JSObject is %p\n",
-               (void*)wrapper, (void*)aJSObj);
+               (void*)wrapper, (void*)jsObj);
 #endif
     }
 
     wrapper->mNext = root->mNext;
     root->mNext = wrapper;
 
 return_wrapper:
     if (clazz)
--- a/js/xpconnect/src/XPCWrappedNativeProto.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeProto.cpp
@@ -66,38 +66,36 @@ XPCWrappedNativeProto::Init(XPCCallConte
         mScriptableInfo =
             XPCNativeScriptableInfo::Construct(ccx, scriptableCreateInfo);
         if (!mScriptableInfo)
             return false;
     }
 
     js::Class* jsclazz;
 
-
     if (mScriptableInfo) {
         const XPCNativeScriptableFlags& flags(mScriptableInfo->GetFlags());
 
         if (flags.AllowPropModsToPrototype()) {
             jsclazz = flags.WantCall() ?
                 &XPC_WN_ModsAllowed_WithCall_Proto_JSClass :
                 &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
         } else {
             jsclazz = flags.WantCall() ?
                 &XPC_WN_NoMods_WithCall_Proto_JSClass :
                 &XPC_WN_NoMods_NoCall_Proto_JSClass;
         }
     } else {
         jsclazz = &XPC_WN_NoMods_NoCall_Proto_JSClass;
     }
 
-    JSObject *parent = mScope->GetGlobalJSObject();
-
+    JS::RootedObject parent(ccx, mScope->GetGlobalJSObject());
+    JS::RootedObject proto(ccx, JS_GetObjectPrototype(ccx, parent));
     mJSProtoObject = JS_NewObjectWithUniqueType(ccx, js::Jsvalify(jsclazz),
-                                                JS_GetObjectPrototype(ccx, parent),
-                                                parent);
+                                                proto, parent);
 
     bool success = !!mJSProtoObject;
     if (success) {
         JS_SetPrivate(mJSProtoObject, this);
         if (callPostCreatePrototype)
             success = CallPostCreatePrototype(ccx);
     }
 
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -80,17 +80,17 @@ static void DEBUG_TrackScopeShutdown()
 
 /***************************************************************************/
 
 XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr;
 XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr;
 
 // static
 XPCWrappedNativeScope*
-XPCWrappedNativeScope::GetNewOrUsed(JSContext *cx, JSObject* aGlobal)
+XPCWrappedNativeScope::GetNewOrUsed(JSContext *cx, JS::HandleObject aGlobal)
 {
     XPCWrappedNativeScope* scope = GetObjectScope(aGlobal);
     if (!scope) {
         scope = new XPCWrappedNativeScope(cx, aGlobal);
     }
     return scope;
 }
 
@@ -113,17 +113,17 @@ RemoteXULForbidsXBLScope(nsIPrincipal *a
   if (!nsContentUtils::AllowXULXBLForPrincipal(aPrincipal))
       return false;
 
   // Check the pref to determine how we should behave.
   return !Preferences::GetBool("dom.use_xbl_scopes_for_remote_xul", false);
 }
 
 XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx,
-                                             JSObject* aGlobal)
+                                             JS::HandleObject aGlobal)
       : mWrappedNativeMap(Native2WrappedNativeMap::newMap(XPC_NATIVE_MAP_SIZE)),
         mWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_SIZE)),
         mMainThreadWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_SIZE)),
         mComponents(nullptr),
         mNext(nullptr),
         mGlobalJSObject(aGlobal),
         mPrototypeNoHelper(nullptr),
         mIsXBLScope(false)
@@ -202,26 +202,26 @@ XPCWrappedNativeScope::GetComponentsJSOb
     xpcObjectHelper helper(cholder);
     nsCOMPtr<XPCWrappedNative> wrapper;
     XPCWrappedNative::GetNewOrUsed(ccx, helper, this, iface, getter_AddRefs(wrapper));
     if (!wrapper)
         return nullptr;
 
     // The call to wrap() here is necessary even though the object is same-
     // compartment, because it applies our security wrapper.
-    JSObject *obj = wrapper->GetFlatJSObject();
-    if (!JS_WrapObject(ccx, &obj))
+    JS::RootedObject obj(ccx, wrapper->GetFlatJSObject());
+    if (!JS_WrapObject(ccx, obj.address()))
         return nullptr;
     return obj;
 }
 
 JSObject*
 XPCWrappedNativeScope::EnsureXBLScope(JSContext *cx)
 {
-    JSObject *global = GetGlobalJSObject();
+    JS::RootedObject global(cx, GetGlobalJSObject());
     MOZ_ASSERT(js::IsObjectInContextCompartment(global, cx));
     MOZ_ASSERT(!mIsXBLScope);
     MOZ_ASSERT(strcmp(js::GetObjectClass(global)->name,
                       "nsXBLPrototypeScript compilation scope"));
 
     // If we already have a special XBL scope object, we know what to use.
     if (mXBLScope)
         return mXBLScope;
@@ -233,48 +233,49 @@ XPCWrappedNativeScope::EnsureXBLScope(JS
     // Set up the sandbox options. Note that we use the DOM global as the
     // sandboxPrototype so that the XBL scope can access all the DOM objects
     // it's accustomed to accessing.
     //
     // NB: One would think that wantXrays wouldn't make a difference here.
     // However, wantXrays lives a secret double life, and one of its other
     // hobbies is to waive Xray on the returned sandbox when set to false.
     // So make sure to keep this set to true, here.
-    SandboxOptions options;
+    SandboxOptions options(cx);
     options.wantXrays = true;
     options.wantComponents = true;
     options.wantXHRConstructor = false;
     options.proto = global;
     options.sameZoneAs = global;
 
     // Use an nsExpandedPrincipal to create asymmetric security.
     nsIPrincipal *principal = GetPrincipal();
     nsCOMPtr<nsIExpandedPrincipal> ep;
     MOZ_ASSERT(!(ep = do_QueryInterface(principal)));
     nsTArray< nsCOMPtr<nsIPrincipal> > principalAsArray(1);
     principalAsArray.AppendElement(principal);
     ep = new nsExpandedPrincipal(principalAsArray);
 
     // Create the sandbox.
     JSAutoRequest ar(cx);
-    JS::Value v = JS::UndefinedValue();
-    nsresult rv = xpc_CreateSandboxObject(cx, &v, ep, options);
+    JS::RootedValue v(cx, JS::UndefinedValue());
+    nsresult rv = xpc_CreateSandboxObject(cx, v.address(), ep, options);
     NS_ENSURE_SUCCESS(rv, nullptr);
     mXBLScope = &v.toObject();
 
     // Tag it.
     EnsureCompartmentPrivate(js::UnwrapObject(mXBLScope))->scope->mIsXBLScope = true;
 
     // Good to go!
     return mXBLScope;
 }
 
 namespace xpc {
-JSObject *GetXBLScope(JSContext *cx, JSObject *contentScope)
+JSObject *GetXBLScope(JSContext *cx, JSObject *contentScope_)
 {
+    JS::RootedObject contentScope(cx, contentScope_);
     JSAutoCompartment ac(cx, contentScope);
     JSObject *scope = EnsureCompartmentPrivate(contentScope)->scope->EnsureXBLScope(cx);
     NS_ENSURE_TRUE(scope, nullptr); // See bug 858642.
     scope = js::UnwrapObject(scope);
     xpc_UnmarkGrayObject(scope);
     return scope;
 }
 
--- a/js/xpconnect/src/XPCWrapper.cpp
+++ b/js/xpconnect/src/XPCWrapper.cpp
@@ -23,22 +23,22 @@ ThrowException(nsresult ex, JSContext *c
 
 static JSBool
 UnwrapNW(JSContext *cx, unsigned argc, jsval *vp)
 {
   if (argc != 1) {
     return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
   }
 
-  jsval v = JS_ARGV(cx, vp)[0];
+  JS::RootedValue v(cx, JS_ARGV(cx, vp)[0]);
   if (JSVAL_IS_PRIMITIVE(v)) {
     return ThrowException(NS_ERROR_INVALID_ARG, cx);
   }
 
-  JSObject *obj = JSVAL_TO_OBJECT(v);
+  JS::RootedObject obj(cx, JSVAL_TO_OBJECT(v));
   if (!js::IsWrapper(obj)) {
     JS_SET_RVAL(cx, vp, v);
     return true;
   }
 
   if (WrapperFactory::IsXrayWrapper(obj) && AccessCheck::wrapperSubsumes(obj)) {
     return JS_GetProperty(cx, obj, "wrappedJSObject", vp);
   }
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -926,33 +926,34 @@ inline nsresult UnexpectedFailure(nsresu
 }
 
 /* void initClasses (in JSContextPtr aJSContext, in JSObjectPtr aGlobalJSObj); */
 NS_IMETHODIMP
 nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
 {
     NS_ASSERTION(aJSContext, "bad param");
     NS_ASSERTION(aGlobalJSObj, "bad param");
+    JS::RootedObject globalJSObj(aJSContext, aGlobalJSObj);
 
     // Nest frame chain save/restore in request created by XPCCallContext.
     XPCCallContext ccx(NATIVE_CALLER, aJSContext);
     if (!ccx.IsValid())
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
-    JSAutoCompartment ac(ccx, aGlobalJSObj);
+    JSAutoCompartment ac(ccx, globalJSObj);
 
     XPCWrappedNativeScope* scope =
-        XPCWrappedNativeScope::GetNewOrUsed(ccx, aGlobalJSObj);
+        XPCWrappedNativeScope::GetNewOrUsed(ccx, globalJSObj);
 
     if (!scope)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     scope->RemoveWrappedNativeProtos();
 
-    if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, aGlobalJSObj))
+    if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, globalJSObj))
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     return NS_OK;
 }
 
 #ifdef DEBUG
 struct VerifyTraceXPCGlobalCalledTracer
 {
@@ -1032,17 +1033,18 @@ CreateGlobalObject(JSContext *cx, JSClas
 {
     // Make sure that Type Inference is enabled for everything non-chrome.
     // Sandboxes and compilation scopes are exceptions. See bug 744034.
     CheckTypeInference(cx, clasp, principal);
 
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "using a principal off the main thread?");
     MOZ_ASSERT(principal);
 
-    JSObject *global = JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), zoneSpec);
+    JS::RootedObject global(cx,
+                            JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), zoneSpec));
     if (!global)
         return nullptr;
     JSAutoCompartment ac(cx, global);
     // The constructor automatically attaches the scope to the compartment private
     // of |global|.
     (void) new XPCWrappedNativeScope(cx, global);
 
 #ifdef DEBUG
@@ -1636,17 +1638,17 @@ nsXPConnect::CreateSandbox(JSContext *cx
     if (!ccx.IsValid())
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     *_retval = nullptr;
 
     jsval rval = JSVAL_VOID;
     AUTO_MARK_JSVAL(ccx, &rval);
 
-    SandboxOptions options;
+    SandboxOptions options(cx);
     nsresult rv = xpc_CreateSandboxObject(cx, &rval, principal, options);
     NS_ASSERTION(NS_FAILED(rv) || !JSVAL_IS_PRIMITIVE(rval),
                  "Bad return value from xpc_CreateSandboxObject()!");
 
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(rval)) {
         *_retval = XPCJSObjectHolder::newHolder(ccx, JSVAL_TO_OBJECT(rval));
         NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY);
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1578,17 +1578,17 @@ enum WrapperType {
 /***************************************************************************/
 // XPCWrappedNativeScope is one-to-one with a JS global object.
 
 class XPCWrappedNativeScope : public PRCList
 {
 public:
 
     static XPCWrappedNativeScope*
-    GetNewOrUsed(JSContext *cx, JSObject* aGlobal);
+    GetNewOrUsed(JSContext *cx, JS::HandleObject aGlobal);
 
     XPCJSRuntime*
     GetRuntime() const {return XPCJSRuntime::Get();}
 
     Native2WrappedNativeMap*
     GetWrappedNativeMap() const {return mWrappedNativeMap;}
 
     ClassInfo2WrappedNativeProtoMap*
@@ -1698,17 +1698,17 @@ public:
             mDOMExpandoMap->RemoveEntry(expando);
     }
 
     // Gets the appropriate scope object for XBL in this scope. The context
     // must be same-compartment with the global upon entering, and the scope
     // object is wrapped into the compartment of the global.
     JSObject *EnsureXBLScope(JSContext *cx);
 
-    XPCWrappedNativeScope(JSContext *cx, JSObject* aGlobal);
+    XPCWrappedNativeScope(JSContext *cx, JS::HandleObject aGlobal);
 
     nsAutoPtr<JSObject2JSObjectMap> mWaiverWrapperMap;
 
     bool IsXBLScope() { return mIsXBLScope; }
     bool AllowXBLScope() { return mAllowXBLScope; }
 
 protected:
     virtual ~XPCWrappedNativeScope();
@@ -4145,32 +4145,38 @@ public:
 // Utilities
 
 inline void *
 xpc_GetJSPrivate(JSObject *obj)
 {
     return js::GetObjectPrivate(obj);
 }
 
+inline JSContext *
+xpc_GetSafeJSContext()
+{
+    return XPCJSRuntime::Get()->GetJSContextStack()->GetSafeJSContext();
+}
+
 namespace xpc {
 struct SandboxOptions {
-    SandboxOptions()
+    SandboxOptions(JSContext *cx)
         : wantXrays(true)
         , wantComponents(true)
         , wantXHRConstructor(false)
-        , proto(NULL)
-        , sameZoneAs(NULL)
+        , proto(xpc_GetSafeJSContext())
+        , sameZoneAs(xpc_GetSafeJSContext())
     { }
 
     bool wantXrays;
     bool wantComponents;
     bool wantXHRConstructor;
-    JSObject* proto;
+    JS::RootedObject proto;
     nsCString sandboxName;
-    JSObject* sameZoneAs;
+    JS::RootedObject sameZoneAs;
 };
 
 JSObject *
 CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
                    JS::ZoneSpecifier zoneSpec);
 }
 
 // Helper for creating a sandbox object to use for evaluating