Backed out changeset eb7402ddbe54 (bug 873622) for Windows bustage.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 30 May 2013 16:56:02 -0400
changeset 145055 a6ce38ac4a15d3bd11501205fa91f39ea0f6da3b
parent 145054 758527363f29db5a7e90ab727a51af7b2db7ddeb
child 145056 d32b01a4ca58849a8a4854310eea3ba58bd7b662
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs873622
milestone24.0a1
backs outeb7402ddbe54579eafaad7e56bd1cbb42e3ab1cd
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
Backed out changeset eb7402ddbe54 (bug 873622) for Windows bustage. CLOSED TREE
caps/src/nsScriptSecurityManager.cpp
content/base/src/nsContentUtils.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCException.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCThrower.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/nsCxPusher.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -2417,17 +2417,21 @@ nsScriptSecurityManager::nsScriptSecurit
 {
     MOZ_STATIC_ASSERT(sizeof(intptr_t) == sizeof(void*),
                       "intptr_t and void* have different lengths on this platform. "
                       "This may cause a security failure with the SecurityLevel union.");
 }
 
 nsresult nsScriptSecurityManager::Init()
 {
-    NS_ADDREF(sXPConnect = nsXPConnect::XPConnect());
+    nsXPConnect* xpconnect = nsXPConnect::GetXPConnect();
+     if (!xpconnect)
+        return NS_ERROR_FAILURE;
+
+    NS_ADDREF(sXPConnect = xpconnect);
 
     JSContext* cx = GetSafeJSContext();
     if (!cx) return NS_ERROR_FAILURE;   // this can happen of xpt loading fails
     
     ::JS_BeginRequest(cx);
     if (sEnabledID == JSID_VOID)
         sEnabledID = INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "enabled"));
     ::JS_EndRequest(cx);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -356,17 +356,20 @@ nsContentUtils::Init()
     NS_WARNING("Init() called twice");
 
     return NS_OK;
   }
 
   nsresult rv = NS_GetNameSpaceManager(&sNameSpaceManager);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  sXPConnect = nsXPConnect::XPConnect();
+  nsXPConnect* xpconnect = nsXPConnect::GetXPConnect();
+  NS_ENSURE_TRUE(xpconnect, NS_ERROR_FAILURE);
+
+  sXPConnect = xpconnect;
 
   sSecurityManager = nsScriptSecurityManager::GetScriptSecurityManager();
   if(!sSecurityManager)
     return NS_ERROR_FAILURE;
   NS_ADDREF(sSecurityManager);
 
   rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
   if (NS_FAILED(rv)) {
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -257,17 +257,22 @@ File(JSContext *cx, unsigned argc, Value
     NS_ASSERTION(initializer, "what?");
 
     rv = initializer->Initialize(nullptr, cx, nullptr, args);
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    if (!xpc) {
+        XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
+        return false;
+    }
+
     JSObject* glob = JS_GetGlobalForScopeChain(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
                                 true, args.rval().address(), nullptr);
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
@@ -292,17 +297,22 @@ Blob(JSContext *cx, unsigned argc, Value
     NS_ASSERTION(initializer, "what?");
 
     rv = initializer->Initialize(nullptr, cx, nullptr, args);
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    if (!xpc) {
+        XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
+        return false;
+    }
+
     JSObject* glob = JS_GetGlobalForScopeChain(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
                                 true, args.rval().address(), nullptr);
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
--- a/js/xpconnect/src/XPCCallContext.cpp
+++ b/js/xpconnect/src/XPCCallContext.cpp
@@ -19,17 +19,17 @@ XPCCallContext::XPCCallContext(XPCContex
                                JSContext* cx       /* = GetDefaultJSContext() */,
                                HandleObject obj    /* = nullptr               */,
                                HandleObject funobj /* = nullptr               */,
                                HandleId name       /* = JSID_VOID             */,
                                unsigned argc       /* = NO_ARGS               */,
                                jsval *argv         /* = nullptr               */,
                                jsval *rval         /* = nullptr               */)
     :   mState(INIT_FAILED),
-        mXPC(nsXPConnect::XPConnect()),
+        mXPC(nsXPConnect::GetXPConnect()),
         mXPCContext(nullptr),
         mJSContext(cx),
         mContextPopRequired(false),
         mDestroyJSContextInDestructor(false),
         mCallerLanguage(callerLanguage),
         mFlattenedJSObject(cx),
         mWrapper(nullptr),
         mTearOff(nullptr),
@@ -43,17 +43,17 @@ XPCCallContext::XPCCallContext(XPCContex
 XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
                                JSContext* cx,
                                JSBool callBeginRequest,
                                HandleObject obj,
                                HandleObject flattenedJSObject,
                                XPCWrappedNative* wrapper,
                                XPCWrappedNativeTearOff* tearOff)
     :   mState(INIT_FAILED),
-        mXPC(nsXPConnect::XPConnect()),
+        mXPC(nsXPConnect::GetXPConnect()),
         mXPCContext(nullptr),
         mJSContext(cx),
         mContextPopRequired(false),
         mDestroyJSContextInDestructor(false),
         mCallerLanguage(callerLanguage),
         mFlattenedJSObject(cx, flattenedJSObject),
         mWrapper(wrapper),
         mTearOff(tearOff),
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -60,17 +60,20 @@ JSValIsInterfaceOfType(JSContext *cx, Ha
 
     nsCOMPtr<nsIXPConnectWrappedNative> wn;
     nsCOMPtr<nsISupports> sup;
     nsISupports* iface;
 
     if (v.isPrimitive())
         return false;
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = nsXPConnect::GetXPConnect();
+    if (!xpc)
+        return false;
+
     RootedObject obj(cx, &v.toObject());
     if (NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && wn &&
         NS_SUCCEEDED(wn->Native()->QueryInterface(iid, (void**)&iface)) && iface)
     {
         NS_RELEASE(iface);
         return true;
     }
     return false;
@@ -2800,18 +2803,19 @@ nsXPCComponents_Utils::ReportError(const
     }
 
     // It's not a JS Error object, so we synthesize as best we're able.
     RootedString msgstr(cx, JS_ValueToString(cx, error));
     if (!msgstr)
         return NS_OK;
 
     nsCOMPtr<nsIStackFrame> frame;
-    nsXPConnect *xpc = nsXPConnect::XPConnect();
-    xpc->GetCurrentJSStack(getter_AddRefs(frame));
+    nsXPConnect *xpc = nsXPConnect::GetXPConnect();
+    if (xpc)
+        xpc->GetCurrentJSStack(getter_AddRefs(frame));
 
     nsXPIDLCString fileName;
     int32_t lineNo = 0;
     if (frame) {
         frame->GetFilename(getter_Copies(fileName));
         frame->GetLineNumber(&lineNo);
     }
 
@@ -3473,17 +3477,19 @@ GetPrincipalFromString(JSContext *cx, Ha
 // for sandbox constructor  the first argument can be a principal object or
 // a script object principal (Document, Window)
 nsresult
 GetPrincipalOrSOP(JSContext *cx, HandleObject from, nsISupports **out)
 {
     MOZ_ASSERT(out);
     *out = NULL;
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = nsXPConnect::GetXPConnect();
+    if (!xpc)
+        return NS_ERROR_XPC_UNEXPECTED;
     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     xpc->GetWrappedNativeOfJSObject(cx, from,
                                     getter_AddRefs(wrapper));
 
     NS_ENSURE_TRUE(wrapper, NS_ERROR_INVALID_ARG);
 
     if (nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryWrappedNative(wrapper)) {
         sop.forget(out);
@@ -3674,17 +3680,19 @@ ParseOptionsObject(JSContext *cx, jsval 
 
 static nsresult
 AssembleSandboxMemoryReporterName(JSContext *cx, nsCString &sandboxName)
 {
     // Use a default name when the caller did not provide a sandboxName.
     if (sandboxName.IsEmpty())
         sandboxName = NS_LITERAL_CSTRING("[anonymous sandbox]");
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    NS_ENSURE_TRUE(xpc, NS_ERROR_XPC_UNEXPECTED);
+
     // Get the xpconnect native call context.
     nsAXPCNativeCallContext *cc = nullptr;
     xpc->GetCurrentNativeCallContext(&cc);
     NS_ENSURE_TRUE(cc, NS_ERROR_INVALID_ARG);
 
     // Get the current source info from xpc.
     nsCOMPtr<nsIStackFrame> frame;
     xpc->GetCurrentJSStack(getter_AddRefs(frame));
@@ -4411,19 +4419,19 @@ nsXPCComponents_Utils::Dispatch(const js
             return NS_ERROR_FAILURE;
     }
 
     // Get an XPCWrappedJS for |runnable|.
     if (!runnable.isObject())
         return NS_ERROR_INVALID_ARG;
 
     nsCOMPtr<nsIRunnable> run;
-    nsresult rv = nsXPConnect::XPConnect()->WrapJS(cx, &runnable.toObject(),
-                                                   NS_GET_IID(nsIRunnable),
-                                                   getter_AddRefs(run));
+    nsresult rv = nsXPConnect::GetXPConnect()->WrapJS(cx, &runnable.toObject(),
+                                                      NS_GET_IID(nsIRunnable),
+                                                      getter_AddRefs(run));
     NS_ENSURE_SUCCESS(rv, rv);
     MOZ_ASSERT(run);
 
     // Dispatch.
     return NS_DispatchToMainThread(run);
 }
 
 /* string canCreateWrapper (in nsIIDPtr iid); */
@@ -4756,17 +4764,19 @@ nsXPCComponents::IsSuccessCode(nsresult 
     *out = NS_SUCCEEDED(result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents::GetStack(nsIStackFrame * *aStack)
 {
     nsresult rv;
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    if (!xpc)
+        return NS_ERROR_FAILURE;
     rv = xpc->GetCurrentJSStack(aStack);
     return rv;
 }
 
 NS_IMETHODIMP
 nsXPCComponents::GetManager(nsIComponentManager * *aManager)
 {
     NS_ASSERTION(aManager, "bad param");
--- a/js/xpconnect/src/XPCException.cpp
+++ b/js/xpconnect/src/XPCException.cpp
@@ -292,17 +292,19 @@ nsXPCException::Initialize(const char *a
         // Later we may allow other locations?
         nsresult rc;
         if (NS_FAILED(rc = aLocation->GetFilename(&mFilename)))
             return rc;
         if (NS_FAILED(rc = aLocation->GetLineNumber(&mLineNumber)))
             return rc;
     } else {
         nsresult rv;
-        nsXPConnect* xpc = nsXPConnect::XPConnect();
+        nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+        if (!xpc)
+            return NS_ERROR_FAILURE;
         rv = xpc->GetCurrentJSStack(&mLocation);
         if (NS_FAILED(rv))
             return rv;
     }
 
     if (aData) {
         mData = aData;
         NS_ADDREF(mData);
@@ -393,17 +395,21 @@ nsXPCException::NewException(const char 
     if (e) {
         NS_ADDREF(e);
 
         nsIStackFrame* location;
         if (aLocation) {
             location = aLocation;
             NS_ADDREF(location);
         } else {
-            nsXPConnect* xpc = nsXPConnect::XPConnect();
+            nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+            if (!xpc) {
+                NS_RELEASE(e);
+                return NS_ERROR_FAILURE;
+            }
             rv = xpc->GetCurrentJSStack(&location);
             if (NS_FAILED(rv)) {
                 NS_RELEASE(e);
                 return NS_ERROR_FAILURE;
             }
             // it is legal for there to be no active JS stack, if C++ code
             // is operating on a JS-implemented interface pointer without
             // having been called in turn by JS.  This happens in the JS
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -142,17 +142,20 @@ XPCJSContextStack::GetSafeJSContext()
 
     // Start by getting the principal holder and principal for this
     // context.  If we can't manage that, don't bother with the rest.
     nsRefPtr<nsNullPrincipal> principal = new nsNullPrincipal();
     nsresult rv = principal->Init();
     if (NS_FAILED(rv))
         return NULL;
 
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsRefPtr<nsXPConnect> xpc = nsXPConnect::GetXPConnect();
+    if (!xpc)
+        return NULL;
+
     XPCJSRuntime* xpcrt = xpc->GetRuntime();
     if (!xpcrt)
         return NULL;
 
     JSRuntime *rt = xpcrt->GetJSRuntime();
     if (!rt)
         return NULL;
 
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -709,17 +709,20 @@ GetIIDArg(uint32_t argc, const JS::Value
 
     return iid;
 }
 
 static void
 GetWrapperObject(MutableHandleObject obj)
 {
     obj.set(NULL);
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    if (!xpc)
+        return;
+
     nsAXPCNativeCallContext *ccxp = NULL;
     xpc->GetCurrentNativeCallContext(&ccxp);
     if (!ccxp)
         return;
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     ccxp->GetCalleeWrapper(getter_AddRefs(wrapper));
     obj.set(wrapper->GetJSObject());
@@ -761,17 +764,17 @@ nsJSCID::CreateInstance(const JS::Value&
 
     nsCOMPtr<nsISupports> inst;
     rv = compMgr->CreateInstance(mDetails.ID(), nullptr, *iid, getter_AddRefs(inst));
     NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!");
 
     if (NS_FAILED(rv) || !inst)
         return NS_ERROR_XPC_CI_RETURNED_FAILURE;
 
-    rv = nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, obj, inst, nullptr, iid, true, retval, nullptr);
+    rv = nsXPConnect::GetXPConnect()->WrapNativeToJSVal(cx, obj, inst, nullptr, iid, true, retval, nullptr);
     if (NS_FAILED(rv) || JSVAL_IS_PRIMITIVE(*retval))
         return NS_ERROR_XPC_CANT_CREATE_WN;
     return NS_OK;
 }
 
 /* nsISupports getService (); */
 NS_IMETHODIMP
 nsJSCID::GetService(const JS::Value& iidval, JSContext* cx,
@@ -810,17 +813,17 @@ nsJSCID::GetService(const JS::Value& iid
     nsCOMPtr<nsISupports> srvc;
     rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc));
     NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!");
     if (NS_FAILED(rv) || !srvc)
         return NS_ERROR_XPC_GS_RETURNED_FAILURE;
 
     RootedObject instJSObj(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv = nsXPConnect::XPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
+    rv = nsXPConnect::GetXPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
     if (NS_FAILED(rv) || !holder ||
         // Assign, not compare
         !(instJSObj = holder->GetJSObject()))
         return NS_ERROR_XPC_CANT_CREATE_WN;
 
     *retval = OBJECT_TO_JSVAL(instJSObj);
     return NS_OK;
 }
@@ -887,17 +890,17 @@ nsJSCID::HasInstance(nsIXPConnectWrapped
 JSObject *
 xpc_NewIDObject(JSContext *cx, HandleObject jsobj, const nsID& aID)
 {
     RootedObject obj(cx);
 
     nsCOMPtr<nsIJSID> iid =
             dont_AddRef(static_cast<nsIJSID*>(nsJSID::NewID(aID)));
     if (iid) {
-        nsXPConnect* xpc = nsXPConnect::XPConnect();
+        nsXPConnect* xpc = nsXPConnect::GetXPConnect();
         if (xpc) {
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             nsresult rv = xpc->WrapNative(cx, jsobj,
                                           static_cast<nsISupports*>(iid),
                                           NS_GET_IID(nsIJSID),
                                           getter_AddRefs(holder));
             if (NS_SUCCEEDED(rv) && holder) {
                 obj = holder->GetJSObject();
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -603,18 +603,19 @@ XPCJSRuntime::UnmarkSkippableJSHolders()
 {
     XPCAutoLock lock(mMapLock);
     mJSHolders.Enumerate(UnmarkJSHolder, nullptr);
 }
 
 void
 xpc_UnmarkSkippableJSHolders()
 {
-    if (nsXPConnect::XPConnect()->GetRuntime()) {
-        nsXPConnect::XPConnect()->GetRuntime()->UnmarkSkippableJSHolders();
+    if (nsXPConnect::GetXPConnect() &&
+        nsXPConnect::GetXPConnect()->GetRuntime()) {
+        nsXPConnect::GetXPConnect()->GetRuntime()->UnmarkSkippableJSHolders();
     }
 }
 
 template<class T> static void
 DoDeferredRelease(nsTArray<T> &array)
 {
     while (1) {
         uint32_t count = array.Length();
@@ -2253,17 +2254,17 @@ class XPCJSRuntimeStats : public JS::Run
 
 
         for (size_t i = 0; i != zoneStatsVector.length(); ++i)
             delete static_cast<xpc::ZoneStatsExtras*>(zoneStatsVector[i].extra);
     }
 
     virtual void initExtraZoneStats(JS::Zone *zone, JS::ZoneStats *zStats) MOZ_OVERRIDE {
         // Get the compartment's global.
-        nsXPConnect *xpc = nsXPConnect::XPConnect();
+        nsXPConnect *xpc = nsXPConnect::GetXPConnect();
         AutoSafeJSContext cx;
         JSCompartment *comp = js::GetAnyCompartmentInZone(zone);
         xpc::ZoneStatsExtras *extras = new xpc::ZoneStatsExtras;
         extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/");
         RootedObject global(cx, JS_GetGlobalForCompartmentOrNull(cx, comp));
         if (global) {
             // Need to enter the compartment, otherwise GetNativeOfWrapper()
             // might crash.
@@ -2286,17 +2287,17 @@ class XPCJSRuntimeStats : public JS::Run
     virtual void initExtraCompartmentStats(JSCompartment *c,
                                            JS::CompartmentStats *cstats) MOZ_OVERRIDE
     {
         xpc::CompartmentStatsExtras *extras = new xpc::CompartmentStatsExtras;
         nsCString cName;
         GetCompartmentName(c, cName, true);
 
         // Get the compartment's global.
-        nsXPConnect *xpc = nsXPConnect::XPConnect();
+        nsXPConnect *xpc = nsXPConnect::GetXPConnect();
         AutoSafeJSContext cx;
         bool needZone = true;
         RootedObject global(cx, JS_GetGlobalForCompartmentOrNull(cx, c));
         if (global) {
             // Need to enter the compartment, otherwise GetNativeOfWrapper()
             // might crash.
             JSAutoCompartment ac(cx, global);
             nsISupports *native = xpc->GetNativeOfWrapper(cx, global);
@@ -2998,18 +2999,18 @@ XPCRootSetElem::AddToRootSet(XPCLock *lo
         mNext->mSelfp = &mNext;
     }
     *listHead = this;
 }
 
 void
 XPCRootSetElem::RemoveFromRootSet(XPCLock *lock)
 {
-    nsXPConnect *xpc = nsXPConnect::XPConnect();
-    JS::PokeGC(xpc->GetRuntime()->GetJSRuntime());
+    if (nsXPConnect *xpc = nsXPConnect::GetXPConnect())
+        JS::PokeGC(xpc->GetRuntime()->GetJSRuntime());
 
     NS_ASSERTION(mSelfp, "Must be linked");
 
     XPCAutoLock autoLock(lock);
 
     NS_ASSERTION(*mSelfp == this, "Link invariant");
     *mSelfp = mNext;
     if (mNext)
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -20,17 +20,17 @@ nsresult xpcJSWeakReference::Init(JSCont
         return NS_OK;
 
     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::XPConnect()->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;
         }
     }
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -60,17 +60,17 @@ LookupInterfaceOrAncestor(uint32_t table
 {
     const xpc_qsHashEntry *entry = LookupEntry(tableSize, table, iid);
     if (!entry) {
         /*
          * On a miss, we have to search for every interface the object
          * supports, including ancestors.
          */
         nsCOMPtr<nsIInterfaceInfo> info;
-        if (NS_FAILED(nsXPConnect::XPConnect()->GetInfoForIID(&iid, getter_AddRefs(info))))
+        if (NS_FAILED(nsXPConnect::GetXPConnect()->GetInfoForIID(&iid, getter_AddRefs(info))))
             return nullptr;
 
         const nsIID *piid;
         for (;;) {
             nsCOMPtr<nsIInterfaceInfo> parent;
             if (NS_FAILED(info->GetParent(getter_AddRefs(parent))) ||
                 !parent ||
                 NS_FAILED(parent->GetIIDShared(&piid))) {
--- a/js/xpconnect/src/XPCThrower.cpp
+++ b/js/xpconnect/src/XPCThrower.cpp
@@ -236,17 +236,17 @@ XPCThrower::ThrowExceptionObject(JSConte
         // context (i.e., not chrome), rethrow the original value.
         if (!IsCallerChrome(cx) &&
             (xpcEx = do_QueryInterface(e)) &&
             NS_SUCCEEDED(xpcEx->StealJSVal(thrown.address()))) {
             if (!JS_WrapValue(cx, thrown.address()))
                 return false;
             JS_SetPendingException(cx, thrown);
             success = true;
-        } else if ((xpc = nsXPConnect::XPConnect())) {
+        } else if ((xpc = nsXPConnect::GetXPConnect())) {
             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));
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -345,21 +345,22 @@ JSBool XPCVariant::InitializeData(JSCont
         mData.u.array.mArrayCount = len;
         mData.u.array.mArrayType = type.TagPart();
 
         return true;
     }
 
     // XXX This could be smarter and pick some more interesting iface.
 
-    nsXPConnect*  xpc = nsXPConnect::XPConnect();
+    nsXPConnect*  xpc;
     nsCOMPtr<nsISupports> wrapper;
     const nsIID& iid = NS_GET_IID(nsISupports);
 
-    return NS_SUCCEEDED(xpc->WrapJS(cx, jsobj,
+    return nullptr != (xpc = nsXPConnect::GetXPConnect()) &&
+           NS_SUCCEEDED(xpc->WrapJS(cx, jsobj,
                                     iid, getter_AddRefs(wrapper))) &&
            NS_SUCCEEDED(nsVariant::SetFromInterface(&mData, iid, wrapper));
 }
 
 NS_IMETHODIMP
 XPCVariant::GetAsJSVal(jsval* result)
 {
   NS_PRECONDITION(result, "null result arg.");
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -120,17 +120,17 @@ nsXPCWrappedJSClass::GetNewOrUsed(JSCont
         XPCAutoLock lock(rt->GetMapLock());
         IID2WrappedJSClassMap* map = rt->GetWrappedJSClassMap();
         clazz = map->Find(aIID);
         NS_IF_ADDREF(clazz);
     }
 
     if (!clazz) {
         nsCOMPtr<nsIInterfaceInfo> info;
-        nsXPConnect::XPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
+        nsXPConnect::GetXPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
         if (info) {
             bool canScript, isBuiltin;
             if (NS_SUCCEEDED(info->IsScriptable(&canScript)) && canScript &&
                 NS_SUCCEEDED(info->IsBuiltinClass(&isBuiltin)) && !isBuiltin &&
                 nsXPConnect::IsISupportsDescendant(info)) {
                 clazz = new nsXPCWrappedJSClass(cx, aIID, info);
                 if (clazz && !clazz->mDescriptors)
                     NS_RELEASE(clazz);  // sets clazz to nullptr
@@ -235,17 +235,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
     // Ensure that we are asking for a scriptable interface.
     // NB:  It's important for security that this check is here rather
     // than later, since it prevents untrusted objects from implementing
     // some interfaces in JS and aggregating a trusted object to
     // implement intentionally (for security) unscriptable interfaces.
     // We so often ask for nsISupports that we can short-circuit the test...
     if (!aIID.Equals(NS_GET_IID(nsISupports))) {
         nsCOMPtr<nsIInterfaceInfo> info;
-        nsXPConnect::XPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
+        nsXPConnect::GetXPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
         if (!info)
             return nullptr;
         bool canScript, isBuiltin;
         if (NS_FAILED(info->IsScriptable(&canScript)) || !canScript ||
             NS_FAILED(info->IsBuiltinClass(&isBuiltin)) || isBuiltin)
             return nullptr;
     }
 
@@ -271,17 +271,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
 
             if (JS_GetPendingException(cx, jsexception.address())) {
                 nsresult rv;
                 if (jsexception.isObject()) {
                     // XPConnect may have constructed an object to represent a
                     // C++ QI failure. See if that is the case.
                     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
 
-                    nsXPConnect::XPConnect()->
+                    nsXPConnect::GetXPConnect()->
                         GetWrappedNativeOfJSObject(cx,
                                                    &jsexception.toObject(),
                                                    getter_AddRefs(wrapper));
 
                     if (wrapper) {
                         nsCOMPtr<nsIException> exception =
                             do_QueryWrappedNative(wrapper);
                         if (exception &&
@@ -679,17 +679,17 @@ nsXPCWrappedJSClass::DelegatedQueryInter
 
     if (aIID.Equals(NS_GET_IID(nsISecurityCheckedComponent))) {
         // XXX This code checks to see if the given object has chrome (also
         // known as system) principals. It really wants to do a
         // UniversalXPConnect type check.
 
         *aInstancePtr = nullptr;
 
-        nsXPConnect *xpc = nsXPConnect::XPConnect();
+        nsXPConnect *xpc = nsXPConnect::GetXPConnect();
         nsCOMPtr<nsIScriptSecurityManager> secMan =
             do_QueryInterface(xpc->GetDefaultSecurityManager());
         if (!secMan)
             return NS_NOINTERFACE;
 
         RootedObject selfObj(ccx, self->GetJSObject());
         nsCOMPtr<nsIPrincipal> objPrin;
         nsresult rv = secMan->GetObjectPrincipal(ccx, selfObj,
--- a/js/xpconnect/src/nsCxPusher.cpp
+++ b/js/xpconnect/src/nsCxPusher.cpp
@@ -112,17 +112,23 @@ nsCxPusher::Push(JSContext *cx)
   mScx = GetScriptContextFromJSContext(cx);
 
   DoPush(cx);
 }
 
 void
 nsCxPusher::DoPush(JSContext* cx)
 {
-  nsXPConnect *xpc = nsXPConnect::XPConnect();
+  nsIXPConnect *xpc = nsXPConnect::GetXPConnect();
+  if (!xpc) {
+    // If someone tries to push a cx when we don't have the relevant state,
+    // it's probably safest to just crash.
+    MOZ_CRASH();
+  }
+
   // NB: The GetDynamicScriptContext is historical and might not be sane.
   if (cx && nsJSUtils::GetDynamicScriptContext(cx) &&
       xpc::IsJSContextOnStack(cx))
   {
     // If the context is on the stack, that means that a script
     // is running at the moment in the context.
     mScriptIsRunning = true;
   }
@@ -160,29 +166,30 @@ nsCxPusher::Pop()
     mScx = nullptr;
     mPushedSomething = false;
 
     NS_ASSERTION(!mScriptIsRunning, "Huh, this can't be happening, "
                  "mScriptIsRunning can't be set here!");
 
     return;
   }
+  MOZ_ASSERT(nsXPConnect::GetXPConnect());
 
   // Leave the request before popping.
   mAutoRequest.destroyIfConstructed();
 
   // When we push a context, we may save the frame chain and pretend like we
   // haven't entered any compartment. This gets restored on Pop(), but we can
   // run into trouble if a Push/Pop are interleaved with a
   // JSAutoEnterCompartment. Make sure the compartment depth right before we
   // pop is the same as it was right after we pushed.
   MOZ_ASSERT_IF(mPushedContext, mCompartmentDepthOnEntry ==
                                 js::GetEnterCompartmentDepth(mPushedContext));
   DebugOnly<JSContext*> stackTop;
-  MOZ_ASSERT(mPushedContext == nsXPConnect::XPConnect()->GetCurrentJSContext());
+  MOZ_ASSERT(mPushedContext == nsXPConnect::GetXPConnect()->GetCurrentJSContext());
   xpc::PopJSContext();
 
   if (!mScriptIsRunning && mScx) {
     // No JS is running in the context, but executing the event handler might have
     // caused some JS to run. Tell the script context that it's done.
 
     mScx->ScriptEvaluated(true);
   }
@@ -208,17 +215,17 @@ AutoJSContext::AutoJSContext(bool aSafe 
 
 void
 AutoJSContext::Init(bool aSafe MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
 {
   MOZ_ASSERT(!mCx, "mCx should not be initialized!");
 
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
-  nsXPConnect *xpc = nsXPConnect::XPConnect();
+  nsIXPConnect *xpc = nsXPConnect::GetXPConnect();
   if (!aSafe) {
     mCx = xpc->GetCurrentJSContext();
   }
 
   if (!mCx) {
     mCx = xpc->GetSafeJSContext();
     mPusher.Push(mCx);
   }
@@ -231,14 +238,14 @@ AutoJSContext::operator JSContext*()
 
 AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
   : AutoJSContext(true MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
 {
 }
 
 AutoPushJSContext::AutoPushJSContext(JSContext *aCx) : mCx(aCx)
 {
-  if (mCx && mCx != nsXPConnect::XPConnect()->GetCurrentJSContext()) {
+  if (mCx && mCx != nsXPConnect::GetXPConnect()->GetCurrentJSContext()) {
     mPusher.Push(mCx);
   }
 }
 
 } // namespace mozilla
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -132,39 +132,58 @@ nsXPConnect::~nsXPConnect()
 
     delete mRuntime;
 
     gSelf = nullptr;
     gOnceAliveNowDead = true;
 }
 
 // static
-void
-    nsXPConnect::InitStatics()
-    {
-    gSelf = new nsXPConnect();
-    gOnceAliveNowDead = false;
-    if (!gSelf->mRuntime) {
-        NS_RUNTIMEABORT("Couldn't create XPCJSRuntime.");
-    }
+nsXPConnect*
+nsXPConnect::GetXPConnect()
+{
+    // Do a release-mode assert that we're not doing anything significant in
+    // XPConnect off the main thread. If you're an extension developer hitting
+    // this, you need to change your code. See bug 716167.
+    if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
+        MOZ_CRASH();
+
+    if (!gSelf) {
+        if (gOnceAliveNowDead)
+            return nullptr;
+        gSelf = new nsXPConnect();
+        if (!gSelf)
+            return nullptr;
 
-    // Initial extra ref to keep the singleton alive
-    // balanced by explicit call to ReleaseXPConnectSingleton()
-    NS_ADDREF(gSelf);
+        if (!gSelf->mRuntime) {
+            NS_RUNTIMEABORT("Couldn't create XPCJSRuntime.");
+        }
+
+        // Initial extra ref to keep the singleton alive
+        // balanced by explicit call to ReleaseXPConnectSingleton()
+        NS_ADDREF(gSelf);
 
-    // Set XPConnect as the main thread observer.
-    if (NS_FAILED(nsThread::SetMainThreadObserver(gSelf))) {
-        MOZ_CRASH();
+        // Set XPConnect as the main thread observer.
+        //
+        // The cycle collector sometimes calls GetXPConnect, but it should never
+        // be the one that initializes gSelf.
+        MOZ_ASSERT(NS_IsMainThread());
+        if (NS_FAILED(nsThread::SetMainThreadObserver(gSelf))) {
+            NS_RELEASE(gSelf);
+            // Fall through to returning null
+        }
     }
+    return gSelf;
 }
 
+// static
 nsXPConnect*
 nsXPConnect::GetSingleton()
 {
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
     NS_IF_ADDREF(xpc);
     return xpc;
 }
 
 // static
 void
 nsXPConnect::ReleaseXPConnectSingleton()
 {
@@ -206,17 +225,18 @@ nsXPConnect::ReleaseXPConnectSingleton()
 #endif
     }
 }
 
 // static
 XPCJSRuntime*
 nsXPConnect::GetRuntimeInstance()
 {
-    nsXPConnect* xpc = XPConnect();
+    nsXPConnect* xpc = GetXPConnect();
+    NS_ASSERTION(xpc, "Must not be called if XPC failed to initialize");
     return xpc->GetRuntime();
 }
 
 // static
 JSBool
 nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
 {
     bool found = false;
@@ -2027,17 +2047,17 @@ nsXPConnect::CheckForDebugMode(JSRuntime
 }
 #endif //#ifdef MOZ_JSDEBUGGER
 
 
 NS_EXPORT_(void)
 xpc_ActivateDebugMode()
 {
     XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
-    nsXPConnect::XPConnect()->SetDebugModeWhenPossible(true, true);
+    nsXPConnect::GetXPConnect()->SetDebugModeWhenPossible(true, true);
     nsXPConnect::CheckForDebugMode(rt->GetJSRuntime());
 }
 
 /* virtual */
 JSContext*
 nsXPConnect::GetCurrentJSContext()
 {
     JSContext *cx = GetRuntime()->GetJSContextStack()->Peek();
@@ -2052,17 +2072,17 @@ nsXPConnect::GetSafeJSContext()
 }
 
 namespace xpc {
 
 bool
 PushJSContext(JSContext *aCx)
 {
     // JSD mumbo jumbo.
-    nsXPConnect *xpc = nsXPConnect::XPConnect();
+    nsXPConnect *xpc = nsXPConnect::GetXPConnect();
     JSRuntime *rt = XPCJSRuntime::Get()->GetJSRuntime();
     if (xpc::gDebugMode != xpc::gDesiredDebugMode) {
         if (!xpc::gDesiredDebugMode) {
             /* Turn off debug mode immediately, even if JS code is currently
                running. */
             xpc->CheckForDebugMode(rt);
         } else {
             bool runningJS = false;
@@ -2227,17 +2247,21 @@ Base64Decode(JSContext *cx, JS::Value va
     *out = STRING_TO_JSVAL(str);
     return true;
 }
 
 void
 DumpJSHeap(FILE* file)
 {
     NS_ABORT_IF_FALSE(NS_IsMainThread(), "Must dump GC heap on main thread.");
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::GetXPConnect();
+    if (!xpc) {
+        NS_ERROR("Failed to get nsXPConnect instance!");
+        return;
+    }
     js::DumpHeapComplete(xpc->GetRuntime()->GetJSRuntime(), file);
 }
 
 void
 SetLocationForGlobal(JSObject *global, const nsACString& location)
 {
     MOZ_ASSERT(global);
     EnsureCompartmentPrivate(global)->SetLocation(location);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -471,28 +471,18 @@ public:
     NS_DECL_NSIXPCONNECT
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIJSRUNTIMESERVICE
     NS_DECL_NSIJSENGINETELEMETRYSTATS
 
     // non-interface implementation
 public:
     // These get non-addref'd pointers
-    static nsXPConnect*  XPConnect()
-    {
-        // Do a release-mode assert that we're not doing anything significant in
-        // XPConnect off the main thread. If you're an extension developer hitting
-        // this, you need to change your code. See bug 716167.
-        if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
-            MOZ_CRASH();
-
-        return gSelf;
-    }
-
-    static nsXPConnect*  FastGetXPConnect() { return gSelf ? gSelf : XPConnect(); }
+    static nsXPConnect*  GetXPConnect();
+    static nsXPConnect*  FastGetXPConnect() { return gSelf ? gSelf : GetXPConnect(); }
     static XPCJSRuntime* GetRuntimeInstance();
     XPCJSRuntime* GetRuntime() {return mRuntime;}
 
 #ifdef DEBUG
     void SetObjectToUnlink(void* aObject);
     void AssertNoObjectsToTrace(void* aPossibleJSHolder);
 #endif
 
@@ -511,17 +501,17 @@ public:
         {return mDefaultSecurityManagerFlags;}
 
     // This returns an AddRef'd pointer. It does not do this with an 'out' param
     // only because this form is required by the generic module macro:
     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
     static nsXPConnect* GetSingleton();
 
     // Called by module code in dll startup
-    static void InitStatics();
+    static void InitStatics() { gSelf = nullptr; gOnceAliveNowDead = false; }
     // Called by module code on dll shutdown.
     static void ReleaseXPConnectSingleton();
 
     virtual ~nsXPConnect();
 
     JSBool IsShuttingDown() const {return mShuttingDown;}
 
     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
@@ -649,17 +639,17 @@ public:
 
 // no virtuals. no refcounting.
 class XPCJSContextStack;
 class XPCIncrementalReleaseRunnable;
 class XPCJSRuntime
 {
 public:
     static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect);
-    static XPCJSRuntime* Get() { return nsXPConnect::XPConnect()->GetRuntime(); }
+    static XPCJSRuntime* Get() { return nsXPConnect::GetXPConnect()->GetRuntime(); }
 
     JSRuntime*     GetJSRuntime() const {return mJSRuntime;}
     nsXPConnect*   GetXPConnect() const {return mXPConnect;}
 
     XPCJSContextStack* GetJSContextStack() {return mJSContextStack;}
     void DestroyJSContextStack();
 
     XPCCallContext*  GetCallContext() const {return mCallContext;}
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -1930,16 +1930,16 @@ do_QueryInterfaceNative(JSContext* cx, H
             if (!UnwrapDOMObjectToISupports(target, nativeSupports)) {
                 nativeSupports = nullptr;
             }
         } else {
             XPCWrappedNative *wn = GetWrappedNative(target);
             nativeSupports = wn->Native();
         }
     } else {
-        nsIXPConnect *xpc = nsXPConnect::XPConnect();
+        nsIXPConnect *xpc = nsXPConnect::GetXPConnect();
         nativeSupports = xpc->GetNativeOfWrapper(cx, wrapper);
     }
 
     return nsQueryInterface(nativeSupports);
 }
 
 }