Backed out changeset d4ae1994c20c (bug 1489147) for bustages in JSDebugger.cpp on a CLOSED TREE
authorshindli <shindli@mozilla.com>
Thu, 06 Sep 2018 22:12:44 +0300
changeset 483394 8be67ab3d7d34909c6e52b7e6984b6ff84cc470a
parent 483393 d4ae1994c20c1b0fb9051862606f94e7854b86f2
child 483395 24058c477407069c999e9fdc52d335f54543bbec
push id239
push userfmarier@mozilla.com
push dateMon, 10 Sep 2018 17:01:34 +0000
bugs1489147
milestone64.0a1
backs outd4ae1994c20c1b0fb9051862606f94e7854b86f2
Backed out changeset d4ae1994c20c (bug 1489147) for bustages in JSDebugger.cpp on a CLOSED TREE
dom/base/nsStructuredCloneContainer.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/ductwork/debugger/JSDebugger.cpp
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCModule.h
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
netwerk/base/LoadInfo.cpp
storage/mozStorageConnection.cpp
storage/mozStorageStatementJSHelper.cpp
toolkit/components/places/History.cpp
toolkit/components/places/PlaceInfo.cpp
widget/cocoa/nsMenuX.mm
xpcom/build/Services.py
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -110,17 +110,17 @@ nsStructuredCloneContainer::DeserializeT
   JS::Rooted<JS::Value> jsStateObj(aCx);
   nsresult rv = DeserializeToJsval(aCx, &jsStateObj);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Now wrap the JS::Value as an nsIVariant.
   nsCOMPtr<nsIVariant> varStateObj;
-  nsCOMPtr<nsIXPConnect> xpconnect = nsIXPConnect::XPConnect();
+  nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
   NS_ENSURE_STATE(xpconnect);
   xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
   NS_ENSURE_STATE(varStateObj);
 
   varStateObj.forget(aData);
   return NS_OK;
 }
 
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -729,17 +729,17 @@ NPObject*
   }
 
   dom::AutoJSAPI jsapi;
   if (NS_WARN_IF(!jsapi.Init(doc->GetInnerWindow()))) {
     return nullptr;
   }
   JSContext* cx = jsapi.cx();
 
-  nsCOMPtr<nsIXPConnect> xpc(nsIXPConnect::XPConnect());
+  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
   NS_ENSURE_TRUE(xpc, nullptr);
 
   JS::RootedValue val(cx);
   if (!ToJSValue(cx, element, &val)) {
     return nullptr;
   }
 
   if (NS_WARN_IF(!val.isObject())) {
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -31,34 +31,39 @@ using mozilla::dom::AutoJSAPI;
 //*****************************************************************************
 
 static JS::PersistentRooted<JSObject *> autoconfigSystemSb;
 static JS::PersistentRooted<JSObject *> autoconfigSb;
 static bool sandboxEnabled;
 
 nsresult CentralizedAdminPrefManagerInit(bool aSandboxEnabled)
 {
+    nsresult rv;
+
     // If the sandbox is already created, no need to create it again.
     if (autoconfigSb.initialized())
         return NS_OK;
 
     sandboxEnabled = aSandboxEnabled;
 
     // Grab XPConnect.
-    nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
+    if (NS_FAILED(rv)) {
+        return rv;
+    }
 
     // Grab the system principal.
     nsCOMPtr<nsIPrincipal> principal;
     nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
 
 
     // Create a sandbox.
     AutoSafeJSContext cx;
     JS::Rooted<JSObject*> sandbox(cx);
-    nsresult rv = xpc->CreateSandbox(cx, principal, sandbox.address());
+    rv = xpc->CreateSandbox(cx, principal, sandbox.address());
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Unwrap, store and root the sandbox.
     NS_ENSURE_STATE(sandbox);
     autoconfigSystemSb.init(cx, js::UncheckedUnwrap(sandbox));
 
 
     // Create an unprivileged sandbox.
@@ -107,16 +112,18 @@ nsresult EvaluateAdminConfigScript(const
 
 }
 
 nsresult EvaluateAdminConfigScript(JS::HandleObject sandbox,
                                    const char *js_buffer, size_t length,
                                    const char *filename, bool globalContext,
                                    bool callbacks, bool skipFirstLine)
 {
+    nsresult rv = NS_OK;
+
     if (skipFirstLine) {
         /* In order to protect the privacy of the JavaScript preferences file
          * from loading by the browser, we make the first line unparseable
          * by JavaScript. We must skip that line here before executing
          * the JavaScript code.
          */
         unsigned int i = 0;
         while (i < length) {
@@ -130,17 +137,20 @@ nsresult EvaluateAdminConfigScript(JS::H
                 break;
         }
 
         length -= i;
         js_buffer += i;
     }
 
     // Grab XPConnect.
-    nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
+    if (NS_FAILED(rv)) {
+        return rv;
+    }
 
     AutoJSAPI jsapi;
     if (!jsapi.Init(sandbox)) {
         return NS_ERROR_UNEXPECTED;
     }
     JSContext* cx = jsapi.cx();
 
     nsAutoCString script(js_buffer, length);
@@ -161,15 +171,15 @@ nsresult EvaluateAdminConfigScript(JS::H
     }
     {
         JSAutoRealm ar(cx, autoconfigSystemSb);
         JS::Rooted<JS::Value> value(cx, JS::BooleanValue(isUTF8));
         if (!JS_DefineProperty(cx, autoconfigSystemSb, "gIsUTF8", value, JSPROP_ENUMERATE)) {
             return NS_ERROR_UNEXPECTED;
         }
     }
-    nsresult rv = xpc->EvalInSandboxObject(convertedScript, filename, cx,
+    rv = xpc->EvalInSandboxObject(convertedScript, filename, cx,
                                   sandbox, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -195,17 +195,17 @@ DumpXPC(JSContext *cx,
     JS::CallArgs args = CallArgsFromVp(argc, vp);
 
     uint16_t depth = 2;
     if (args.length() > 0) {
         if (!JS::ToUint16(cx, args[0], &depth))
             return false;
     }
 
-    nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
     if (xpc)
         xpc->DebugDump(int16_t(depth));
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 GC(JSContext *cx,
--- a/js/ductwork/debugger/JSDebugger.cpp
+++ b/js/ductwork/debugger/JSDebugger.cpp
@@ -32,17 +32,18 @@ JSDebugger::JSDebugger()
 
 JSDebugger::~JSDebugger()
 {
 }
 
 NS_IMETHODIMP
 JSDebugger::AddClass(JS::Handle<JS::Value> global, JSContext* cx)
 {
-  nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+  nsresult rv;
+  nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
 
   if (!global.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::RootedObject obj(cx, &global.toObject());
   obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
   if (!obj) {
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -186,22 +186,29 @@ interface nsIXPConnectWrappedJSUnmarkGra
 interface nsIXPCWrappedJSObjectGetter : nsISupports
 {
     readonly attribute nsISupports neverCalled;
 };
 
 /***************************************************************************/
 
 
-[noscript, builtinclass, uuid(768507b5-b981-40c7-8276-f6a1da502a24)]
+%{ C++
+// For use with the service manager
+// {CB6593E0-F9B2-11d2-BDD6-000064657374}
+#define NS_XPCONNECT_CID \
+{ 0xcb6593e0, 0xf9b2, 0x11d2, \
+    { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
+%}
+
+[noscript, uuid(768507b5-b981-40c7-8276-f6a1da502a24)]
 interface nsIXPConnect : nsISupports
 {
 %{ C++
-    // These get non-addref'd pointers
-    static nsIXPConnect* XPConnect();
+  NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCONNECT_CID)
 %}
 
     /**
     * wrapNative will create a new JSObject or return an existing one.
     *
     * This method now correctly deals with cases where the passed in xpcom
     * object already has an associated JSObject for the cases:
     *  1) The xpcom object has already been wrapped for use in the same scope
@@ -364,11 +371,9 @@ interface nsIXPConnect : nsISupports
                                       in JSContextPtr aJSContext);
 
     [noscript] void writeFunction(in nsIObjectOutputStream aStream,
                                   in JSContextPtr aJSContext,
                                   in JSObjectPtr aJSObject);
 
     [noscript] JSObjectPtr readFunction(in nsIObjectInputStream aStream,
                                         in JSContextPtr aJSContext);
-
-    [infallible] readonly attribute boolean isShuttingDown;
 };
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -64,17 +64,17 @@ JSValIsInterfaceOfType(JSContext* cx, Ha
 {
 
     nsCOMPtr<nsIXPConnectWrappedNative> wn;
     nsCOMPtr<nsISupports> iface;
 
     if (v.isPrimitive())
         return false;
 
-    nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::XPConnect();
     RootedObject obj(cx, &v.toObject());
     return NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && wn &&
         NS_SUCCEEDED(wn->Native()->QueryInterface(iid, getter_AddRefs(iface))) && iface;
 }
 
 char*
 xpc::CloneAllAccess()
 {
@@ -253,17 +253,17 @@ nsXPCComponents_Interfaces::Resolve(nsIX
     if (name && name[0] != '{') {
         const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name.get());
         if (!info)
             return NS_OK;
 
         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (nsid) {
-            nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+            nsXPConnect* xpc = nsXPConnect::XPConnect();
             RootedObject idobj(cx);
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSIID*>(nsid),
                                              NS_GET_IID(nsIJSIID),
                                              idobj.address()))) {
                 if (idobj) {
                     *resolvedp = true;
                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
@@ -441,17 +441,17 @@ nsXPCComponents_InterfacesByID::Resolve(
         if (!info)
             return NS_OK;
 
         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (!nsid)
             return NS_ERROR_OUT_OF_MEMORY;
 
-        nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+        nsXPConnect* xpc = nsXPConnect::XPConnect();
         RootedObject idobj(cx);
         if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                          static_cast<nsIJSIID*>(nsid),
                                          NS_GET_IID(nsIJSIID),
                                          idobj.address()))) {
             if (idobj) {
                 *resolvedp = true;
                 *_retval =
@@ -626,17 +626,17 @@ nsXPCComponents_Classes::Resolve(nsIXPCo
     if (!JSID_IS_STRING(id))
         return NS_OK;
 
     JS::UniqueChars name = JS_EncodeStringToLatin1(cx, JSID_TO_STRING(id));
     if (name &&
         name[0] != '{') { // we only allow contractids here
         nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.get());
         if (nsid) {
-            nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+            nsXPConnect* xpc = nsXPConnect::XPConnect();
             RootedObject idobj(cx);
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSCID*>(nsid),
                                              NS_GET_IID(nsIJSCID),
                                              idobj.address()))) {
                 if (idobj) {
                     *resolvedp = true;
                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
@@ -836,17 +836,17 @@ nsXPCComponents_ClassesByID::Resolve(nsI
 
     RootedString str(cx, JSID_TO_STRING(id));
     JS::UniqueChars name = JS_EncodeStringToLatin1(cx, str);
     if (name && name[0] == '{' &&
         IsRegisteredCLSID(name.get())) // we only allow canonical CLSIDs here
     {
         nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.get());
         if (nsid) {
-            nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+            nsXPConnect* xpc = nsXPConnect::XPConnect();
             RootedObject idobj(cx);
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSCID*>(nsid),
                                              NS_GET_IID(nsIJSCID),
                                              idobj.address()))) {
                 if (idobj) {
                     *resolvedp = true;
                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
@@ -1315,17 +1315,17 @@ nsXPCComponents_Exception::Construct(nsI
 {
     RootedObject obj(cx, objArg);
     return CallOrConstruct(wrapper, cx, obj, args, _retval);
 }
 
 struct MOZ_STACK_CLASS ExceptionArgParser
 {
     ExceptionArgParser(JSContext* context,
-                       nsIXPConnect* xpconnect)
+                       nsXPConnect* xpconnect)
         : eMsg("exception")
         , eResult(NS_ERROR_FAILURE)
         , cx(context)
         , xpc(xpconnect)
     {}
 
     // Public exception parameter values. During construction, these are
     // initialized to the appropriate defaults.
@@ -1459,26 +1459,26 @@ struct MOZ_STACK_CLASS ExceptionArgParse
      * Internal data members.
      */
 
     // If there's a non-default exception string, hold onto the allocated bytes.
     JS::UniqueChars messageBytes;
 
     // Various bits and pieces that are helpful to have around.
     JSContext* cx;
-    nsIXPConnect* xpc;
+    nsXPConnect* xpc;
 };
 
 // static
 nsresult
 nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
                                            JSContext* cx, HandleObject obj,
                                            const CallArgs& args, bool* _retval)
 {
-    nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::XPConnect();
 
     MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::IsCallerChrome());
 
     // Parse the arguments to the Exception constructor.
     ExceptionArgParser parser(cx, xpc);
     if (!parser.parse(args))
         return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
@@ -1677,17 +1677,17 @@ nsXPCConstructor::Construct(nsIXPConnect
     return CallOrConstruct(wrapper, cx, obj, args, _retval);
 }
 
 // static
 nsresult
 nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,JSContext* cx,
                                   HandleObject obj, const CallArgs& args, bool* _retval)
 {
-    nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::XPConnect();
 
     // security check not required because we are going to call through the
     // code which is reflected into JS which will do that for us later.
 
     RootedObject cidObj(cx);
     RootedObject iidObj(cx);
 
     if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID), cidObj.address())) || !cidObj ||
@@ -1854,17 +1854,17 @@ nsXPCComponents_Constructor::CallOrConst
 {
     // make sure we have at least one arg
 
     if (args.length() < 1)
         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
 
     // get the various other object pointers we need
 
-    nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+    nsXPConnect* xpc = nsXPConnect::XPConnect();
     XPCWrappedNativeScope* scope = ObjectScope(obj);
     nsCOMPtr<nsIXPCComponents> comp;
 
     if (!xpc || !scope || !(comp = do_QueryInterface(scope->GetComponents())))
         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
 
     // Do the security check if necessary
 
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -753,17 +753,17 @@ nsJSCID::HasInstance(nsIXPConnectWrapped
 
 JSObject*
 xpc_NewIDObject(JSContext* cx, HandleObject scope, const nsID& aID)
 {
     RootedObject obj(cx);
 
     nsCOMPtr<nsIJSID> iid = nsJSID::NewID(aID);
     if (iid) {
-        nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+        nsXPConnect* xpc = nsXPConnect::XPConnect();
         if (xpc) {
             xpc->WrapNative(cx, scope, static_cast<nsISupports*>(iid),
                             NS_GET_IID(nsIJSID), obj.address());
         }
     }
     return obj;
 }
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -672,17 +672,17 @@ bool XPCJSRuntime::UsefulToMergeZones() 
 void XPCJSRuntime::TraceNativeBlackRoots(JSTracer* trc)
 {
     for (CycleCollectedJSContext* ccx : Contexts()) {
         auto* cx = static_cast<const XPCJSContext*>(ccx);
         if (AutoMarkingPtr* roots = cx->mAutoRoots)
             roots->TraceJSAll(trc);
     }
 
-    dom::TraceBlackJS(trc, nsIXPConnect::XPConnect()->GetIsShuttingDown());
+    dom::TraceBlackJS(trc, nsXPConnect::XPConnect()->IsShuttingDown());
 }
 
 void XPCJSRuntime::TraceAdditionalNativeGrayRoots(JSTracer* trc)
 {
     XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(trc);
 
     for (XPCRootSetElem* e = mVariantRoots; e ; e = e->GetNextRoot())
         static_cast<XPCTraceableVariant*>(e)->TraceJS(trc);
--- a/js/xpconnect/src/XPCModule.h
+++ b/js/xpconnect/src/XPCModule.h
@@ -16,31 +16,36 @@
 // {FE4F7592-C1FC-4662-AC83-538841318803}
 #define SCRIPTABLE_INTERFACES_CID                                             \
     {0xfe4f7592, 0xc1fc, 0x4662,                                              \
       { 0xac, 0x83, 0x53, 0x88, 0x41, 0x31, 0x88, 0x3 } }
 
 #define MOZJSSUBSCRIPTLOADER_CONTRACTID "@mozilla.org/moz/jssubscript-loader;1"
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSID)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect,
+                                         nsXPConnect::GetSingleton)
 
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(mozJSComponentLoader,
                                          mozJSComponentLoader::GetOrCreate);
 NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader)
 
 NS_DEFINE_NAMED_CID(NS_JS_ID_CID);
+NS_DEFINE_NAMED_CID(NS_XPCONNECT_CID);
 NS_DEFINE_NAMED_CID(MOZJSCOMPONENTLOADER_CID);
 NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID);
 
 #define XPCONNECT_CIDENTRIES                                                  \
   { &kNS_JS_ID_CID, false, nullptr,  nsJSIDConstructor },                     \
+  { &kNS_XPCONNECT_CID, false, nullptr,  nsIXPConnectConstructor },           \
   { &kMOZJSCOMPONENTLOADER_CID, false, nullptr, mozJSComponentLoaderConstructor },\
   { &kMOZ_JSSUBSCRIPTLOADER_CID, false, nullptr, mozJSSubScriptLoaderConstructor },
 
 #define XPCONNECT_CONTRACTS                                                   \
+  { XPC_XPCONNECT_CONTRACTID, &kNS_XPCONNECT_CID },                           \
   { MOZJSCOMPONENTLOADER_CONTRACTID, &kMOZJSCOMPONENTLOADER_CID },            \
   { MOZJSSUBSCRIPTLOADER_CONTRACTID, &kMOZ_JSSUBSCRIPTLOADER_CID },
 
 #define XPCONNECT_CATEGORIES \
   { "module-loader", "js", MOZJSCOMPONENTLOADER_CONTRACTID },
 
 nsresult xpcModuleCtor();
 void xpcModuleDtor();
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -350,17 +350,17 @@ bool XPCVariant::InitializeData(JSContex
         mData.u.array.mArrayCount = len;
         mData.u.array.mArrayType = elty.Tag();
 
         return true;
     }
 
     // XXX This could be smarter and pick some more interesting iface.
 
-    nsIXPConnect* xpc = nsIXPConnect::XPConnect();
+    nsXPConnect*  xpc = nsXPConnect::XPConnect();
     nsCOMPtr<nsISupports> wrapper;
     const nsIID& iid = NS_GET_IID(nsISupports);
 
     if (NS_FAILED(xpc->WrapJS(cx, jsobj, iid, getter_AddRefs(wrapper)))) {
         return false;
     }
 
     mData.SetFromInterface(iid, wrapper);
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -6,16 +6,17 @@
 
 /* High level class and public functions implementation. */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Unused.h"
 
+#include "xpcprivate.h"
 #include "XPCWrapper.h"
 #include "jsfriendapi.h"
 #include "js/ProfilingStack.h"
 #include "GeckoProfiler.h"
 #include "nsJSEnvironment.h"
 #include "nsThreadUtils.h"
 #include "nsDOMJSUtils.h"
 
@@ -53,16 +54,17 @@ bool         nsXPConnect::gOnceAliveNowD
 // Global cache of the default script security manager (QI'd to
 // nsIScriptSecurityManager) and the system principal.
 nsIScriptSecurityManager* nsXPConnect::gScriptSecurityManager = nullptr;
 nsIPrincipal* nsXPConnect::gSystemPrincipal = nullptr;
 
 const char XPC_EXCEPTION_CONTRACTID[]     = "@mozilla.org/js/xpc/Exception;1";
 const char XPC_CONSOLE_CONTRACTID[]       = "@mozilla.org/consoleservice;1";
 const char XPC_SCRIPT_ERROR_CONTRACTID[]  = "@mozilla.org/scripterror;1";
+const char XPC_XPCONNECT_CONTRACTID[]     = "@mozilla.org/js/xpc/XPConnect;1";
 
 /***************************************************************************/
 
 // This global should be used very sparingly: only to create and destroy
 // nsXPConnect and when creating a new cooperative (non-primary) XPCJSContext.
 static XPCJSContext* gPrimaryContext;
 
 nsXPConnect::nsXPConnect()
@@ -147,16 +149,22 @@ nsXPConnect::InitStatics()
         MOZ_CRASH("InitSelfHostedCode failed");
     if (!gSelf->mRuntime->InitializeStrings(cx))
         MOZ_CRASH("InitializeStrings failed");
 
     // Initialize our singleton scopes.
     gSelf->mRuntime->InitSingletonScopes();
 }
 
+already_AddRefed<nsXPConnect>
+nsXPConnect::GetSingleton()
+{
+    return do_AddRef(nsXPConnect::XPConnect());
+}
+
 // static
 void
 nsXPConnect::ReleaseXPConnectSingleton()
 {
     nsXPConnect* xpc = gSelf;
     if (xpc) {
         nsrefcnt cnt;
         NS_RELEASE2(xpc, cnt);
@@ -1085,40 +1093,16 @@ nsXPConnect::WriteFunction(nsIObjectOutp
 }
 
 NS_IMETHODIMP
 nsXPConnect::ReadFunction(nsIObjectInputStream* stream, JSContext* cx, JSObject** functionObjp)
 {
     return ReadScriptOrFunction(stream, cx, nullptr, functionObjp);
 }
 
-NS_IMETHODIMP
-nsXPConnect::GetIsShuttingDown(bool* aIsShuttingDown)
-{
-    if (!aIsShuttingDown)
-        return NS_ERROR_INVALID_ARG;
-
-    *aIsShuttingDown = mShuttingDown;
-
-    return NS_OK;
-}
-
-// static
-nsIXPConnect*
-nsIXPConnect::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()))
-        MOZ_CRASH();
-
-    return nsXPConnect::gSelf;
-}
-
 /* These are here to be callable from a debugger */
 extern "C" {
 
 MOZ_EXPORT void
 DumpJSStack()
 {
     xpc_DumpJSStack(true, true, false);
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -224,16 +224,28 @@ class nsXPConnect final : public nsIXPCo
 {
 public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCONNECT
 
     // 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()))
+            MOZ_CRASH();
+
+        return gSelf;
+    }
+
     static XPCJSRuntime* GetRuntimeInstance();
 
     static bool IsISupportsDescendant(const nsXPTInterfaceInfo* info);
 
     static nsIScriptSecurityManager* SecurityManager()
     {
         MOZ_ASSERT(NS_IsMainThread());
         MOZ_ASSERT(gScriptSecurityManager);
@@ -242,44 +254,45 @@ public:
 
     static nsIPrincipal* SystemPrincipal()
     {
         MOZ_ASSERT(NS_IsMainThread());
         MOZ_ASSERT(gSystemPrincipal);
         return gSystemPrincipal;
     }
 
+    static already_AddRefed<nsXPConnect> GetSingleton();
+
     // Called by module code in dll startup
     static void InitStatics();
     // Called by module code on dll shutdown.
     static void ReleaseXPConnectSingleton();
 
+    bool IsShuttingDown() const {return mShuttingDown;}
+
     void RecordTraversal(void* p, nsISupports* s);
 
 protected:
     virtual ~nsXPConnect();
 
     nsXPConnect();
 
 private:
     // Singleton instance
     static nsXPConnect*             gSelf;
     static bool                     gOnceAliveNowDead;
 
     XPCJSRuntime*                   mRuntime;
     bool                            mShuttingDown;
 
-    friend class nsIXPConnect;
-
 public:
     static nsIScriptSecurityManager* gScriptSecurityManager;
     static nsIPrincipal* gSystemPrincipal;
 };
 
-
 /***************************************************************************/
 
 class XPCRootSetElem
 {
 public:
     XPCRootSetElem() :
         mNext(nullptr),
         mSelfp(nullptr)
@@ -756,17 +769,17 @@ private:
 inline void CHECK_STATE(int s) const {MOZ_ASSERT(mState >= s, "bad state");}
 #else
 #define CHECK_STATE(s) ((void)0)
 #endif
 
 private:
     State                           mState;
 
-    nsCOMPtr<nsIXPConnect>          mXPC;
+    RefPtr<nsXPConnect>           mXPC;
 
     XPCJSContext*                   mXPCJSContext;
     JSContext*                      mJSContext;
 
     // ctor does not necessarily init the following. BEWARE!
 
     XPCCallContext*                 mPrevCallContext;
 
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -17,17 +17,16 @@
 #include "nsFrameLoader.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIFrameLoaderOwner.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISupportsImpl.h"
 #include "nsISupportsUtils.h"
-#include "nsIXPConnect.h"
 #include "nsContentUtils.h"
 #include "nsDocShell.h"
 #include "nsGlobalWindow.h"
 #include "nsMixedContentBlocker.h"
 #include "nsRedirectHistoryEntry.h"
 #include "LoadInfo.h"
 
 using namespace mozilla::dom;
@@ -1168,17 +1167,17 @@ LoadInfo::GetRedirects(JSContext* aCx, J
                        const RedirectHistoryArray& aArray)
 {
   JS::Rooted<JSObject*> redirects(aCx, JS_NewArrayObject(aCx, aArray.Length()));
   NS_ENSURE_TRUE(redirects, NS_ERROR_OUT_OF_MEMORY);
 
   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
   NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+  nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
 
   for (size_t idx = 0; idx < aArray.Length(); idx++) {
     JS::RootedObject jsobj(aCx);
     nsresult rv = xpc->WrapNative(aCx, global, aArray[idx],
                                   NS_GET_IID(nsIRedirectHistoryEntry),
                                   jsobj.address());
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ENSURE_STATE(jsobj);
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -1336,17 +1336,17 @@ Connection::Close()
 #endif // DEBUG
 
   // Make sure we have not executed any asynchronous statements.
   // If this fails, the mDBConn may be left open, resulting in a leak.
   // We'll try to finalize the pending statements and close the connection.
   if (isAsyncExecutionThreadAvailable()) {
 #ifdef DEBUG
     if (NS_IsMainThread()) {
-      nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+      nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
       Unused << xpc->DebugDumpJSStack(false, false, false);
     }
 #endif
     MOZ_ASSERT(false,
                "Close() was invoked on a connection that executed asynchronous statements. "
                "Should have used asyncClose().");
     // Try to close the database regardless, to free up resources.
     Unused << SpinningSynchronousClose();
--- a/storage/mozStorageStatementJSHelper.cpp
+++ b/storage/mozStorageStatementJSHelper.cpp
@@ -30,17 +30,17 @@ namespace storage {
 //// Global Functions
 
 static
 bool
 stepFunc(JSContext *aCtx, uint32_t argc, JS::Value *_vp)
 {
   JS::CallArgs args = CallArgsFromVp(argc, _vp);
 
-  nsCOMPtr<nsIXPConnect> xpc(nsIXPConnect::XPConnect());
+  nsCOMPtr<nsIXPConnect> xpc(mozilla::services::GetXPConnect());
   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
 
   if (!args.thisv().isObject()) {
     ::JS_ReportErrorASCII(aCtx, "mozIStorageStatement::step() requires object");
     return false;
   }
 
   JSObject *obj = &args.thisv().toObject();
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -223,17 +223,17 @@ GetJSArrayFromJSValue(JS::Handle<JS::Val
  * @param aValue
  *        The JS value to convert.
  * @return the nsIURI object, or null if aValue is not a nsIURI object.
  */
 already_AddRefed<nsIURI>
 GetJSValueAsURI(JSContext* aCtx,
                 const JS::Value& aValue) {
   if (!aValue.isPrimitive()) {
-    nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+    nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrappedObj;
     nsresult rv = xpc->GetWrappedNativeOfJSObject(aCtx, aValue.toObjectOrNull(),
                                                   getter_AddRefs(wrappedObj));
     NS_ENSURE_SUCCESS(rv, nullptr);
     nsCOMPtr<nsIURI> uri = do_QueryWrappedNative(wrappedObj);
     return uri.forget();
   }
@@ -2516,17 +2516,17 @@ History::UpdatePlaces(JS::Handle<JS::Val
       NS_ENSURE_SUCCESS(rv, rv);
       // visitDate should be in microseconds. It's easy to do the wrong thing
       // and pass milliseconds to updatePlaces, so we lazily check for that.
       // While it's not easily distinguishable, since both are integers, we can
       // check if the value is very far in the past, and assume it's probably
       // a mistake.
       if (data.visitTime < (PR_Now() / 1000)) {
 #ifdef DEBUG
-        nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+        nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
         Unused << xpc->DebugDumpJSStack(false, false, false);
         MOZ_CRASH("invalid time format passed to updatePlaces");
 #endif
         return NS_ERROR_INVALID_ARG;
       }
       uint32_t transitionType = 0;
       rv = GetIntFromJSObject(aCtx, visit, "transitionType", &transitionType);
       NS_ENSURE_SUCCESS(rv, rv);
--- a/toolkit/components/places/PlaceInfo.cpp
+++ b/toolkit/components/places/PlaceInfo.cpp
@@ -102,17 +102,17 @@ PlaceInfo::GetVisits(JSContext* aContext
   // visit here, we will likely want to make this cache the value.
   JS::Rooted<JSObject*> visits(aContext,
                                JS_NewArrayObject(aContext, 0));
   NS_ENSURE_TRUE(visits, NS_ERROR_OUT_OF_MEMORY);
 
   JS::Rooted<JSObject*> global(aContext, JS::CurrentGlobalOrNull(aContext));
   NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+  nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
 
   for (VisitsArray::size_type idx = 0; idx < mVisits.Length(); idx++) {
     JS::RootedObject jsobj(aContext);
     nsresult rv = xpc->WrapNative(aContext, global, mVisits[idx],
                                   NS_GET_IID(mozIVisitInfo),
                                   jsobj.address());
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ENSURE_STATE(jsobj);
--- a/widget/cocoa/nsMenuX.mm
+++ b/widget/cocoa/nsMenuX.mm
@@ -414,25 +414,29 @@ void nsMenuX::MenuConstruct()
   GetMenuPopupContent(getter_AddRefs(menuPopup));
   if (!menuPopup) {
     gConstructingMenu = false;
     return;
   }
 
   // bug 365405: Manually wrap the menupopup node to make sure it's bounded
   if (!mXBLAttached) {
-    nsCOMPtr<nsIXPConnect> xpconnect = nsIXPConnect::XPConnect();
-    nsIDocument* ownerDoc = menuPopup->OwnerDoc();
-    dom::AutoJSAPI jsapi;
-    if (ownerDoc && jsapi.Init(ownerDoc->GetInnerWindow())) {
-      JSContext* cx = jsapi.cx();
-      JS::RootedObject ignoredObj(cx);
-      xpconnect->WrapNative(cx, JS::CurrentGlobalOrNull(cx), menuPopup,
-                            NS_GET_IID(nsISupports), ignoredObj.address());
-      mXBLAttached = true;
+    nsresult rv;
+    nsCOMPtr<nsIXPConnect> xpconnect =
+      do_GetService(nsIXPConnect::GetCID(), &rv);
+    if (NS_SUCCEEDED(rv)) {
+      nsIDocument* ownerDoc = menuPopup->OwnerDoc();
+      dom::AutoJSAPI jsapi;
+      if (ownerDoc && jsapi.Init(ownerDoc->GetInnerWindow())) {
+        JSContext* cx = jsapi.cx();
+        JS::RootedObject ignoredObj(cx);
+        xpconnect->WrapNative(cx, JS::CurrentGlobalOrNull(cx), menuPopup,
+                              NS_GET_IID(nsISupports), ignoredObj.address());
+        mXBLAttached = true;
+      }
     }
   }
 
   // Iterate over the kids
   for (nsIContent* child = menuPopup->GetFirstChild();
        child; child = child->GetNextSibling()) {
     // depending on the type, create a menu item, separator, or submenu
     if (child->IsAnyOfXULElements(nsGkAtoms::menuitem,
--- a/xpcom/build/Services.py
+++ b/xpcom/build/Services.py
@@ -15,16 +15,18 @@ service('ToolkitChromeRegistryService', 
 service('XULChromeRegistryService', 'nsIXULChromeRegistry',
         "@mozilla.org/chrome/chrome-registry;1")
 service('IOService', 'nsIIOService',
         "@mozilla.org/network/io-service;1")
 service('ObserverService', 'nsIObserverService',
         "@mozilla.org/observer-service;1")
 service('StringBundleService', 'nsIStringBundleService',
         "@mozilla.org/intl/stringbundle;1")
+service('XPConnect', 'nsIXPConnect',
+        "@mozilla.org/js/xpc/XPConnect;1")
 service('PermissionManager', 'nsIPermissionManager',
         "@mozilla.org/permissionmanager;1")
 service('ServiceWorkerManager', 'nsIServiceWorkerManager',
         "@mozilla.org/serviceworkers/manager;1")
 service('AsyncShutdown', 'nsIAsyncShutdownService',
         "@mozilla.org/async-shutdown-service;1")
 service('UUIDGenerator', 'nsIUUIDGenerator',
         "@mozilla.org/uuid-generator;1")