Bug 1438688, part 1 - Add methods for accessing arrays in xpt_struct.h. r=njn
☠☠ backed out by 70400746eb53 ☠ ☠
authorAndrew McCreight <continuation@gmail.com>
Wed, 28 Feb 2018 10:07:45 -0800
changeset 411393 08b1a5f904e447b46dd1f93551f01f8f10c87239
parent 411392 05b85c67123d3bdfb4a6c5186b05083e468e44c7
child 411394 186f916dcc7aabfea7981702c47c666338fcf869
push id101643
push userdluca@mozilla.com
push dateTue, 03 Apr 2018 04:25:27 +0000
treeherdermozilla-inbound@ac667545d8aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1438688
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 1438688, part 1 - Add methods for accessing arrays in xpt_struct.h. r=njn This lets us hide later changes to how these arrays are stored. There should be no behavioral change. Some methods in xpt_struct.h are declared inline at the end of the header due to the order that classes are declared in the header. MozReview-Commit-ID: KAxUKn3sDOD
xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/xptinfo.h
xpcom/typelib/xpt/xpt_struct.h
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
@@ -24,24 +24,24 @@ xptiInterfaceEntry::Create(const XPTInte
         return nullptr;
     }
     return new (place) xptiInterfaceEntry(aEntry, aTypelib);
 }
 
 xptiInterfaceEntry::xptiInterfaceEntry(const XPTInterfaceDirectoryEntry* aEntry,
                                        xptiTypelibGuts* aTypelib)
     : mIID(aEntry->mIID)
-    , mDescriptor(aEntry->mInterfaceDescriptor)
+    , mDescriptor(aEntry->InterfaceDescriptor())
     , mTypelib(aTypelib)
     , mParent(nullptr)
     , mInfo(nullptr)
     , mMethodBaseIndex(0)
     , mConstantBaseIndex(0)
     , mFlags(0)
-    , mName(aEntry->mName)
+    , mName(aEntry->Name())
 {
     SetResolvedState(PARTIALLY_RESOLVED);
     SetScriptableFlag(mDescriptor->IsScriptable());
     SetBuiltinClassFlag(mDescriptor->IsBuiltinClass());
     SetMainProcessScriptableOnlyFlag(mDescriptor->IsMainProcessScriptableOnly());
 }
 
 bool
@@ -80,17 +80,17 @@ xptiInterfaceEntry::ResolveLocked()
         }
 
         mParent = parent;
         if (parent->GetHasNotXPCOMFlag()) {
             SetHasNotXPCOMFlag();
         } else {
             for (uint16_t idx = 0; idx < mDescriptor->mNumMethods; ++idx) {
                 const nsXPTMethodInfo* method = static_cast<const nsXPTMethodInfo*>(
-                    mDescriptor->mMethodDescriptors + idx);
+                    &mDescriptor->Method(idx));
                 if (method->IsNotXPCOM()) {
                     SetHasNotXPCOMFlag();
                     break;
                 }
             }
         }
 
 
@@ -184,32 +184,32 @@ xptiInterfaceEntry::GetMethodInfo(uint16
     {
         NS_ERROR("bad param");
         *info = nullptr;
         return NS_ERROR_INVALID_ARG;
     }
 
     // else...
     *info = static_cast<const nsXPTMethodInfo*>
-        (&mDescriptor->mMethodDescriptors[index - mMethodBaseIndex]);
+        (&mDescriptor->Method(index - mMethodBaseIndex));
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16_t *index,
                                          const nsXPTMethodInfo** result)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
     // This is a slow algorithm, but this is not expected to be called much.
     for(uint16_t i = 0; i < mDescriptor->mNumMethods; ++i)
     {
         const nsXPTMethodInfo* info;
-        info = static_cast<const nsXPTMethodInfo*>(&mDescriptor->mMethodDescriptors[i]);
+        info = static_cast<const nsXPTMethodInfo*>(&mDescriptor->Method(i));
         if (PL_strcmp(methodName, info->GetName()) == 0) {
             *index = i + mMethodBaseIndex;
             *result = info;
             return NS_OK;
         }
     }
 
     if(mParent)
@@ -234,17 +234,17 @@ xptiInterfaceEntry::GetConstant(uint16_t
 
     if(index >= mConstantBaseIndex +
                 mDescriptor->mNumConstants)
     {
         NS_PRECONDITION(0, "bad param");
         return NS_ERROR_INVALID_ARG;
     }
 
-    const auto& c = mDescriptor->mConstDescriptors[index - mConstantBaseIndex];
+    const auto& c = mDescriptor->Const(index - mConstantBaseIndex);
     AutoJSContext cx;
     JS::Rooted<JS::Value> v(cx);
     v.setUndefined();
 
     switch (c.mType.mPrefix.mFlags) {
       case nsXPTType::T_I16:
       {
         v.setInt32(c.mValue.i16);
@@ -267,17 +267,17 @@ xptiInterfaceEntry::GetConstant(uint16_t
       }
       default:
       {
         MOZ_ASSERT(false, "Invalid constant type found in interface");
       }
     }
 
     constant.set(v);
-    *name = ToNewCString(nsDependentCString(c.mName));
+    *name = ToNewCString(nsDependentCString(c.Name()));
 
     return NS_OK;
 }
 
 // this is a private helper
 
 nsresult
 xptiInterfaceEntry::GetInterfaceIndexForParam(uint16_t methodIndex,
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
@@ -129,26 +129,26 @@ XPTInterfaceInfoManager::RegisterXPTHead
         VerifyAndAddEntryIfNew(aHeader->mInterfaceDirectory + k, k, typelib);
 }
 
 void
 XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface,
                                                 uint16_t idx,
                                                 xptiTypelibGuts* typelib)
 {
-    if (!iface->mInterfaceDescriptor)
+    if (!iface->InterfaceDescriptor())
         return;
 
     // The number of maximum methods is not arbitrary. It is the same value as
     // in xpcom/reflect/xptcall/genstubs.pl; do not change this value
     // without changing that one or you WILL see problems.
-    if (iface->mInterfaceDescriptor->mNumMethods > 250 &&
-            !iface->mInterfaceDescriptor->IsBuiltinClass()) {
+    if (iface->InterfaceDescriptor()->mNumMethods > 250 &&
+            !iface->InterfaceDescriptor()->IsBuiltinClass()) {
         NS_ASSERTION(0, "Too many methods to handle for the stub, cannot load");
-        fprintf(stderr, "ignoring too large interface: %s\n", iface->mName);
+        fprintf(stderr, "ignoring too large interface: %s\n", iface->Name());
         return;
     }
 
     mWorkingSet.mTableReentrantMonitor.AssertCurrentThreadIn();
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->mIID);
     if (entry) {
         // XXX validate this info to find possible inconsistencies
         return;
--- a/xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
+++ b/xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
@@ -47,17 +47,17 @@ xptiTypelibGuts::GetEntryAt(uint16_t i)
     const XPTInterfaceDirectoryEntry* iface = mHeader->mInterfaceDirectory + i;
 
     XPTInterfaceInfoManager::xptiWorkingSet& set =
         XPTInterfaceInfoManager::GetSingleton()->mWorkingSet;
 
     {
         ReentrantMonitorAutoEnter monitor(set.mTableReentrantMonitor);
         if (iface->mIID.Equals(zeroIID))
-            r = set.mNameTable.Get(iface->mName);
+            r = set.mNameTable.Get(iface->Name());
         else
             r = set.mIIDTable.Get(iface->mIID);
     }
 
     if (r)
         SetEntryAt(i, r);
 
     return r;
@@ -66,10 +66,10 @@ xptiTypelibGuts::GetEntryAt(uint16_t i)
 const char*
 xptiTypelibGuts::GetEntryNameAt(uint16_t i)
 {
     NS_ASSERTION(mHeader, "bad state");
     NS_ASSERTION(i < GetEntryCount(), "bad index");
 
     const XPTInterfaceDirectoryEntry* iface = mHeader->mInterfaceDirectory + i;
 
-    return iface->mName;
+    return iface->Name();
 }
--- a/xpcom/reflect/xptinfo/xptinfo.h
+++ b/xpcom/reflect/xptinfo/xptinfo.h
@@ -189,21 +189,21 @@ public:
         {*(XPTMethodDescriptor*)this = desc;}
 
     bool IsGetter() const { return !!(mFlags & kGetterMask); }
     bool IsSetter() const { return !!(mFlags & kSetterMask); }
     bool IsNotXPCOM() const { return !!(mFlags & kNotXPCOMMask); }
     bool IsHidden() const { return !!(mFlags & kHiddenMask); }
     bool WantsOptArgc() const { return !!(mFlags & kOptArgcMask); }
     bool WantsContext() const { return !!(mFlags & kContextMask); }
-    const char* GetName() const { return mName; }
+    const char* GetName() const { return Name(); }
     uint8_t GetParamCount() const { return mNumArgs; }
     const nsXPTParamInfo GetParam(uint8_t idx) const {
         MOZ_ASSERT(idx < GetParamCount(), "bad arg");
-        return mParams[idx];
+        return Param(idx);
     }
 
 private:
     static const uint8_t kGetterMask =   0x80;
     static const uint8_t kSetterMask =   0x40;
     static const uint8_t kNotXPCOMMask = 0x20;
     static const uint8_t kHiddenMask =   0x08;
     static const uint8_t kOptArgcMask =  0x04;
--- a/xpcom/typelib/xpt/xpt_struct.h
+++ b/xpcom/typelib/xpt/xpt_struct.h
@@ -67,16 +67,19 @@ struct XPTHeader {
 
 /*
  * A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
  * the byte offset identified by the mInterfaceDirectory field in the file
  * header.  The array is used to quickly locate an interface description
  * using its IID.  No interface should appear more than once in the array.
  */
 struct XPTInterfaceDirectoryEntry {
+  inline const XPTInterfaceDescriptor* InterfaceDescriptor() const;
+  inline const char* Name() const;
+
   nsID mIID;
   const char* mName;
 
   // This field exists in the on-disk format. But it isn't used so we don't
   // allocate space for it in memory.
   //const char* mNameSpace;
 
   const XPTInterfaceDescriptor* mInterfaceDescriptor;
@@ -92,16 +95,19 @@ struct XPTInterfaceDescriptor {
   static const uint8_t kBuiltinClassMask =              0x20;
   static const uint8_t kMainProcessScriptableOnlyMask = 0x10;
 
   bool IsScriptable() const { return !!(mFlags & kScriptableMask); }
   bool IsFunction() const { return !!(mFlags & kFunctionMask); }
   bool IsBuiltinClass() const { return !!(mFlags & kBuiltinClassMask); }
   bool IsMainProcessScriptableOnly() const { return !!(mFlags & kMainProcessScriptableOnlyMask); }
 
+  inline const XPTMethodDescriptor& Method(size_t aIndex) const;
+  inline const XPTConstDescriptor& Const(size_t aIndex) const;
+
   /*
    * This field ordering minimizes the size of this struct.
    * The fields are serialized on disk in a different order.
    * See DoInterfaceDescriptor().
    */
   const XPTMethodDescriptor* mMethodDescriptors;
   const XPTConstDescriptor* mConstDescriptors;
   const XPTTypeDescriptor* mAdditionalTypes;
@@ -240,16 +246,20 @@ struct XPTTypeDescriptor {
 union XPTConstValue {
   int16_t i16;
   uint16_t ui16;
   int32_t i32;
   uint32_t ui32;
 }; /* varies according to type */
 
 struct XPTConstDescriptor {
+  const char* Name() const {
+    return mName;
+  }
+
   const char* mName;
   XPTTypeDescriptor mType;
   union XPTConstValue mValue;
 };
 
 /*
  * A ParamDescriptor is a variable-size record used to describe either a
  * single argument to a method or a method's result.
@@ -259,16 +269,43 @@ struct XPTParamDescriptor {
   XPTTypeDescriptor mType;
 };
 
 /*
  * A MethodDescriptor is a variable-size record used to describe a single
  * interface method.
  */
 struct XPTMethodDescriptor {
+  const char* Name() const {
+    return mName;
+  }
+  const XPTParamDescriptor& Param(uint8_t aIndex) const {
+    return mParams[aIndex];
+  }
+
   const char* mName;
   const XPTParamDescriptor* mParams;
   //XPTParamDescriptor mResult; // Present on disk, omitted here.
   uint8_t mFlags;
   uint8_t mNumArgs;
 };
 
+const char*
+XPTInterfaceDirectoryEntry::Name() const {
+  return mName;
+}
+
+const XPTInterfaceDescriptor*
+XPTInterfaceDirectoryEntry::InterfaceDescriptor() const {
+  return mInterfaceDescriptor;
+}
+
+const XPTMethodDescriptor&
+XPTInterfaceDescriptor::Method(size_t aIndex) const {
+  return mMethodDescriptors[aIndex];
+}
+
+const XPTConstDescriptor&
+XPTInterfaceDescriptor::Const(size_t aIndex) const {
+  return mConstDescriptors[aIndex];
+}
+
 #endif /* xpt_struct_h */