Bug 1444745 - Part 5: Update consumers of nsIInterfaceInfo to use the nsXPTInterfaceInfo directly, r=mccr8
authorNika Layzell <nika@thelayzells.com>
Wed, 04 Apr 2018 18:45:44 -0400
changeset 467732 90e79480ebc68009799722ec9882df00f3ec986f
parent 467731 4425a51bc16542c856d9320445540d5ac5fe5ce0
child 467733 40a027a1f2cf5318f96e97cef8a5a7a388cb0a20
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1444745
milestone61.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 1444745 - Part 5: Update consumers of nsIInterfaceInfo to use the nsXPTInterfaceInfo directly, r=mccr8 Due to the decision to keep the old API on nsXPTInterfaceInfo in part 4, this is a fairly straightforward patch. 1. I had to change a couple of consumers of `IsRetval()` due to the movement of that flag. 2. I changed all code which held a nsIInterfaceInfo to hold an `const nsXPTInterfaceInfo*` instead. 3. I changed code which used the nsIInterfaceInfoManager to instead call the static methods on nsXPTInterfaceInfo.
dom/xbl/nsXBLPrototypeBinding.cpp
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeInfo.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
xpcom/build/XPCOMInit.cpp
xpcom/ds/nsIVariant.idl
xpcom/ds/nsVariant.cpp
xpcom/reflect/xptcall/genstubs.pl
xpcom/reflect/xptcall/md/unix/xptcstubs_arm_netbsd.cpp
xpcom/reflect/xptcall/md/unix/xptcstubs_netbsd_m68k.cpp
xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_netbsd.cpp
xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_netbsd.cpp
xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_openbsd.cpp
xpcom/reflect/xptcall/porting.html
xpcom/reflect/xptcall/xptcall.cpp
xpcom/reflect/xptcall/xptcprivate.h
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -29,16 +29,17 @@
 #include "nsXBLContentSink.h"
 #include "xptinfo.h"
 #include "nsIDocumentObserver.h"
 #include "nsGkAtoms.h"
 #include "nsXBLProtoImpl.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsTextFragment.h"
+#include "nsTextNode.h"
 #include "nsIScriptError.h"
 
 #include "nsXBLResourceLoader.h"
 #include "mozilla/dom/CDATASection.h"
 #include "mozilla/dom/CharacterData.h"
 #include "mozilla/dom/Comment.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/StyleSheet.h"
@@ -702,50 +703,42 @@ nsXBLPrototypeBinding::ConstructAttribut
     }
   }
 }
 
 nsresult
 nsXBLPrototypeBinding::ConstructInterfaceTable(const nsAString& aImpls)
 {
   if (!aImpls.IsEmpty()) {
-    // Obtain the interface info manager that can tell us the IID
-    // for a given interface name.
-    nsCOMPtr<nsIInterfaceInfoManager>
-      infoManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
-    if (!infoManager)
-      return NS_ERROR_FAILURE;
-
     // The user specified at least one attribute.
     NS_ConvertUTF16toUTF8 utf8impl(aImpls);
     char* str = utf8impl.BeginWriting();
     char* newStr;
     // XXX We should use a strtok function that tokenizes PRUnichars
     // so that we don't have to convert from Unicode to ASCII and then back
 
     char* token = nsCRT::strtok( str, ", ", &newStr );
     while( token != nullptr ) {
       // get the InterfaceInfo for the name
-      nsCOMPtr<nsIInterfaceInfo> iinfo;
-      infoManager->GetInfoForName(token, getter_AddRefs(iinfo));
+      const nsXPTInterfaceInfo* iinfo = nsXPTInterfaceInfo::ByName(token);
 
       if (iinfo) {
         // obtain an IID.
         const nsIID* iid = nullptr;
         iinfo->GetIIDShared(&iid);
 
         if (iid) {
           // We found a valid iid.  Add it to our table.
           mInterfaceTable.Put(*iid, mBinding);
 
           // this block adds the parent interfaces of each interface
           // defined in the xbl definition (implements="nsI...")
-          nsCOMPtr<nsIInterfaceInfo> parentInfo;
+          const nsXPTInterfaceInfo* parentInfo;
           // if it has a parent, add it to the table
-          while (NS_SUCCEEDED(iinfo->GetParent(getter_AddRefs(parentInfo))) && parentInfo) {
+          while (NS_SUCCEEDED(iinfo->GetParent(&parentInfo)) && parentInfo) {
             // get the iid
             parentInfo->GetIIDShared(&iid);
 
             // don't add nsISupports to the table
             if (!iid || iid->Equals(NS_GET_IID(nsISupports)))
               break;
 
             // add the iid to the table
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -7,35 +7,36 @@
 /* The core XPConnect public interfaces. */
 
 #include "nsISupports.idl"
 
 %{ C++
 #include "jspubtd.h"
 #include "js/TypeDecls.h"
 #include "mozilla/Attributes.h"
+#include "xptinfo.h"
 #include "nsCOMPtr.h"
 
 class nsWrapperCache;
 %}
 
 /***************************************************************************/
 
 // NB: jsval and jsid are declared in nsrootidl.idl
 
 [ptr] native JSContextPtr(JSContext);
 [ptr] native JSObjectPtr(JSObject);
 [ptr] native JSScriptPtr(JSScript);
 [ptr] native nsWrapperCachePtr(nsWrapperCache);
       native JSHandleId(JS::Handle<jsid>);
+[ptr] native InterfaceInfoPtr(const nsXPTInterfaceInfo);
 
 /***************************************************************************/
 
 // forward declarations...
-interface nsIInterfaceInfo;
 interface nsIPrincipal;
 interface nsIClassInfo;
 interface nsIVariant;
 interface nsIObjectInputStream;
 interface nsIObjectOutputStream;
 
 /***************************************************************************/
 [uuid(73e6ff4a-ab99-4d99-ac00-ba39ccb8e4d7)]
@@ -82,17 +83,17 @@ do_QueryWrappedNative(nsIXPConnectWrappe
 }
 
 %}
 
 [uuid(3a01b0d6-074b-49ed-bac3-08c76366cae4)]
 interface nsIXPConnectWrappedJS : nsIXPConnectJSObjectHolder
 {
     /* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
-    readonly attribute nsIInterfaceInfo InterfaceInfo;
+    readonly attribute InterfaceInfoPtr InterfaceInfo;
     readonly attribute nsIIDPtr         InterfaceIID;
 
     void debugDump(in short depth);
 
     void aggregatedQueryInterface(in nsIIDRef uuid,
                                   [iid_is(uuid),retval] out nsQIResult result);
 
 };
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -194,49 +194,43 @@ NS_IMPL_ISUPPORTS(nsXPCComponents_Interf
 
 NS_IMETHODIMP
 nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
                                          JSContext* cx, JSObject* obj,
                                          JS::AutoIdVector& properties,
                                          bool* _retval)
 {
 
-    // Lazily init the list of interfaces when someone tries to
-    // enumerate them.
-    if (mInterfaces.IsEmpty()) {
-        XPTInterfaceInfoManager::GetSingleton()->
-            GetScriptableInterfaces(mInterfaces);
-    }
-
-    if (!properties.reserve(mInterfaces.Length())) {
+    if (!properties.reserve(nsXPTInterfaceInfo::InterfaceCount())) {
         *_retval = false;
         return NS_OK;
     }
 
-    for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
-        nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
+    for (uint32_t index = 0; index < nsXPTInterfaceInfo::InterfaceCount(); index++) {
+        const nsXPTInterfaceInfo* interface = nsXPTInterfaceInfo::ByIndex(index);
         if (!interface)
             continue;
 
-        const char* name;
-        if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
-            RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
-            if (!idstr) {
-                *_retval = false;
-                return NS_OK;
-            }
-
-            RootedId id(cx);
-            if (!JS_StringToId(cx, idstr, &id)) {
-                *_retval = false;
-                return NS_OK;
-            }
-
-            properties.infallibleAppend(id);
+        const char* name = interface->Name();
+        if (!name)
+            continue;
+
+        RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
+        if (!idstr) {
+            *_retval = false;
+            return NS_OK;
         }
+
+        RootedId id(cx);
+        if (!JS_StringToId(cx, idstr, &id)) {
+            *_retval = false;
+            return NS_OK;
+        }
+
+        properties.infallibleAppend(id);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Interfaces::Resolve(nsIXPConnectWrappedNative* wrapper,
                                     JSContext* cx, JSObject* objArg,
@@ -249,22 +243,17 @@ nsXPCComponents_Interfaces::Resolve(nsIX
     if (!JSID_IS_STRING(id))
         return NS_OK;
 
     JSAutoByteString name;
     RootedString str(cx, JSID_TO_STRING(id));
 
     // we only allow interfaces by name here
     if (name.encodeLatin1(cx, str) && name.ptr()[0] != '{') {
-        nsCOMPtr<nsIInterfaceInfo> info =
-            ShimInterfaceInfo::MaybeConstruct(name.ptr(), cx);
-        if (!info) {
-            XPTInterfaceInfoManager::GetSingleton()->
-                GetInfoForName(name.ptr(), getter_AddRefs(info));
-        }
+        const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name.ptr());
         if (!info)
             return NS_OK;
 
         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (nsid) {
             nsXPConnect* xpc = nsXPConnect::XPConnect();
             RootedObject idobj(cx);
@@ -388,49 +377,41 @@ NS_IMPL_ISUPPORTS(nsXPCComponents_Interf
 
 NS_IMETHODIMP
 nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
                                              JSContext* cx, JSObject* obj,
                                              JS::AutoIdVector& properties,
                                              bool* _retval)
 {
 
-    if (mInterfaces.IsEmpty()) {
-        XPTInterfaceInfoManager::GetSingleton()->
-            GetScriptableInterfaces(mInterfaces);
-    }
-
-    if (!properties.reserve(mInterfaces.Length())) {
+    if (!properties.reserve(nsXPTInterfaceInfo::InterfaceCount())) {
         *_retval = false;
         return NS_OK;
     }
 
-    for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
-        nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
+    for (uint32_t index = 0; index < nsXPTInterfaceInfo::InterfaceCount(); index++) {
+        const nsXPTInterfaceInfo* interface = nsXPTInterfaceInfo::ByIndex(index);
         if (!interface)
             continue;
 
-        nsIID const* iid;
-        if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
-            char idstr[NSID_LENGTH];
-            iid->ToProvidedString(idstr);
-            RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
-            if (!jsstr) {
-                *_retval = false;
-                return NS_OK;
-            }
-
-            RootedId id(cx);
-            if (!JS_StringToId(cx, jsstr, &id)) {
-                *_retval = false;
-                return NS_OK;
-            }
-
-            properties.infallibleAppend(id);
+        char idstr[NSID_LENGTH];
+        interface->IID().ToProvidedString(idstr);
+        RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
+        if (!jsstr) {
+            *_retval = false;
+            return NS_OK;
         }
+
+        RootedId id(cx);
+        if (!JS_StringToId(cx, jsstr, &id)) {
+            *_retval = false;
+            return NS_OK;
+        }
+
+        properties.infallibleAppend(id);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_InterfacesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
                                         JSContext* cx, JSObject* objArg,
@@ -448,19 +429,17 @@ nsXPCComponents_InterfacesByID::Resolve(
         return NS_OK;
 
     JSAutoByteString utf8str;
     if (utf8str.encodeUtf8(cx, str)) {
         nsID iid;
         if (!iid.Parse(utf8str.ptr()))
             return NS_OK;
 
-        nsCOMPtr<nsIInterfaceInfo> info;
-        XPTInterfaceInfoManager::GetSingleton()->
-            GetInfoForIID(&iid, getter_AddRefs(info));
+        const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(iid);
         if (!info)
             return NS_OK;
 
         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
 
         if (!nsid)
             return NS_ERROR_OUT_OF_MEMORY;
 
@@ -1927,18 +1906,18 @@ nsXPCComponents_Constructor::CallOrConst
 
         nsCOMPtr<nsIXPConnectWrappedNative> wn;
         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, &val.toObject(),
                                                       getter_AddRefs(wn))) || !wn ||
             !(cInterfaceID = do_QueryWrappedNative(wn))) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
     } else {
-        nsCOMPtr<nsIInterfaceInfo> info;
-        xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info));
+        const nsXPTInterfaceInfo* info =
+            nsXPTInterfaceInfo::ByIID(NS_GET_IID(nsISupports));
 
         if (info) {
             cInterfaceID = nsJSIID::NewID(info);
         }
         if (!cInterfaceID)
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
     }
 
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1360,81 +1360,81 @@ XPCConvert::JSTypedArray2Native(void** d
 
         return false;
     }
 
     void* output = nullptr;
 
     switch (JS_GetArrayBufferViewType(jsArray)) {
     case js::Scalar::Int8:
-        output = CheckTargetAndPopulate(nsXPTType::T_I8, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_I8 }, type,
                                         sizeof(int8_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Uint8:
     case js::Scalar::Uint8Clamped:
-        output = CheckTargetAndPopulate(nsXPTType::T_U8, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_U8 }, type,
                                         sizeof(uint8_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Int16:
-        output = CheckTargetAndPopulate(nsXPTType::T_I16, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_I16 }, type,
                                         sizeof(int16_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Uint16:
-        output = CheckTargetAndPopulate(nsXPTType::T_U16, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_U16 }, type,
                                         sizeof(uint16_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Int32:
-        output = CheckTargetAndPopulate(nsXPTType::T_I32, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_I32 }, type,
                                         sizeof(int32_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Uint32:
-        output = CheckTargetAndPopulate(nsXPTType::T_U32, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_U32 }, type,
                                         sizeof(uint32_t), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Float32:
-        output = CheckTargetAndPopulate(nsXPTType::T_FLOAT, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_FLOAT }, type,
                                         sizeof(float), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     case js::Scalar::Float64:
-        output = CheckTargetAndPopulate(nsXPTType::T_DOUBLE, type,
+        output = CheckTargetAndPopulate({ nsXPTType::T_DOUBLE }, type,
                                         sizeof(double), count,
                                         jsArray, pErr);
         if (!output) {
             return false;
         }
         break;
 
     // Yet another array type was defined? It is not supported yet...
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -282,17 +282,17 @@ NS_IMPL_CI_INTERFACE_GETTER(nsJSIID, nsI
 #define XPC_MAP_QUOTED_CLASSNAME "nsJSIID"
 #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
                        XPC_SCRIPTABLE_WANT_ENUMERATE | \
                        XPC_SCRIPTABLE_WANT_HASINSTANCE | \
                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
 #include "xpc_map_end.h" /* This will #undef the above */
 
 
-nsJSIID::nsJSIID(nsIInterfaceInfo* aInfo)
+nsJSIID::nsJSIID(const nsXPTInterfaceInfo* aInfo)
     : mInfo(aInfo)
 {
 }
 
 nsJSIID::~nsJSIID() {}
 
 // If mInfo is present we use it and ignore mDetails, else we use mDetails.
 
@@ -345,25 +345,24 @@ NS_IMETHODIMP nsJSIID::Initialize(const 
 
 NS_IMETHODIMP nsJSIID::ToString(char** _retval)
 {
     return mInfo->GetName(_retval);
 }
 
 // static
 already_AddRefed<nsJSIID>
-nsJSIID::NewID(nsIInterfaceInfo* aInfo)
+nsJSIID::NewID(const nsXPTInterfaceInfo* aInfo)
 {
     if (!aInfo) {
         NS_ERROR("no info");
         return nullptr;
     }
 
-    bool canScript;
-    if (NS_FAILED(aInfo->IsScriptable(&canScript)) || !canScript)
+    if (!aInfo->IsScriptable())
         return nullptr;
 
     RefPtr<nsJSIID> idObj = new nsJSIID(aInfo);
     return idObj.forget();
 }
 
 
 NS_IMETHODIMP
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -213,38 +213,38 @@ XPCArrayHomogenizer::GetTypeForArray(JSC
         MOZ_ASSERT(state != tUnk, "bad state table!");
 
         if (state == tVar)
             break;
     }
 
     switch (state) {
         case tInt :
-            *resultType = nsXPTType((uint8_t)TD_INT32);
+            *resultType = TD_INT32;
             break;
         case tDbl :
-            *resultType = nsXPTType((uint8_t)TD_DOUBLE);
+            *resultType = TD_DOUBLE;
             break;
         case tBool:
-            *resultType = nsXPTType((uint8_t)TD_BOOL);
+            *resultType = TD_BOOL;
             break;
         case tStr :
-            *resultType = nsXPTType((uint8_t)TD_PWSTRING);
+            *resultType = TD_PWSTRING;
             break;
         case tID  :
-            *resultType = nsXPTType((uint8_t)TD_PNSIID);
+            *resultType = TD_PNSIID;
             break;
         case tISup:
-            *resultType = nsXPTType((uint8_t)TD_INTERFACE_IS_TYPE);
+            *resultType = TD_INTERFACE_IS_TYPE;
             *resultID = NS_GET_IID(nsISupports);
             break;
         case tNull:
             // FALL THROUGH
         case tVar :
-            *resultType = nsXPTType((uint8_t)TD_INTERFACE_IS_TYPE);
+            *resultType = TD_INTERFACE_IS_TYPE;
             *resultID = NS_GET_IID(nsIVariant);
             break;
         case tArr :
             // FALL THROUGH
         case tUnk :
             // FALL THROUGH
         case tErr :
             // FALL THROUGH
@@ -448,122 +448,122 @@ XPCVariant::VariantDataToJS(nsIVariant* 
             pJSVal.setBoolean(b);
             return true;
         }
         case nsIDataType::VTYPE_CHAR:
         {
             char c;
             if (NS_FAILED(variant->GetAsChar(&c)))
                 return false;
-            return XPCConvert::NativeData2JS(pJSVal, (const void*)&c, TD_CHAR, &iid, pErr);
+            return XPCConvert::NativeData2JS(pJSVal, (const void*)&c, { TD_CHAR }, &iid, pErr);
         }
         case nsIDataType::VTYPE_WCHAR:
         {
             char16_t wc;
             if (NS_FAILED(variant->GetAsWChar(&wc)))
                 return false;
-            return XPCConvert::NativeData2JS(pJSVal, (const void*)&wc, TD_WCHAR, &iid, pErr);
+            return XPCConvert::NativeData2JS(pJSVal, (const void*)&wc, { TD_WCHAR }, &iid, pErr);
         }
         case nsIDataType::VTYPE_ID:
         {
             if (NS_FAILED(variant->GetAsID(&iid)))
                 return false;
             nsID* v = &iid;
-            return XPCConvert::NativeData2JS(pJSVal, (const void*)&v, TD_PNSIID, &iid, pErr);
+            return XPCConvert::NativeData2JS(pJSVal, (const void*)&v, { TD_PNSIID }, &iid, pErr);
         }
         case nsIDataType::VTYPE_ASTRING:
         {
             nsAutoString astring;
             if (NS_FAILED(variant->GetAsAString(astring)))
                 return false;
             nsAutoString* v = &astring;
-            return XPCConvert::NativeData2JS(pJSVal, (const void*)&v, TD_ASTRING, &iid, pErr);
+            return XPCConvert::NativeData2JS(pJSVal, (const void*)&v, { TD_ASTRING }, &iid, pErr);
         }
         case nsIDataType::VTYPE_DOMSTRING:
         {
             nsAutoString astring;
             if (NS_FAILED(variant->GetAsAString(astring)))
                 return false;
             nsAutoString* v = &astring;
             return XPCConvert::NativeData2JS(pJSVal, (const void*)&v,
-                                             TD_DOMSTRING, &iid, pErr);
+                                             { TD_DOMSTRING }, &iid, pErr);
         }
         case nsIDataType::VTYPE_CSTRING:
         {
             nsAutoCString cString;
             if (NS_FAILED(variant->GetAsACString(cString)))
                 return false;
             nsAutoCString* v = &cString;
             return XPCConvert::NativeData2JS(pJSVal, (const void*)&v,
-                                             TD_CSTRING, &iid, pErr);
+                                             { TD_CSTRING }, &iid, pErr);
         }
         case nsIDataType::VTYPE_UTF8STRING:
         {
             nsUTF8String utf8String;
             if (NS_FAILED(variant->GetAsAUTF8String(utf8String)))
                 return false;
             nsUTF8String* v = &utf8String;
             return XPCConvert::NativeData2JS(pJSVal, (const void*)&v,
-                                             TD_UTF8STRING, &iid, pErr);
+                                             { TD_UTF8STRING }, &iid, pErr);
         }
         case nsIDataType::VTYPE_CHAR_STR:
         {
             char* pc;
             if (NS_FAILED(variant->GetAsString(&pc)))
                 return false;
             bool success = XPCConvert::NativeData2JS(pJSVal, (const void*)&pc,
-                                                     TD_PSTRING, &iid, pErr);
+                                                     { TD_PSTRING }, &iid, pErr);
             free(pc);
             return success;
         }
         case nsIDataType::VTYPE_STRING_SIZE_IS:
         {
             char* pc;
             uint32_t size;
             if (NS_FAILED(variant->GetAsStringWithSize(&size, &pc)))
                 return false;
             bool success = XPCConvert::NativeStringWithSize2JS(pJSVal, (const void*)&pc,
-                                                               TD_PSTRING_SIZE_IS, size, pErr);
+                                                               { TD_PSTRING_SIZE_IS }, size, pErr);
             free(pc);
             return success;
         }
         case nsIDataType::VTYPE_WCHAR_STR:
         {
             char16_t* pwc;
             if (NS_FAILED(variant->GetAsWString(&pwc)))
                 return false;
             bool success = XPCConvert::NativeData2JS(pJSVal, (const void*)&pwc,
-                                                     TD_PSTRING, &iid, pErr);
+                                                     { TD_PSTRING }, &iid, pErr);
             free(pwc);
             return success;
         }
         case nsIDataType::VTYPE_WSTRING_SIZE_IS:
         {
             char16_t* pwc;
             uint32_t size;
             if (NS_FAILED(variant->GetAsWStringWithSize(&size, &pwc)))
                 return false;
             bool success = XPCConvert::NativeStringWithSize2JS(pJSVal, (const void*)&pwc,
-                                                               TD_PWSTRING_SIZE_IS, size, pErr);
+                                                               { TD_PWSTRING_SIZE_IS }, size, pErr);
             free(pwc);
             return success;
         }
         case nsIDataType::VTYPE_INTERFACE:
         case nsIDataType::VTYPE_INTERFACE_IS:
         {
             nsISupports* pi;
             nsID* piid;
             if (NS_FAILED(variant->GetAsInterface(&piid, (void**)&pi)))
                 return false;
 
             iid = *piid;
             free((char*)piid);
 
             bool success = XPCConvert::NativeData2JS(pJSVal, (const void*)&pi,
-                                                     TD_INTERFACE_IS_TYPE, &iid, pErr);
+                                                     { TD_INTERFACE_IS_TYPE }, &iid, pErr);
             if (pi)
                 pi->Release();
             return success;
         }
         case nsIDataType::VTYPE_ARRAY:
         {
             nsDiscriminatedUnion du;
             nsresult rv;
@@ -591,33 +591,33 @@ XPCVariant::VariantDataToJS(nsIVariant* 
                 case nsIDataType::VTYPE_UINT16:
                 case nsIDataType::VTYPE_UINT32:
                 case nsIDataType::VTYPE_UINT64:
                 case nsIDataType::VTYPE_FLOAT:
                 case nsIDataType::VTYPE_DOUBLE:
                 case nsIDataType::VTYPE_BOOL:
                 case nsIDataType::VTYPE_CHAR:
                 case nsIDataType::VTYPE_WCHAR:
-                    conversionType = nsXPTType((uint8_t)elementType);
+                    conversionType = (uint8_t)elementType;
                     break;
 
                 case nsIDataType::VTYPE_ID:
                 case nsIDataType::VTYPE_CHAR_STR:
                 case nsIDataType::VTYPE_WCHAR_STR:
-                    conversionType = nsXPTType((uint8_t)elementType);
+                    conversionType = (uint8_t)elementType;
                     break;
 
                 case nsIDataType::VTYPE_INTERFACE:
                     pid = &NS_GET_IID(nsISupports);
-                    conversionType = nsXPTType((uint8_t)elementType);
+                    conversionType = (uint8_t)elementType;
                     break;
 
                 case nsIDataType::VTYPE_INTERFACE_IS:
                     pid = &du.u.array.mArrayInterfaceID;
-                    conversionType = nsXPTType((uint8_t)elementType);
+                    conversionType = (uint8_t)elementType;
                     break;
 
                 // The rest are illegal.
                 case nsIDataType::VTYPE_VOID:
                 case nsIDataType::VTYPE_ASTRING:
                 case nsIDataType::VTYPE_DOMSTRING:
                 case nsIDataType::VTYPE_CSTRING:
                 case nsIDataType::VTYPE_UTF8STRING:
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -580,29 +580,26 @@ nsXPCWrappedJS::FindInherited(REFNSIID a
                          HasAncestor(&aIID, &found)) && found)
             return cur;
     }
 
     return nullptr;
 }
 
 NS_IMETHODIMP
-nsXPCWrappedJS::GetInterfaceInfo(nsIInterfaceInfo** infoResult)
+nsXPCWrappedJS::GetInterfaceInfo(const nsXPTInterfaceInfo** infoResult)
 {
     MOZ_ASSERT(GetClass(), "wrapper without class");
     MOZ_ASSERT(GetClass()->GetInterfaceInfo(), "wrapper class without interface");
 
     // Since failing to get this info will crash some platforms(!), we keep
     // mClass valid at shutdown time.
 
-    nsCOMPtr<nsIInterfaceInfo> info = GetClass()->GetInterfaceInfo();
-    if (!info)
-        return NS_ERROR_UNEXPECTED;
-    info.forget(infoResult);
-    return NS_OK;
+    *infoResult = GetClass()->GetInterfaceInfo();
+    return *infoResult ? NS_OK : NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::CallMethod(uint16_t methodIndex,
                            const nsXPTMethodInfo* info,
                            nsXPTCMiniVariant* params)
 {
     // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread.
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -108,35 +108,34 @@ private:
 already_AddRefed<nsXPCWrappedJSClass>
 nsXPCWrappedJSClass::GetNewOrUsed(JSContext* cx, REFNSIID aIID, bool allowNonScriptable)
 {
     XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance();
     IID2WrappedJSClassMap* map = xpcrt->GetWrappedJSClassMap();
     RefPtr<nsXPCWrappedJSClass> clasp = map->Find(aIID);
 
     if (!clasp) {
-        nsCOMPtr<nsIInterfaceInfo> info;
-        nsXPConnect::XPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
+        const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID);
         if (info) {
             bool canScript, isBuiltin;
             if (NS_SUCCEEDED(info->IsScriptable(&canScript)) && (canScript || allowNonScriptable) &&
                 NS_SUCCEEDED(info->IsBuiltinClass(&isBuiltin)) && !isBuiltin &&
                 nsXPConnect::IsISupportsDescendant(info))
             {
                 clasp = new nsXPCWrappedJSClass(cx, aIID, info);
                 if (!clasp->mDescriptors)
                     clasp = nullptr;
             }
         }
     }
     return clasp.forget();
 }
 
 nsXPCWrappedJSClass::nsXPCWrappedJSClass(JSContext* cx, REFNSIID aIID,
-                                         nsIInterfaceInfo* aInfo)
+                                         const nsXPTInterfaceInfo* aInfo)
     : mRuntime(nsXPConnect::GetRuntimeInstance()),
       mInfo(aInfo),
       mName(nullptr),
       mIID(aIID),
       mDescriptors(nullptr)
 {
     mRuntime->GetWrappedJSClassMap()->Add(this);
 
@@ -220,24 +219,22 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
     // 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))) {
         bool allowNonScriptable = mozilla::jsipc::IsWrappedCPOW(jsobj);
 
-        nsCOMPtr<nsIInterfaceInfo> info;
-        nsXPConnect::XPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
-        if (!info)
+        const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID);
+        if (!info || info->IsBuiltinClass() ||
+            (!info->IsScriptable() && !allowNonScriptable))
+        {
             return nullptr;
-        bool canScript, isBuiltin;
-        if (NS_FAILED(info->IsScriptable(&canScript)) || (!canScript && !allowNonScriptable) ||
-            NS_FAILED(info->IsBuiltinClass(&isBuiltin)) || isBuiltin)
-            return nullptr;
+        }
     }
 
     id = xpc_NewIDObject(cx, jsobj, aIID);
     if (id) {
         // Throwing NS_NOINTERFACE is the prescribed way to fail QI from JS. It
         // is not an exception that is ever worth reporting, but we don't want
         // to eat all exceptions either.
 
@@ -290,17 +287,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
 
 static bool
 GetNamedPropertyAsVariantRaw(XPCCallContext& ccx,
                              HandleObject aJSObj,
                              HandleId aName,
                              nsIVariant** aResult,
                              nsresult* pErr)
 {
-    nsXPTType type = nsXPTType((uint8_t)TD_INTERFACE_TYPE);
+    nsXPTType type = { TD_INTERFACE_TYPE };
     RootedValue val(ccx);
 
     return JS_GetPropertyById(ccx, aJSObj, aName, &val) &&
            XPCConvert::JSData2Native(aResult, val, type,
                                      &NS_GET_IID(nsIVariant), pErr);
 }
 
 // static
@@ -485,17 +482,17 @@ GetFunctionName(JSContext* cx, HandleObj
     } else {
         filenameSuffix = filename;
     }
 
     nsCString displayName("anonymous");
     if (funName) {
         nsCString* displayNamePtr = &displayName;
         RootedValue funNameVal(cx, StringValue(funName));
-        if (!XPCConvert::JSData2Native(&displayNamePtr, funNameVal, nsXPTType::T_UTF8STRING,
+        if (!XPCConvert::JSData2Native(&displayNamePtr, funNameVal, { nsXPTType::T_UTF8STRING },
                                        nullptr, nullptr))
         {
             JS_ClearPendingException(cx);
             return nsCString("anonymous");
         }
     }
 
     displayName.Append('[');
@@ -582,20 +579,18 @@ nsXPCWrappedJSClass::DelegatedQueryInter
         NS_ADDREF(sibling);
         *aInstancePtr = sibling->GetXPTCStub();
         return NS_OK;
     }
 
     // Check if the desired interface is a function interface. If so, we don't
     // want to QI, because the function almost certainly doesn't have a QueryInterface
     // property, and doesn't need one.
-    bool isFunc = false;
-    nsCOMPtr<nsIInterfaceInfo> info;
-    nsXPConnect::XPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info));
-    if (info && NS_SUCCEEDED(info->IsFunction(&isFunc)) && isFunc) {
+    const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID);
+    if (info && info->IsFunction()) {
         RefPtr<nsXPCWrappedJS> wrapper;
         RootedObject obj(RootingCx(), self->GetJSObject());
         nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, aIID, getter_AddRefs(wrapper));
 
         // Do the same thing we do for the "check for any existing wrapper" case above.
         if (NS_SUCCEEDED(rv) && wrapper) {
             *aInstancePtr = wrapper.forget().take()->GetXPTCStub();
         }
@@ -1026,17 +1021,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     AutoScriptEvaluate scriptEval(cx);
 
     XPCJSContext* xpccx = ccx.GetContext();
     AutoSavePendingResult apr(xpccx);
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
     uint8_t paramCount = info->GetParamCount();
     uint8_t argc = paramCount;
-    if (paramCount > 0 && info->GetParam(paramCount - 1).IsRetval()) {
+    if (info->HasRetval()) {
         argc -= 1;
     }
 
     if (!scriptEval.StartEvaluating(obj))
         goto pre_call_clean_up;
 
     xpccx->SetPendingException(nullptr);
 
@@ -1258,17 +1253,17 @@ pre_call_clean_up:
         uint8_t type_tag = type.TagPart();
         nsXPTCMiniVariant* pv;
 
         if (param.IsDipper())
             pv = (nsXPTCMiniVariant*) &nativeParams[i].val.p;
         else
             pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
 
-        if (param.IsRetval())
+        if (&param == info->GetRetval())
             val = rval;
         else if (argv[i].isPrimitive())
             break;
         else {
             RootedObject obj(cx, &argv[i].toObject());
             if (!JS_GetPropertyById(cx, obj,
                                     mRuntime->GetStringID(XPCJSContext::IDX_VALUE),
                                     &val))
@@ -1307,17 +1302,17 @@ pre_call_clean_up:
             bool isArray = type.IsArray();
             bool isSizedString = isArray ?
                     false :
                     type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
                     type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
             pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
 
-            if (param.IsRetval())
+            if (&param == info->GetRetval())
                 val = rval;
             else {
                 RootedObject obj(cx, &argv[i].toObject());
                 if (!JS_GetPropertyById(cx, obj,
                                         mRuntime->GetStringID(XPCJSContext::IDX_VALUE),
                                         &val))
                     break;
             }
@@ -1414,24 +1409,24 @@ nsXPCWrappedJSClass::DebugDump(int16_t d
         mInfo->GetName(&name);
         XPC_LOG_ALWAYS(("interface name is %s", name));
         if (name)
             free(name);
         char * iid = mIID.ToString();
         XPC_LOG_ALWAYS(("IID number is %s", iid ? iid : "invalid"));
         if (iid)
             free(iid);
-        XPC_LOG_ALWAYS(("InterfaceInfo @ %p", mInfo.get()));
+        XPC_LOG_ALWAYS(("InterfaceInfo @ %p", mInfo));
         uint16_t methodCount = 0;
         if (depth) {
             uint16_t i;
-            nsCOMPtr<nsIInterfaceInfo> parent;
+            const nsXPTInterfaceInfo* parent;
             XPC_LOG_INDENT();
-            mInfo->GetParent(getter_AddRefs(parent));
-            XPC_LOG_ALWAYS(("parent @ %p", parent.get()));
+            mInfo->GetParent(&parent);
+            XPC_LOG_ALWAYS(("parent @ %p", parent));
             mInfo->GetMethodCount(&methodCount);
             XPC_LOG_ALWAYS(("MethodCount = %d", methodCount));
             mInfo->GetConstantCount(&i);
             XPC_LOG_ALWAYS(("ConstantCount = %d", i));
             XPC_LOG_OUTDENT();
         }
         XPC_LOG_ALWAYS(("mRuntime @ %p", mRuntime));
         XPC_LOG_ALWAYS(("mDescriptors @ %p count = %d", mDescriptors, methodCount));
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1131,17 +1131,17 @@ static bool Throw(nsresult errNum, XPCCa
 }
 
 /***************************************************************************/
 
 class MOZ_STACK_CLASS CallMethodHelper
 {
     XPCCallContext& mCallContext;
     nsresult mInvokeResult;
-    nsIInterfaceInfo* const mIFaceInfo;
+    const nsXPTInterfaceInfo* const mIFaceInfo;
     const nsXPTMethodInfo* mMethodInfo;
     nsISupports* const mCallee;
     const uint16_t mVTableIndex;
     HandleId mIdxValueId;
 
     AutoTArray<nsXPTCVariant, 8> mDispatchParams;
     uint8_t mJSContextIndex; // TODO make const
     uint8_t mOptArgcIndex; // TODO make const
@@ -1394,19 +1394,20 @@ CallMethodHelper::GetInterfaceTypeFromPa
     }
     return true;
 }
 
 bool
 CallMethodHelper::GetOutParamSource(uint8_t paramIndex, MutableHandleValue srcp) const
 {
     const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(paramIndex);
+    bool isRetval = &paramInfo == mMethodInfo->GetRetval();
 
     MOZ_ASSERT(!paramInfo.IsDipper(), "Dipper params are handled separately");
-    if (paramInfo.IsOut() && !paramInfo.IsRetval()) {
+    if (paramInfo.IsOut() && !isRetval) {
         MOZ_ASSERT(paramIndex < mArgc || paramInfo.IsOptional(),
                    "Expected either enough arguments or an optional argument");
         Value arg = paramIndex < mArgc ? mArgv[paramIndex] : JS::NullValue();
         if (paramIndex < mArgc) {
             RootedObject obj(mCallContext);
             if (!arg.isPrimitive())
                 obj = &arg.toObject();
             if (!obj || !JS_GetPropertyById(mCallContext, obj, mIdxValueId, srcp)) {
@@ -1483,17 +1484,17 @@ CallMethodHelper::GatherAndConvertResult
         } else {
             if (!XPCConvert::NativeData2JS(&v, &dp->val, datum_type,
                                            &param_iid, &err)) {
                 ThrowBadParam(err, i, mCallContext);
                 return false;
             }
         }
 
-        if (paramInfo.IsRetval()) {
+        if (&paramInfo == mMethodInfo->GetRetval()) {
             mCallContext.SetRetVal(v);
         } else if (i < mArgc) {
             // we actually assured this before doing the invoke
             MOZ_ASSERT(mArgv[i].isObject(), "out var is not object");
             RootedObject obj(mCallContext, &mArgv[i].toObject());
             if (!JS_SetPropertyById(mCallContext, obj, mIdxValueId, v)) {
                 ThrowBadParam(NS_ERROR_XPC_CANT_SET_OUT_VAL, i, mCallContext);
                 return false;
@@ -1536,17 +1537,17 @@ CallMethodHelper::QueryInterfaceFastPath
         ThrowBadResult(mInvokeResult, mCallContext);
         return false;
     }
 
     RootedValue v(mCallContext, NullValue());
     nsresult err;
     bool success =
         XPCConvert::NativeData2JS(&v, &qiresult,
-                                  nsXPTType::T_INTERFACE_IS,
+                                  { nsXPTType::T_INTERFACE_IS },
                                   iid, &err);
     NS_IF_RELEASE(qiresult);
 
     if (!success) {
         ThrowBadParam(err, 0, mCallContext);
         return false;
     }
 
@@ -1559,17 +1560,17 @@ CallMethodHelper::InitializeDispatchPara
 {
     const uint8_t wantsOptArgc = mMethodInfo->WantsOptArgc() ? 1 : 0;
     const uint8_t wantsJSContext = mMethodInfo->WantsContext() ? 1 : 0;
     const uint8_t paramCount = mMethodInfo->GetParamCount();
     uint8_t requiredArgs = paramCount;
     uint8_t hasRetval = 0;
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
-    if (paramCount && mMethodInfo->GetParam(paramCount-1).IsRetval()) {
+    if (mMethodInfo->HasRetval()) {
         hasRetval = 1;
         requiredArgs--;
     }
 
     if (mArgc < requiredArgs || wantsOptArgc) {
         if (wantsOptArgc)
             mOptArgcIndex = requiredArgs;
 
@@ -2067,17 +2068,17 @@ static void DEBUG_CheckClassInfoClaims(X
         return;
 
     nsISupports* obj = wrapper->GetIdentityObject();
     XPCNativeSet* set = wrapper->GetSet();
     uint16_t count = set->GetInterfaceCount();
     for (uint16_t i = 0; i < count; i++) {
         nsIClassInfo* clsInfo = wrapper->GetClassInfo();
         XPCNativeInterface* iface = set->GetInterfaceAt(i);
-        nsIInterfaceInfo* info = iface->GetInterfaceInfo();
+        const nsXPTInterfaceInfo* info = iface->GetInterfaceInfo();
         const nsIID* iid;
         nsISupports* ptr;
 
         info->GetIIDShared(&iid);
         nsresult rv = obj->QueryInterface(*iid, (void**)&ptr);
         if (NS_SUCCEEDED(rv)) {
             NS_RELEASE(ptr);
             continue;
--- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp
@@ -72,18 +72,18 @@ XPCNativeMember::Resolve(XPCCallContext&
     JSNative callback;
 
     if (IsMethod()) {
         const nsXPTMethodInfo* info;
         if (NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info)))
             return false;
 
         // Note: ASSUMES that retval is last arg.
-        argc = (int) info->GetParamCount();
-        if (argc && info->GetParam((uint8_t)(argc-1)).IsRetval())
+        argc = (int) info->ParamCount();
+        if (info->HasRetval())
             argc-- ;
 
         callback = XPC_WN_CallMethod;
     } else {
         argc = 0;
         callback = XPC_WN_GetterSetter;
     }
 
@@ -124,18 +124,17 @@ XPCNativeInterface::GetNewOrUsed(const n
     if (!map)
         return nullptr;
 
     iface = map->Find(*iid);
 
     if (iface)
         return iface.forget();
 
-    nsCOMPtr<nsIInterfaceInfo> info;
-    XPTInterfaceInfoManager::GetSingleton()->GetInfoForIID(iid, getter_AddRefs(info));
+    const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(*iid);
     if (!info)
         return nullptr;
 
     iface = NewInstance(info);
     if (!iface)
         return nullptr;
 
     XPCNativeInterface* iface2 = map->Add(iface);
@@ -146,17 +145,17 @@ XPCNativeInterface::GetNewOrUsed(const n
         iface = iface2;
     }
 
     return iface.forget();
 }
 
 // static
 already_AddRefed<XPCNativeInterface>
-XPCNativeInterface::GetNewOrUsed(nsIInterfaceInfo* info)
+XPCNativeInterface::GetNewOrUsed(const nsXPTInterfaceInfo* info)
 {
     RefPtr<XPCNativeInterface> iface;
 
     const nsIID* iid;
     if (NS_FAILED(info->GetIIDShared(&iid)) || !iid)
         return nullptr;
 
     XPCJSRuntime* rt = XPCJSRuntime::Get();
@@ -184,32 +183,31 @@ XPCNativeInterface::GetNewOrUsed(nsIInte
 
     return iface.forget();
 }
 
 // static
 already_AddRefed<XPCNativeInterface>
 XPCNativeInterface::GetNewOrUsed(const char* name)
 {
-    nsCOMPtr<nsIInterfaceInfo> info;
-    XPTInterfaceInfoManager::GetSingleton()->GetInfoForName(name, getter_AddRefs(info));
+    const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name);
     return info ? GetNewOrUsed(info) : nullptr;
 }
 
 // static
 already_AddRefed<XPCNativeInterface>
 XPCNativeInterface::GetISupports()
 {
     // XXX We should optimize this to cache this common XPCNativeInterface.
     return GetNewOrUsed(&NS_GET_IID(nsISupports));
 }
 
 // static
 already_AddRefed<XPCNativeInterface>
-XPCNativeInterface::NewInstance(nsIInterfaceInfo* aInfo)
+XPCNativeInterface::NewInstance(const nsXPTInterfaceInfo* aInfo)
 {
     AutoJSContext cx;
     static const uint16_t MAX_LOCAL_MEMBER_COUNT = 16;
     XPCNativeMember local_members[MAX_LOCAL_MEMBER_COUNT];
     RefPtr<XPCNativeInterface> obj;
     XPCNativeMember* members = nullptr;
 
     int i;
@@ -414,17 +412,17 @@ void
 XPCNativeInterface::DebugDump(int16_t depth)
 {
 #ifdef DEBUG
     depth--;
     XPC_LOG_ALWAYS(("XPCNativeInterface @ %p", this));
         XPC_LOG_INDENT();
         XPC_LOG_ALWAYS(("name is %s", GetNameString()));
         XPC_LOG_ALWAYS(("mMemberCount is %d", mMemberCount));
-        XPC_LOG_ALWAYS(("mInfo @ %p", mInfo.get()));
+        XPC_LOG_ALWAYS(("mInfo @ %p", mInfo));
         XPC_LOG_OUTDENT();
 #endif
 }
 
 /***************************************************************************/
 // XPCNativeSetKey
 
 static PLDHashNumber
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -171,22 +171,19 @@ XPCJSRuntime*
 nsXPConnect::GetRuntimeInstance()
 {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     return gSelf->mRuntime;
 }
 
 // static
 bool
-nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
+nsXPConnect::IsISupportsDescendant(const nsXPTInterfaceInfo* info)
 {
-    bool found = false;
-    if (info)
-        info->HasAncestor(&NS_GET_IID(nsISupports), &found);
-    return found;
+    return info && info->HasAncestor(NS_GET_IID(nsISupports));
 }
 
 void
 xpc::ErrorBase::Init(JSErrorBase* aReport)
 {
     if (!aReport->filename)
         mFileName.SetIsVoid(true);
     else
@@ -389,22 +386,16 @@ xpc::ErrorReport::ErrorReportToMessageSt
         }
         aString.Append(NS_ConvertUTF8toUTF16(aReport->message().c_str()));
     }
 }
 
 /***************************************************************************/
 
 
-nsresult
-nsXPConnect::GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info)
-{
-  return XPTInterfaceInfoManager::GetSingleton()->GetInfoForIID(aIID, info);
-}
-
 void
 xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS)
 {
     // QIing to nsIXPConnectWrappedJSUnmarkGray may have side effects!
     nsCOMPtr<nsIXPConnectWrappedJSUnmarkGray> wjsug =
       do_QueryInterface(aWrappedJS);
     Unused << wjsug;
     MOZ_ASSERT(!wjsug, "One should never be able to QI to "
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -238,17 +238,17 @@ public:
         if (!MOZ_LIKELY(NS_IsMainThread()))
             MOZ_CRASH();
 
         return gSelf;
     }
 
     static XPCJSRuntime* GetRuntimeInstance();
 
-    static bool IsISupportsDescendant(nsIInterfaceInfo* info);
+    static bool IsISupportsDescendant(const nsXPTInterfaceInfo* info);
 
     static nsIScriptSecurityManager* SecurityManager()
     {
         MOZ_ASSERT(NS_IsMainThread());
         MOZ_ASSERT(gScriptSecurityManager);
         return gScriptSecurityManager;
     }
 
@@ -263,18 +263,16 @@ public:
 
     // 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;}
 
-    nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
-
     void RecordTraversal(void* p, nsISupports* s);
 
 protected:
     virtual ~nsXPConnect();
 
     nsXPConnect();
 
 private:
@@ -1136,22 +1134,22 @@ private:
 
 class XPCNativeInterface final
 {
   public:
     NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeInterface,
                                             DestroyInstance(this))
 
     static already_AddRefed<XPCNativeInterface> GetNewOrUsed(const nsIID* iid);
-    static already_AddRefed<XPCNativeInterface> GetNewOrUsed(nsIInterfaceInfo* info);
+    static already_AddRefed<XPCNativeInterface> GetNewOrUsed(const nsXPTInterfaceInfo* info);
     static already_AddRefed<XPCNativeInterface> GetNewOrUsed(const char* name);
     static already_AddRefed<XPCNativeInterface> GetISupports();
 
-    inline nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo.get();}
-    inline jsid              GetName()          const {return mName;}
+    inline const nsXPTInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
+    inline jsid                      GetName()          const {return mName;}
 
     inline const nsIID* GetIID() const;
     inline const char*  GetNameString() const;
     inline XPCNativeMember* FindMember(jsid name) const;
 
     inline bool HasAncestor(const nsIID* iid) const;
     static inline size_t OffsetOfMembers();
 
@@ -1163,33 +1161,33 @@ class XPCNativeInterface final
         return &mMembers[i];
     }
 
     void DebugDump(int16_t depth);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
   protected:
-    static already_AddRefed<XPCNativeInterface> NewInstance(nsIInterfaceInfo* aInfo);
+    static already_AddRefed<XPCNativeInterface> NewInstance(const nsXPTInterfaceInfo* aInfo);
 
     XPCNativeInterface() = delete;
-    XPCNativeInterface(nsIInterfaceInfo* aInfo, jsid aName)
+    XPCNativeInterface(const nsXPTInterfaceInfo* aInfo, jsid aName)
       : mInfo(aInfo), mName(aName), mMemberCount(0)
     {}
     ~XPCNativeInterface();
 
     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
 
     XPCNativeInterface(const XPCNativeInterface& r) = delete;
     XPCNativeInterface& operator= (const XPCNativeInterface& r) = delete;
 
     static void DestroyInstance(XPCNativeInterface* inst);
 
 private:
-    nsCOMPtr<nsIInterfaceInfo> mInfo;
+    const nsXPTInterfaceInfo*  mInfo;
     jsid                       mName;
     uint16_t                   mMemberCount;
     XPCNativeMember            mMembers[1]; // always last - object sized for array
 };
 
 /***************************************************************************/
 // XPCNativeSetKey is used to key a XPCNativeSet in a NativeSetMap.
 // It represents a new XPCNativeSet we are considering constructing, without
@@ -1749,17 +1747,17 @@ public:
 
     static already_AddRefed<nsXPCWrappedJSClass>
     GetNewOrUsed(JSContext* cx,
                  REFNSIID aIID,
                  bool allowNonScriptable = false);
 
     REFNSIID GetIID() const {return mIID;}
     XPCJSRuntime* GetRuntime() const {return mRuntime;}
-    nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
+    const nsXPTInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
     const char* GetInterfaceName();
 
     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
                                        void** aInstancePtr);
 
     JSObject* GetRootJSObject(JSContext* cx, JSObject* aJSObj);
 
     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
@@ -1786,17 +1784,17 @@ private:
                                       mozilla::dom::AutoEntryScript& aes,
                                       const char * aPropertyName,
                                       const char * anInterfaceName,
                                       mozilla::dom::Exception* aSyntheticException = nullptr);
     virtual ~nsXPCWrappedJSClass();
 
     nsXPCWrappedJSClass() = delete;
     nsXPCWrappedJSClass(JSContext* cx, REFNSIID aIID,
-                        nsIInterfaceInfo* aInfo);
+                        const nsXPTInterfaceInfo* aInfo);
 
     bool IsReflectable(uint16_t i) const
         {return (bool)(mDescriptors[i/32] & (1 << (i%32)));}
     void SetReflectable(uint16_t i, bool b)
         {if (b) mDescriptors[i/32] |= (1 << (i%32));
          else mDescriptors[i/32] &= ~(1 << (i%32));}
 
     bool GetArraySizeFromParam(JSContext* cx,
@@ -1822,17 +1820,17 @@ private:
     static void CleanupPointerTypeObject(const nsXPTType& type,
                                          void** pp);
 
     void CleanupOutparams(JSContext* cx, uint16_t methodIndex, const nsXPTMethodInfo* info,
                           nsXPTCMiniVariant* nativeParams, bool inOutOnly, uint8_t n) const;
 
 private:
     XPCJSRuntime* mRuntime;
-    nsCOMPtr<nsIInterfaceInfo> mInfo;
+    const nsXPTInterfaceInfo* mInfo;
     char* mName;
     nsIID mIID;
     uint32_t* mDescriptors;
 };
 
 /*************************/
 // nsXPCWrappedJS is a wrapper for a single JSObject for use from native code.
 // nsXPCWrappedJS objects are chained together to represent the various
@@ -2185,25 +2183,25 @@ public:
 
     // we manually delegate these to nsJSID
     NS_DECL_NSIJSID
 
     // we implement the rest...
     NS_DECL_NSIJSIID
     NS_DECL_NSIXPCSCRIPTABLE
 
-    static already_AddRefed<nsJSIID> NewID(nsIInterfaceInfo* aInfo);
-
-    explicit nsJSIID(nsIInterfaceInfo* aInfo);
+    static already_AddRefed<nsJSIID> NewID(const nsXPTInterfaceInfo* aInfo);
+
+    explicit nsJSIID(const nsXPTInterfaceInfo* aInfo);
     nsJSIID() = delete;
 
 private:
     virtual ~nsJSIID();
 
-    nsCOMPtr<nsIInterfaceInfo> mInfo;
+    const nsXPTInterfaceInfo* mInfo;
 };
 
 // nsJSCID
 
 class nsJSCID : public nsIJSCID, public nsIXPCScriptable
 {
 public:
     NS_DECL_ISUPPORTS
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -237,34 +237,16 @@ nsThreadManagerGetSingleton(nsISupports*
     return NS_ERROR_NO_AGGREGATION;
   }
 
   return nsThreadManager::get().QueryInterface(aIID, aInstancePtr);
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
 
-static nsresult
-nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* aOuter,
-                                       const nsIID& aIID,
-                                       void** aInstancePtr)
-{
-  NS_ASSERTION(aInstancePtr, "null outptr");
-  if (NS_WARN_IF(aOuter)) {
-    return NS_ERROR_NO_AGGREGATION;
-  }
-
-  nsCOMPtr<nsIInterfaceInfoManager> iim(XPTInterfaceInfoManager::GetSingleton());
-  if (!iim) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return iim->QueryInterface(aIID, aInstancePtr);
-}
-
 nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
 bool gXPCOMShuttingDown = false;
 bool gXPCOMThreadsShutDown = false;
 char16_t* gGREBinPath = nullptr;
 
 static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
 static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
 
@@ -663,20 +645,16 @@ NS_InitXPCOM2(nsIServiceManager** aResul
     NS_RELEASE(nsComponentManagerImpl::gComponentManager);
     return rv;
   }
 
   if (aResult) {
     NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager);
   }
 
-  // The iimanager constructor searches and registers XPT files.
-  // (We trigger the singleton's lazy construction here to make that happen.)
-  (void)XPTInterfaceInfoManager::GetSingleton();
-
   // After autoreg, but before we actually instantiate any components,
   // add any services listed in the "xpcom-directory-providers" category
   // to the directory service.
   nsDirectoryService::gService->RegisterCategoryProviders();
 
   // Init SharedThreadPool (which needs the service manager).
   SharedThreadPool::InitStatics();
 
@@ -1003,22 +981,16 @@ ShutdownXPCOM(nsIServiceManager* aServMg
 #if defined(DEBUG) && !defined(ANDROID)
       MOZ_CRASH("NSS_Shutdown failed");
 #else
       NS_WARNING("NSS_Shutdown failed");
 #endif
     }
   }
 
-  // Release our own singletons
-  // Do this _after_ shutting down the component manager, because the
-  // JS component loader will use XPConnect to call nsIModule::canUnload,
-  // and that will spin up the InterfaceInfoManager again -- bad mojo
-  XPTInterfaceInfoManager::FreeInterfaceInfoManager();
-
   // Finally, release the component manager last because it unloads the
   // libraries:
   if (nsComponentManagerImpl::gComponentManager) {
     nsrefcnt cnt;
     NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
     NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
   }
   nsComponentManagerImpl::gComponentManager = nullptr;
--- a/xpcom/ds/nsIVariant.idl
+++ b/xpcom/ds/nsIVariant.idl
@@ -6,19 +6,19 @@
 
 /* The long avoided variant support for xpcom. */
 
 #include "nsISupports.idl"
 
 [scriptable,uuid(4d12e540-83d7-11d5-90ed-0010a4e73d9a)]
 interface nsIDataType : nsISupports
 {
-    // These MUST match the declarations in xpt_struct.h. 
-    // Otherwise the world is likely to explode.   
-                                                   // From xpt_struct.h ...
+    // These MUST match the declarations in xptinfo.h.
+    // Otherwise the world is likely to explode.
+                                                   // From xptinfo.h ...
     const uint16_t VTYPE_INT8                =  0; // TD_INT8              = 0,
     const uint16_t VTYPE_INT16               =  1; // TD_INT16             = 1,
     const uint16_t VTYPE_INT32               =  2; // TD_INT32             = 2,
     const uint16_t VTYPE_INT64               =  3; // TD_INT64             = 3,
     const uint16_t VTYPE_UINT8               =  4; // TD_UINT8             = 4,
     const uint16_t VTYPE_UINT16              =  5; // TD_UINT16            = 5,
     const uint16_t VTYPE_UINT32              =  6; // TD_UINT32            = 6,
     const uint16_t VTYPE_UINT64              =  7; // TD_UINT64            = 7,
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsVariant.h"
 #include "prprf.h"
 #include "prdtoa.h"
 #include <math.h>
 #include "nsCycleCollectionParticipant.h"
-#include "xpt_struct.h"
+#include "xptinfo.h"
 #include "nsReadableUtils.h"
 #include "nsMemory.h"
 #include "nsString.h"
 #include "nsCRTGlue.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Printf.h"
 
 /***************************************************************************/
@@ -1640,17 +1640,17 @@ nsDiscriminatedUnion::Traverse(nsCycleCo
 // members...
 
 nsVariantBase::nsVariantBase()
   : mWritable(true)
 {
 #ifdef DEBUG
   {
     // Assert that the nsIDataType consts match the values #defined in
-    // xpt_struct.h. Bad things happen somewhere if they don't.
+    // xptinfo.h. Bad things happen somewhere if they don't.
     struct THE_TYPES
     {
       uint16_t a;
       uint16_t b;
     };
     static const THE_TYPES array[] = {
       {nsIDataType::VTYPE_INT8              , TD_INT8             },
       {nsIDataType::VTYPE_INT16             , TD_INT16            },
--- a/xpcom/reflect/xptcall/genstubs.pl
+++ b/xpcom/reflect/xptcall/genstubs.pl
@@ -11,19 +11,18 @@
 #
 # if "$entry_count" is ever changed and the .inc files regenerated then
 # the following issues need to be addressed:
 #
 # 1) The current Linux ARM code has a limitation of only having 256-3 stubs,
 #    as a result of the limitations of immediate values in ARM assembly.
 #
 # This number is verified by the IDL parser in xpcom/idl-parser/xpidl.py, as
-# well as in xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp, to
-# prevent generating interfaces or loading xpt files that would cause the
-# stubs to run off the entries.
+# well as in xpcom/reflect/xptinfo/xptinfo.cpp, to prevent generating interfaces
+# or loading xpt files that would cause the stubs to run off the entries.
 # If you change this number, please update that location.
 
 # 3 entries are already 'used' by the 3 methods of nsISupports.
 # 3+247+5=255 This should get us in under the Linux ARM limitation
 $entry_count    = 247;
 $sentinel_count = 5;
 
 $decl_name = "xptcstubsdecl.inc";
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_arm_netbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_arm_netbsd.cpp
@@ -9,17 +9,17 @@
 
 nsresult ATTRIBUTE_USED
 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
 {
 #define PARAM_BUFFER_COUNT     16
 
     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
     nsXPTCMiniVariant* dispatchParams = nullptr;
-    nsIInterfaceInfo* iface_info = nullptr;
+    const nsXPTInterfaceInfo* iface_info = nullptr;
     const nsXPTMethodInfo* info;
     uint8_t paramCount;
     uint8_t i;
     nsresult result = NS_ERROR_FAILURE;
 
     NS_ASSERTION(self,"no self");
 
     self->GetInterfaceInfo(&iface_info);
@@ -68,18 +68,16 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         default:
             NS_ERROR("bad type");
             break;
         }
     }
 
     result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);
 
-    NS_RELEASE(iface_info);
-
     if(dispatchParams != paramBuffer)
         delete [] dispatchParams;
 
     return result;
 }
 
 /*
  * These stubs move just move the values passed in registers onto the stack,
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_netbsd_m68k.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_netbsd_m68k.cpp
@@ -14,17 +14,17 @@
 extern "C" {
     static nsresult ATTRIBUTE_USED
     PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
     {
 #define PARAM_BUFFER_COUNT     16
 
         nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
         nsXPTCMiniVariant* dispatchParams = nullptr;
-        nsIInterfaceInfo* iface_info = nullptr;
+        const nsXPTInterfaceInfo* iface_info = nullptr;
         const nsXPTMethodInfo* info;
         uint8_t paramCount;
         uint8_t i;
         nsresult result = NS_ERROR_FAILURE;
 
         NS_ASSERTION(self,"no self");
 
         self->GetInterfaceInfo(&iface_info);
@@ -77,18 +77,16 @@ extern "C" {
             default:
                 NS_ERROR("bad type");
                 break;
             }
         }
 
         result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);
 
-        NS_RELEASE(iface_info);
-
         if(dispatchParams != paramBuffer)
             delete [] dispatchParams;
 
         return result;
     }
 }
 
 #define STUB_ENTRY(n)							\
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_netbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc_netbsd.cpp
@@ -31,17 +31,17 @@ extern "C" nsresult ATTRIBUTE_USED
 PrepareAndDispatch(nsXPTCStubBase* self,
                    uint32_t methodIndex,
                    uint32_t* args,
                    uint32_t *gprData,
                    double *fprData)
 {
     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
     nsXPTCMiniVariant* dispatchParams = nullptr;
-    nsIInterfaceInfo* iface_info = nullptr;
+    const nsXPTInterfaceInfo* iface_info = nullptr;
     const nsXPTMethodInfo* info;
     uint32_t paramCount;
     uint32_t i;
     nsresult result = NS_ERROR_FAILURE;
 
     NS_ASSERTION(self,"no self");
 
     self->GetInterfaceInfo(&iface_info);
@@ -144,18 +144,16 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         default:
             NS_ERROR("bad type");
             break;
         }
     }
 
     result = self->CallMethod((uint16_t) methodIndex, info, dispatchParams);
 
-    NS_RELEASE(iface_info);
-
     if (dispatchParams != paramBuffer)
         delete [] dispatchParams;
 
     return result;
 }
 
 // Load r11 with the constant 'n' and branch to SharedStub().
 //
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_netbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_netbsd.cpp
@@ -18,17 +18,17 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         uint32_t lo;
     } DU;               // have to move 64 bit entities as 32 bit halves since
                         // stack slots are not guaranteed 16 byte aligned
 
 #define PARAM_BUFFER_COUNT     16
 
     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
     nsXPTCMiniVariant* dispatchParams = nullptr;
-    nsIInterfaceInfo* iface_info = nullptr;
+    const nsXPTInterfaceInfo* iface_info = nullptr;
     const nsXPTMethodInfo* info;
     uint8_t paramCount;
     uint8_t i;
     nsresult result = NS_ERROR_FAILURE;
 
     NS_ASSERTION(self,"no self");
 
     self->GetInterfaceInfo(&iface_info);
@@ -83,18 +83,16 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         default:
             NS_ERROR("bad type");
             break;
         }
     }
 
     result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);
 
-    NS_RELEASE(iface_info);
-
     if(dispatchParams != paramBuffer)
         delete [] dispatchParams;
 
     return result;
 }
 
 extern "C" nsresult SharedStub(int, int*);
 
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_openbsd.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_openbsd.cpp
@@ -18,17 +18,17 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         uint32_t lo;
     } DU;               // have to move 64 bit entities as 32 bit halves since
                         // stack slots are not guaranteed 16 byte aligned
 
 #define PARAM_BUFFER_COUNT     16
 
     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
     nsXPTCMiniVariant* dispatchParams = nullptr;
-    nsIInterfaceInfo* iface_info = nullptr;
+    const nsXPTInterfaceInfo* iface_info = nullptr;
     const nsXPTMethodInfo* info;
     uint8_t paramCount;
     uint8_t i;
     nsresult result = NS_ERROR_FAILURE;
 
     NS_ASSERTION(self,"no self");
 
     self->GetInterfaceInfo(&iface_info);
@@ -86,18 +86,16 @@ PrepareAndDispatch(nsXPTCStubBase* self,
         default:
             NS_ERROR("bad type");
             break;
         }
     }
 
     result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);
 
-    NS_RELEASE(iface_info);
-
     if(dispatchParams != paramBuffer)
         delete [] dispatchParams;
 
     return result;
 }
 
 extern "C" nsresult SharedStub(int, int*);
 
--- a/xpcom/reflect/xptcall/porting.html
+++ b/xpcom/reflect/xptcall/porting.html
@@ -93,17 +93,17 @@ public:
     // Include generated vtbl stub declarations.
     // These are virtual and *also* implemented by this class..
 #include "xptcstubsdecl.inc"
 
     // The following methods must be provided by inheritor of this class.
 
     // return a refcounted pointer to the InterfaceInfo for this object
     // NOTE: on some platforms this MUST not fail or we crash!
-    NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0;
+    NS_IMETHOD GetInterfaceInfo(const nsXPTInterfaceInfo** info) = 0;
 
     // call this method and return result
     NS_IMETHOD CallMethod(uint16_t methodIndex,
                           const nsXPTMethodInfo* info,
                           nsXPTCMiniVariant* params) = 0;
 };
 </pre>
 
--- a/xpcom/reflect/xptcall/xptcall.cpp
+++ b/xpcom/reflect/xptcall/xptcall.cpp
@@ -37,33 +37,20 @@ nsXPTCStubBase::Release()
 
 EXPORT_XPCOM_API(nsresult)
 NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
                   nsISomeInterface* *aResult)
 {
     if (NS_WARN_IF(!aOuter) || NS_WARN_IF(!aResult))
         return NS_ERROR_INVALID_ARG;
 
-    XPTInterfaceInfoManager *iim =
-        XPTInterfaceInfoManager::GetSingleton();
-    if (NS_WARN_IF(!iim))
-        return NS_ERROR_NOT_INITIALIZED;
-
-    xptiInterfaceEntry *iie = iim->GetInterfaceEntryForIID(&aIID);
-    if (!iie || !iie->EnsureResolved() || iie->GetBuiltinClassFlag())
+    const nsXPTInterfaceInfo* iie = nsXPTInterfaceInfo::ByIID(aIID);
+    if (!iie || !iie->EnsureResolved() || iie->IsBuiltinClass())
         return NS_ERROR_FAILURE;
 
-    if (iie->GetHasNotXPCOMFlag()) {
-#ifdef DEBUG
-        nsPrintfCString msg("XPTCall will not implement interface %s because of [notxpcom] members.", iie->GetTheName());
-        NS_WARNING(msg.get());
-#endif
-        return NS_ERROR_FAILURE;
-    }
-
     *aResult = new nsXPTCStubBase(aOuter, iie);
     return NS_OK;
 }
 
 EXPORT_XPCOM_API(void)
 NS_DestroyXPTCallStub(nsISomeInterface* aStub)
 {
     nsXPTCStubBase* stub = static_cast<nsXPTCStubBase*>(aStub);
--- a/xpcom/reflect/xptcall/xptcprivate.h
+++ b/xpcom/reflect/xptcall/xptcprivate.h
@@ -39,21 +39,21 @@ public:
 
 class nsXPTCStubBase final : public nsIXPTCStubBase
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
 
 #include "xptcstubsdef.inc"
 
-    nsXPTCStubBase(nsIXPTCProxy* aOuter, xptiInterfaceEntry *aEntry)
+    nsXPTCStubBase(nsIXPTCProxy* aOuter, const nsXPTInterfaceInfo *aEntry)
         : mOuter(aOuter), mEntry(aEntry) {}
 
-    nsIXPTCProxy*          mOuter;
-    xptiInterfaceEntry*    mEntry;
+    nsIXPTCProxy*             mOuter;
+    const nsXPTInterfaceInfo* mEntry;
 
     ~nsXPTCStubBase() {}
 };
 
 #undef STUB_ENTRY
 #undef SENTINEL_ENTRY
 
 #if defined(__clang__) || defined(__GNUC__)