Bug 1204669 - optimize out hashtable lookups caused by extra GetPrototypeBinding call, r=bz,waldo, a=al
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 24 Sep 2015 03:53:31 +0300
changeset 296134 d7c8fdff521011ea9f69626ca8250bc870c0738f
parent 296133 b86c987909e20b8d656424934679c498ce1a005d
child 296135 3ac18b24304e0fc6128eae506f5e63eccac63f56
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, waldo, al
bugs1204669
milestone43.0a2
Bug 1204669 - optimize out hashtable lookups caused by extra GetPrototypeBinding call, r=bz,waldo, a=al
dom/xbl/nsXBLPrototypeBinding.h
dom/xbl/nsXBLService.cpp
mfbt/WeakPtr.h
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -13,16 +13,17 @@
 #include "nsICSSLoaderObserver.h"
 #include "nsInterfaceHashtable.h"
 #include "nsWeakReference.h"
 #include "nsXBLDocumentInfo.h"
 #include "nsXBLProtoImpl.h"
 #include "nsXBLProtoImplMethod.h"
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLPrototypeResources.h"
+#include "mozilla/WeakPtr.h"
 
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
 class nsXBLAttributeEntry;
 class nsXBLBinding;
 class nsXBLProtoImplField;
 
@@ -31,19 +32,22 @@ class CSSStyleSheet;
 } // namespace mozilla
 
 // *********************************************************************/
 // The XBLPrototypeBinding class
 
 // Instances of this class are owned by the nsXBLDocumentInfo object returned
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
-class nsXBLPrototypeBinding final
+class nsXBLPrototypeBinding final :
+  public mozilla::SupportsWeakPtr<nsXBLPrototypeBinding>
 {
 public:
+  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsXBLPrototypeBinding)
+
   nsIContent* GetBindingElement() const { return mBinding; }
   void SetBindingElement(nsIContent* aElement);
 
   nsIURI* BindingURI() const { return mBindingURI; }
   nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; }
   nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
   nsIURI* GetBaseBindingURI() const { return mBaseBindingURI; }
 
@@ -285,17 +289,18 @@ protected:
   nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
 
   // the url of the base binding
   nsCOMPtr<nsIURI> mBaseBindingURI;
 
   nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields,
                                    // the constructor, and the destructor).
 
-  nsXBLPrototypeBinding* mBaseBinding; // Weak.  The docinfo will own our base binding.
+  // Weak.  The docinfo will own our base binding.
+  mozilla::WeakPtr<nsXBLPrototypeBinding> mBaseBinding;
   bool mInheritStyle;
   bool mCheckedBaseProto;
   bool mKeyHandlersRegistered;
   bool mChromeOnlyContent;
   bool mBindToUntrustedContent;
 
   nsAutoPtr<nsXBLPrototypeResources> mResources; // If we have any resources, this will be non-null.
 
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -725,17 +725,18 @@ nsXBLService::GetBinding(nsIContent* aBo
   nsresult rv = LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI,
                                         aOriginPrincipal,
                                         false, getter_AddRefs(docInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!docInfo)
     return NS_ERROR_FAILURE;
 
-  nsXBLPrototypeBinding* protoBinding = docInfo->GetPrototypeBinding(ref);
+  WeakPtr<nsXBLPrototypeBinding> protoBinding =
+    docInfo->GetPrototypeBinding(ref);
 
   if (!protoBinding) {
 #ifdef DEBUG
     nsAutoCString uriSpec;
     aURI->GetSpec(uriSpec);
     nsAutoCString doc;
     boundDocument->GetDocumentURI()->GetSpec(doc);
     nsAutoCString message("Unable to locate an XBL binding for URI ");
@@ -776,17 +777,17 @@ nsXBLService::GetBinding(nsIContent* aBo
     protoBinding->AddResourceListener(aBoundElement);
     return NS_ERROR_FAILURE; // The binding isn't ready yet.
   }
 
   rv = protoBinding->ResolveBaseBinding();
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIURI> baseBindingURI;
-  nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
+  WeakPtr<nsXBLPrototypeBinding> baseProto = protoBinding->GetBasePrototype();
   if (baseProto) {
     baseBindingURI = baseProto->BindingURI();
   }
   else {
     baseBindingURI = protoBinding->GetBaseBindingURI();
     if (baseBindingURI) {
       uint32_t count = aDontExtendURIs.Length();
       for (uint32_t index = 0; index < count; ++index) {
@@ -821,17 +822,16 @@ nsXBLService::GetBinding(nsIContent* aBo
     if (NS_FAILED(rv))
       return rv; // We aren't ready yet.
   }
 
   *aIsReady = true;
 
   if (!aPeekOnly) {
     // Make a new binding
-    protoBinding = docInfo->GetPrototypeBinding(ref);
     NS_ENSURE_STATE(protoBinding);
     nsXBLBinding *newBinding = new nsXBLBinding(protoBinding);
 
     if (baseBinding) {
       if (!baseProto) {
         protoBinding->SetBasePrototype(baseBinding->PrototypeBinding());
       }
        newBinding->SetBaseBinding(baseBinding);
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -167,17 +167,23 @@ public:
 
   WeakPtr(const WeakPtr& aOther)
   {
     *this = aOther;
   }
 
   WeakPtr& operator=(T* aOther)
   {
-    return *this = aOther->SelfReferencingWeakPtr();
+    if (aOther) {
+      *this = aOther->SelfReferencingWeakPtr();
+    } else if (!mRef || mRef->get()) {
+      // Ensure that mRef is dereferenceable in the uninitialized state.
+      mRef = new WeakReference(nullptr);
+    }
+    return *this;
   }
 
   MOZ_IMPLICIT WeakPtr(T* aOther)
   {
     *this = aOther;
   }
 
   // Ensure that mRef is dereferenceable in the uninitialized state.