Bug 1344974 - Part 2: Make the non-virtual helpers for principal equality/subsumption checks inline; r=bholley
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 06 Mar 2017 23:04:50 -0500
changeset 396771 a84b225957b499c03ec78ca0ed6cb8ff9ddd03aa
parent 396770 2c8caf7ff9f2397ed57734c211d1a21711357db3
child 396772 a9c886b3517f9c5e2728539c6426df45b80b077b
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1344974
milestone54.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 1344974 - Part 2: Make the non-virtual helpers for principal equality/subsumption checks inline; r=bholley
caps/BasePrincipal.cpp
caps/BasePrincipal.h
dom/base/ChromeUtils.cpp
dom/base/ChromeUtils.h
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -330,151 +330,56 @@ BasePrincipal::Subsumes(nsIPrincipal* aO
   if (Kind() == eCodebasePrincipal &&
       mOriginSuffix != Cast(aOther)->mOriginSuffix) {
     return false;
   }
 
   return SubsumesInternal(aOther, aConsideration);
 }
 
-bool
-BasePrincipal::FastEquals(nsIPrincipal* aOther)
-{
-  auto other = Cast(aOther);
-  if (Kind() != other->Kind()) {
-    // Principals of different kinds can't be equal.
-    return false;
-  }
-
-  // Two principals are considered to be equal if their origins are the same.
-  // If the two principals are codebase principals, their origin attributes
-  // (aka the origin suffix) must also match.
-  // If the two principals are null principals, they're only equal if they're
-  // the same object.
-  if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
-    return this == other;
-  }
-
-  if (mOriginNoSuffix) {
-    if (Kind() == eCodebasePrincipal) {
-      return mOriginNoSuffix == other->mOriginNoSuffix &&
-             mOriginSuffix == other->mOriginSuffix;
-    }
-
-    MOZ_ASSERT(Kind() == eExpandedPrincipal);
-    return mOriginNoSuffix == other->mOriginNoSuffix;
-  }
-
-  // If mOriginNoSuffix is null on one of our principals, we must fall back
-  // to the slow path.
-  return Subsumes(aOther, DontConsiderDocumentDomain) &&
-         other->Subsumes(this, DontConsiderDocumentDomain);
-}
-
 NS_IMETHODIMP
 BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
 
   *aResult = FastEquals(aOther);
 
   return NS_OK;
 }
 
-bool
-BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
-{
-  // If neither of the principals have document.domain set, we use the fast path
-  // in Equals().  Otherwise, we fall back to the slow path below.
-  auto other = Cast(aOther);
-  if (!mDomainSet && !other->mDomainSet) {
-    return FastEquals(aOther);
-  }
-
-  return Subsumes(aOther, ConsiderDocumentDomain) &&
-         other->Subsumes(this, ConsiderDocumentDomain);
-}
-
 NS_IMETHODIMP
 BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
 
   *aResult = FastEqualsConsideringDomain(aOther);
 
   return NS_OK;
 }
 
-bool
-BasePrincipal::FastSubsumes(nsIPrincipal* aOther)
-{
-  // If two principals are equal, then they both subsume each other.
-  // We deal with two special cases first:
-  // Null principals only subsume each other if they are equal, and are only
-  // equal if they're the same object.
-  // Also, if mOriginNoSuffix is null, FastEquals falls back to the slow path
-  // using Subsumes, so we don't want to use it in that case to avoid an
-  // infinite recursion.
-  auto other = Cast(aOther);
-  if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
-    return this == other;
-  }
-  if (mOriginNoSuffix && FastEquals(aOther)) {
-    return true;
-  }
-
-  // Otherwise, fall back to the slow path.
-  return Subsumes(aOther, DontConsiderDocumentDomain);
-}
-
 NS_IMETHODIMP
 BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
 
   *aResult = FastSubsumes(aOther);
 
   return NS_OK;
 }
 
-bool
-BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
-{
-  // If neither of the principals have document.domain set, we hand off to
-  // FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
-  // back to the slow path below.
-  if (!mDomainSet && !Cast(aOther)->mDomainSet) {
-    return FastSubsumes(aOther);
-  }
-
-  return Subsumes(aOther, ConsiderDocumentDomain);
-}
-
 NS_IMETHODIMP
 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
 
   *aResult = FastSubsumesConsideringDomain(aOther);
 
   return NS_OK;
 }
 
-bool
-BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
-{
-  if (Kind() == eCodebasePrincipal &&
-      !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
-            OriginAttributesRef(), aOther->OriginAttributesRef())) {
-    return false;
-  }
-
- return SubsumesInternal(aOther, ConsiderDocumentDomain);
-}
-
 NS_IMETHODIMP
 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal *aOther,
                                                     bool *aResult)
 {
   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
 
   *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
 
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_BasePrincipal_h
 #define mozilla_BasePrincipal_h
 
 #include "nsJSPrincipals.h"
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/ChromeUtilsBinding.h"
 #include "nsIScriptSecurityManager.h"
 
 class nsIContentSecurityPolicy;
 class nsIObjectOutputStream;
 class nsIObjectInputStream;
 class nsIURI;
 
@@ -245,37 +246,37 @@ public:
 
   virtual bool IsCodebasePrincipal() const { return false; };
 
   static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
   static already_AddRefed<BasePrincipal>
   CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
   static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(const nsACString& aOrigin);
 
-  const OriginAttributes& OriginAttributesRef() override { return mOriginAttributes; }
+  const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
   uint32_t AppId() const { return mOriginAttributes.mAppId; }
   uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
   uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
   bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }
 
   PrincipalKind Kind() const { return mKind; }
 
   already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
 
   // Helper to check whether this principal is associated with an addon that
   // allows unprivileged code to load aURI.  aExplicit == true will prevent
   // use of all_urls permission, requiring the domain in its permissions.
   bool AddonAllowsLoad(nsIURI* aURI, bool aExplicit = false);
 
   // Call these to avoid the cost of virtual dispatch.
-  bool FastEquals(nsIPrincipal* aOther);
-  bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
-  bool FastSubsumes(nsIPrincipal* aOther);
-  bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
-  bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
+  inline bool FastEquals(nsIPrincipal* aOther);
+  inline bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
+  inline bool FastSubsumes(nsIPrincipal* aOther);
+  inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
+  inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
 
 protected:
   virtual ~BasePrincipal();
 
   virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
   // Note that this does not check OriginAttributes. Callers that depend on
   // those must call Subsumes instead.
   virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
@@ -295,11 +296,106 @@ protected:
   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
   nsCOMPtr<nsIAtom> mOriginNoSuffix;
   nsCOMPtr<nsIAtom> mOriginSuffix;
   OriginAttributes mOriginAttributes;
   PrincipalKind mKind;
   bool mDomainSet;
 };
 
+inline bool
+BasePrincipal::FastEquals(nsIPrincipal* aOther)
+{
+  auto other = Cast(aOther);
+  if (Kind() != other->Kind()) {
+    // Principals of different kinds can't be equal.
+    return false;
+  }
+
+  // Two principals are considered to be equal if their origins are the same.
+  // If the two principals are codebase principals, their origin attributes
+  // (aka the origin suffix) must also match.
+  // If the two principals are null principals, they're only equal if they're
+  // the same object.
+  if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
+    return this == other;
+  }
+
+  if (mOriginNoSuffix) {
+    if (Kind() == eCodebasePrincipal) {
+      return mOriginNoSuffix == other->mOriginNoSuffix &&
+             mOriginSuffix == other->mOriginSuffix;
+    }
+
+    MOZ_ASSERT(Kind() == eExpandedPrincipal);
+    return mOriginNoSuffix == other->mOriginNoSuffix;
+  }
+
+  // If mOriginNoSuffix is null on one of our principals, we must fall back
+  // to the slow path.
+  return Subsumes(aOther, DontConsiderDocumentDomain) &&
+         other->Subsumes(this, DontConsiderDocumentDomain);
+}
+
+inline bool
+BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
+{
+  // If neither of the principals have document.domain set, we use the fast path
+  // in Equals().  Otherwise, we fall back to the slow path below.
+  auto other = Cast(aOther);
+  if (!mDomainSet && !other->mDomainSet) {
+    return FastEquals(aOther);
+  }
+
+  return Subsumes(aOther, ConsiderDocumentDomain) &&
+         other->Subsumes(this, ConsiderDocumentDomain);
+}
+
+inline bool
+BasePrincipal::FastSubsumes(nsIPrincipal* aOther)
+{
+  // If two principals are equal, then they both subsume each other.
+  // We deal with two special cases first:
+  // Null principals only subsume each other if they are equal, and are only
+  // equal if they're the same object.
+  // Also, if mOriginNoSuffix is null, FastEquals falls back to the slow path
+  // using Subsumes, so we don't want to use it in that case to avoid an
+  // infinite recursion.
+  auto other = Cast(aOther);
+  if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
+    return this == other;
+  }
+  if (mOriginNoSuffix && FastEquals(aOther)) {
+    return true;
+  }
+
+  // Otherwise, fall back to the slow path.
+  return Subsumes(aOther, DontConsiderDocumentDomain);
+}
+
+inline bool
+BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
+{
+  // If neither of the principals have document.domain set, we hand off to
+  // FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
+  // back to the slow path below.
+  if (!mDomainSet && !Cast(aOther)->mDomainSet) {
+    return FastSubsumes(aOther);
+  }
+
+  return Subsumes(aOther, ConsiderDocumentDomain);
+}
+
+inline bool
+BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
+{
+  if (Kind() == eCodebasePrincipal &&
+      !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
+            mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
+    return false;
+  }
+
+ return SubsumesInternal(aOther, ConsiderDocumentDomain);
+}
+
 } // namespace mozilla
 
 #endif /* mozilla_BasePrincipal_h */
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -183,20 +183,10 @@ ChromeUtils::IsOriginAttributesEqual(con
                                      const dom::OriginAttributesDictionary& aB)
 {
   return aA.mAppId == aB.mAppId &&
          aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
          aA.mUserContextId == aB.mUserContextId &&
          aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
 }
 
-/* static */ bool
-ChromeUtils::IsOriginAttributesEqualIgnoringFPD(const dom::OriginAttributesDictionary& aA,
-                                                const dom::OriginAttributesDictionary& aB)
-{
-  return aA.mAppId == aB.mAppId &&
-         aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
-         aA.mUserContextId == aB.mUserContextId &&
-         aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/ChromeUtils.h
+++ b/dom/base/ChromeUtils.h
@@ -89,15 +89,21 @@ public:
                           const dom::OriginAttributesDictionary& aB);
 
   static bool
   IsOriginAttributesEqual(const dom::OriginAttributesDictionary& aA,
                           const dom::OriginAttributesDictionary& aB);
 
   static bool
   IsOriginAttributesEqualIgnoringFPD(const dom::OriginAttributesDictionary& aA,
-                                     const dom::OriginAttributesDictionary& aB);
+                                     const dom::OriginAttributesDictionary& aB)
+  {
+    return aA.mAppId == aB.mAppId &&
+           aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
+           aA.mUserContextId == aB.mUserContextId &&
+           aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
+  }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_ChromeUtils__