Bug 972591, part 3 - Convert nsXBLDocumentInfo::mBindingTable to nsClassHashtable. r=froydnj,bz
authorAndrew McCreight <continuation@gmail.com>
Thu, 20 Feb 2014 12:55:40 -0800
changeset 169756 df1edcb49a35e1e7b44136952a7e2635983f3cd5
parent 169755 0f213da041376943d90fc69b62665535a317727e
child 169757 91dd2cdb110c5df1a2be72d8fd67a8f698729166
push id26266
push usercbook@mozilla.com
push dateFri, 21 Feb 2014 12:03:53 +0000
treeherdermozilla-central@2d935f3e9587 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, bz
bugs972591
milestone30.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 972591, part 3 - Convert nsXBLDocumentInfo::mBindingTable to nsClassHashtable. r=froydnj,bz
dom/xbl/nsXBLDocumentInfo.cpp
dom/xbl/nsXBLDocumentInfo.h
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -218,101 +218,97 @@ nsXBLDocGlobalObject::GetPrincipal()
   if (!document)
     return nullptr;
 
   return document->NodePrincipal();
 }
 
 /* Implementation file */
 
-static bool
-TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+TraverseProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Traverse(*cb);
-  return kHashEnumerateNext;
+  aProto->Traverse(*cb);
+  return PL_DHASH_NEXT;
 }
 
-static bool
-UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+UnlinkProtoJSObjects(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->UnlinkJSObjects();
-  return kHashEnumerateNext;
+  aProto->UnlinkJSObjects();
+  return PL_DHASH_NEXT;
 }
 
 struct ProtoTracer
 {
   const TraceCallbacks &mCallbacks;
   void *mClosure;
 };
 
-static bool
-TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+TraceProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
   ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
-  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Trace(closure->mCallbacks, closure->mClosure);
-  return kHashEnumerateNext;
+  aProto->Trace(closure->mCallbacks, closure->mClosure);
+  return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nullptr);
+    tmp->mBindingTable->EnumerateRead(UnlinkProtoJSObjects, nullptr);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mDocument &&
       nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
+    tmp->mBindingTable->EnumerateRead(TraverseProtos, &cb);
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
     ProtoTracer closure = { aCallbacks, aClosure };
-    tmp->mBindingTable->Enumerate(TraceProtos, &closure);
+    tmp->mBindingTable->EnumerateRead(TraceProtos, &closure);
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 static void
 UnmarkXBLJSObject(void* aP, const char* aName, void* aClosure)
 {
   JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP));
 }
 
-static bool
-UnmarkProtos(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+UnmarkProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* proto = static_cast<nsXBLPrototypeBinding*>(aData);
-  proto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
-  return kHashEnumerateNext;
+  aProto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
+  return PL_DHASH_NEXT;
 }
 
 void
 nsXBLDocumentInfo::MarkInCCGeneration(uint32_t aGeneration)
 {
   if (mDocument) {
     mDocument->MarkUncollectableForCCGeneration(aGeneration);
   }
   // Unmark any JS we hold
   if (mBindingTable) {
-    mBindingTable->Enumerate(UnmarkProtos, nullptr);
+    mBindingTable->EnumerateRead(UnmarkProtos, nullptr);
   }
   if (mGlobalObject) {
     mGlobalObject->UnmarkCompilationGlobal();
   }
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@@ -321,17 +317,16 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLDocumentInfo)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXBLDocumentInfo)
 
 nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
   : mDocument(aDocument),
     mScriptAccess(true),
     mIsChrome(false),
-    mBindingTable(nullptr),
     mFirstBinding(nullptr)
 {
   nsIURI* uri = aDocument->GetDocumentURI();
   if (IsChromeURI(uri)) {
     // Cache whether or not this chrome XBL can execute scripts.
     nsCOMPtr<nsIXULChromeRegistry> reg =
       mozilla::services::GetXULChromeRegistryService();
     if (reg) {
@@ -362,84 +357,63 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsI
 }
 
 nsXBLDocumentInfo::~nsXBLDocumentInfo()
 {
   /* destructor code */
   if (mGlobalObject) {
     mGlobalObject->ClearGlobalObjectOwner(); // just in case
   }
-  if (mBindingTable) {
-    delete mBindingTable;
-    mBindingTable = nullptr;
-    mozilla::DropJSObjects(this);
-  }
+  mozilla::DropJSObjects(this);
 }
 
 nsXBLPrototypeBinding*
 nsXBLDocumentInfo::GetPrototypeBinding(const nsACString& aRef)
 {
   if (!mBindingTable)
     return nullptr;
 
   if (aRef.IsEmpty()) {
     // Return our first binding
     return mFirstBinding;
   }
 
-  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-  nsCStringKey key(flat.get());
-  return static_cast<nsXBLPrototypeBinding*>(mBindingTable->Get(&key));
-}
-
-static bool
-DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure)
-{
-  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding*>(aData);
-  delete binding;
-  return true;
+  return mBindingTable->Get(aRef);
 }
 
 nsresult
 nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
 {
   if (!mBindingTable) {
-    mBindingTable = new nsObjectHashtable(nullptr, nullptr, DeletePrototypeBinding, nullptr);
-
+    mBindingTable = new nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>();
     mozilla::HoldJSObjects(this);
   }
 
-  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-  nsCStringKey key(flat.get());
-  NS_ENSURE_STATE(!mBindingTable->Get(&key));
-  mBindingTable->Put(&key, aBinding);
+  NS_ENSURE_STATE(!mBindingTable->Get(aRef));
+  mBindingTable->Put(aRef, aBinding);
 
   return NS_OK;
 }
 
 void
 nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef)
 {
   if (mBindingTable) {
-    // Use a flat string to avoid making a copy.
-    const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
-    nsCStringKey key(flat);
-    mBindingTable->Remove(&key);
+    mBindingTable->Remove(aRef);
   }
 }
 
 // Callback to enumerate over the bindings from this document and write them
 // out to the cache.
-bool
-WriteBinding(nsHashKey *aKey, void *aData, void* aClosure)
+static PLDHashOperator
+WriteBinding(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding *>(aData);
-  binding->Write((nsIObjectOutputStream*)aClosure);
+  aProto->Write((nsIObjectOutputStream*)aClosure);
 
-  return kHashEnumerateNext;
+  return PL_DHASH_NEXT;
 }
 
 // static
 nsresult
 nsXBLDocumentInfo::ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocInfo)
 {
   *aDocInfo = nullptr;
 
@@ -525,18 +499,19 @@ nsXBLDocumentInfo::WritePrototypeBinding
   rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(stream),
                                            getter_AddRefs(storageStream),
                                            true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = stream->Write32(XBLBinding_Serialize_Version);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (mBindingTable)
-    mBindingTable->Enumerate(WriteBinding, stream);
+  if (mBindingTable) {
+    mBindingTable->EnumerateRead(WriteBinding, stream);
+  }
 
   // write a end marker at the end
   rv = stream->Write8(XBLBinding_Serialize_NoMoreBindings);
   NS_ENSURE_SUCCESS(rv, rv);
 
   stream->Close();
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -549,28 +524,29 @@ nsXBLDocumentInfo::WritePrototypeBinding
 }
 
 void
 nsXBLDocumentInfo::SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding)
 {
   mFirstBinding = aBinding;
 }
 
-bool FlushScopedSkinSheets(nsHashKey* aKey, void* aData, void* aClosure)
+static PLDHashOperator
+FlushScopedSkinSheets(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
 {
-  nsXBLPrototypeBinding* proto = (nsXBLPrototypeBinding*)aData;
-  proto->FlushSkinSheets();
-  return true;
+  aProto->FlushSkinSheets();
+  return PL_DHASH_NEXT;
 }
 
 void
 nsXBLDocumentInfo::FlushSkinStylesheets()
 {
-  if (mBindingTable)
-    mBindingTable->Enumerate(FlushScopedSkinSheets);
+  if (mBindingTable) {
+    mBindingTable->EnumerateRead(FlushScopedSkinSheets, nullptr);
+  }
 }
 
 JSObject*
 nsXBLDocumentInfo::GetCompilationGlobal()
 {
   EnsureGlobalObject();
   return mGlobalObject->GetCompilationGlobal();
 }
--- a/dom/xbl/nsXBLDocumentInfo.h
+++ b/dom/xbl/nsXBLDocumentInfo.h
@@ -8,17 +8,16 @@
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsXBLPrototypeBinding;
-class nsObjectHashtable;
 class nsXBLDocGlobalObject;
 
 class nsXBLDocumentInfo : public nsSupportsWeakReference
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsXBLDocumentInfo(nsIDocument* aDocument);
@@ -36,17 +35,17 @@ public:
                                nsXBLPrototypeBinding* aBinding);
 
   // This removes the binding without deleting it
   void RemovePrototypeBinding(const nsACString& aRef);
 
   nsresult WritePrototypeBindings();
 
   void SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding);
-  
+
   void FlushSkinStylesheets();
 
   bool IsChrome() { return mIsChrome; }
 
   JSObject* GetCompilationGlobal();
 
   void MarkInCCGeneration(uint32_t aGeneration);
 
@@ -55,17 +54,18 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsXBLDocumentInfo)
 
 private:
   void EnsureGlobalObject();
   nsCOMPtr<nsIDocument> mDocument;
   bool mScriptAccess;
   bool mIsChrome;
   // the binding table owns each nsXBLPrototypeBinding
-  nsObjectHashtable* mBindingTable;
+  nsAutoPtr<nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>> mBindingTable;
+
   // non-owning pointer to the first binding in the table
   nsXBLPrototypeBinding* mFirstBinding;
 
   nsRefPtr<nsXBLDocGlobalObject> mGlobalObject;
 };
 
 #ifdef DEBUG
 void AssertInCompilationScope();