Bug 972591, part 3 - Convert nsXBLDocumentInfo::mBindingTable to nsClassHashtable. r=froydnj,bz

This commit is contained in:
Andrew McCreight 2014-02-19 13:27:14 -08:00
parent 5c8e9c47db
commit f2a5f8893b
2 changed files with 44 additions and 68 deletions

View File

@ -223,22 +223,20 @@ nsXBLDocGlobalObject::GetPrincipal()
/* Implementation file */ /* Implementation file */
static bool static PLDHashOperator
TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure) TraverseProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
{ {
nsCycleCollectionTraversalCallback *cb = nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(aClosure); static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData); aProto->Traverse(*cb);
proto->Traverse(*cb); return PL_DHASH_NEXT;
return kHashEnumerateNext;
} }
static bool static PLDHashOperator
UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure) UnlinkProtoJSObjects(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
{ {
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData); aProto->UnlinkJSObjects();
proto->UnlinkJSObjects(); return PL_DHASH_NEXT;
return kHashEnumerateNext;
} }
struct ProtoTracer struct ProtoTracer
@ -247,20 +245,19 @@ struct ProtoTracer
void *mClosure; void *mClosure;
}; };
static bool static PLDHashOperator
TraceProtos(nsHashKey *aKey, void *aData, void* aClosure) TraceProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
{ {
ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure); ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData); aProto->Trace(closure->mCallbacks, closure->mClosure);
proto->Trace(closure->mCallbacks, closure->mClosure); return PL_DHASH_NEXT;
return kHashEnumerateNext;
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) { if (tmp->mBindingTable) {
tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nullptr); tmp->mBindingTable->EnumerateRead(UnlinkProtoJSObjects, nullptr);
} }
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject) NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject)
@ -273,7 +270,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
if (tmp->mBindingTable) { if (tmp->mBindingTable) {
tmp->mBindingTable->Enumerate(TraverseProtos, &cb); tmp->mBindingTable->EnumerateRead(TraverseProtos, &cb);
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
@ -281,7 +278,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) { if (tmp->mBindingTable) {
ProtoTracer closure = { aCallbacks, aClosure }; ProtoTracer closure = { aCallbacks, aClosure };
tmp->mBindingTable->Enumerate(TraceProtos, &closure); tmp->mBindingTable->EnumerateRead(TraceProtos, &closure);
} }
NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRACE_END
@ -291,12 +288,11 @@ UnmarkXBLJSObject(void* aP, const char* aName, void* aClosure)
JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP)); JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP));
} }
static bool static PLDHashOperator
UnmarkProtos(nsHashKey* aKey, void* aData, void* aClosure) UnmarkProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
{ {
nsXBLPrototypeBinding* proto = static_cast<nsXBLPrototypeBinding*>(aData); aProto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
proto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr); return PL_DHASH_NEXT;
return kHashEnumerateNext;
} }
void void
@ -307,7 +303,7 @@ nsXBLDocumentInfo::MarkInCCGeneration(uint32_t aGeneration)
} }
// Unmark any JS we hold // Unmark any JS we hold
if (mBindingTable) { if (mBindingTable) {
mBindingTable->Enumerate(UnmarkProtos, nullptr); mBindingTable->EnumerateRead(UnmarkProtos, nullptr);
} }
if (mGlobalObject) { if (mGlobalObject) {
mGlobalObject->UnmarkCompilationGlobal(); mGlobalObject->UnmarkCompilationGlobal();
@ -326,7 +322,6 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
: mDocument(aDocument), : mDocument(aDocument),
mScriptAccess(true), mScriptAccess(true),
mIsChrome(false), mIsChrome(false),
mBindingTable(nullptr),
mFirstBinding(nullptr) mFirstBinding(nullptr)
{ {
nsIURI* uri = aDocument->GetDocumentURI(); nsIURI* uri = aDocument->GetDocumentURI();
@ -367,11 +362,7 @@ nsXBLDocumentInfo::~nsXBLDocumentInfo()
if (mGlobalObject) { if (mGlobalObject) {
mGlobalObject->ClearGlobalObjectOwner(); // just in case mGlobalObject->ClearGlobalObjectOwner(); // just in case
} }
if (mBindingTable) { mozilla::DropJSObjects(this);
delete mBindingTable;
mBindingTable = nullptr;
mozilla::DropJSObjects(this);
}
} }
nsXBLPrototypeBinding* nsXBLPrototypeBinding*
@ -385,32 +376,19 @@ nsXBLDocumentInfo::GetPrototypeBinding(const nsACString& aRef)
return mFirstBinding; return mFirstBinding;
} }
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef); return mBindingTable->Get(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;
} }
nsresult nsresult
nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding) nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
{ {
if (!mBindingTable) { if (!mBindingTable) {
mBindingTable = new nsObjectHashtable(nullptr, nullptr, DeletePrototypeBinding, nullptr); mBindingTable = new nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>();
mozilla::HoldJSObjects(this); mozilla::HoldJSObjects(this);
} }
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef); NS_ENSURE_STATE(!mBindingTable->Get(aRef));
nsCStringKey key(flat.get()); mBindingTable->Put(aRef, aBinding);
NS_ENSURE_STATE(!mBindingTable->Get(&key));
mBindingTable->Put(&key, aBinding);
return NS_OK; return NS_OK;
} }
@ -419,22 +397,18 @@ void
nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef) nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef)
{ {
if (mBindingTable) { if (mBindingTable) {
// Use a flat string to avoid making a copy. mBindingTable->Remove(aRef);
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat);
mBindingTable->Remove(&key);
} }
} }
// Callback to enumerate over the bindings from this document and write them // Callback to enumerate over the bindings from this document and write them
// out to the cache. // out to the cache.
bool static PLDHashOperator
WriteBinding(nsHashKey *aKey, void *aData, void* aClosure) WriteBinding(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
{ {
nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding *>(aData); aProto->Write((nsIObjectOutputStream*)aClosure);
binding->Write((nsIObjectOutputStream*)aClosure);
return kHashEnumerateNext; return PL_DHASH_NEXT;
} }
// static // static
@ -530,8 +504,9 @@ nsXBLDocumentInfo::WritePrototypeBindings()
rv = stream->Write32(XBLBinding_Serialize_Version); rv = stream->Write32(XBLBinding_Serialize_Version);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (mBindingTable) if (mBindingTable) {
mBindingTable->Enumerate(WriteBinding, stream); mBindingTable->EnumerateRead(WriteBinding, stream);
}
// write a end marker at the end // write a end marker at the end
rv = stream->Write8(XBLBinding_Serialize_NoMoreBindings); rv = stream->Write8(XBLBinding_Serialize_NoMoreBindings);
@ -554,18 +529,19 @@ nsXBLDocumentInfo::SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding)
mFirstBinding = 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; aProto->FlushSkinSheets();
proto->FlushSkinSheets(); return PL_DHASH_NEXT;
return true;
} }
void void
nsXBLDocumentInfo::FlushSkinStylesheets() nsXBLDocumentInfo::FlushSkinStylesheets()
{ {
if (mBindingTable) if (mBindingTable) {
mBindingTable->Enumerate(FlushScopedSkinSheets); mBindingTable->EnumerateRead(FlushScopedSkinSheets, nullptr);
}
} }
JSObject* JSObject*

View File

@ -13,7 +13,6 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
class nsXBLPrototypeBinding; class nsXBLPrototypeBinding;
class nsObjectHashtable;
class nsXBLDocGlobalObject; class nsXBLDocGlobalObject;
class nsXBLDocumentInfo : public nsSupportsWeakReference class nsXBLDocumentInfo : public nsSupportsWeakReference
@ -41,7 +40,7 @@ public:
nsresult WritePrototypeBindings(); nsresult WritePrototypeBindings();
void SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding); void SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding);
void FlushSkinStylesheets(); void FlushSkinStylesheets();
bool IsChrome() { return mIsChrome; } bool IsChrome() { return mIsChrome; }
@ -60,7 +59,8 @@ private:
bool mScriptAccess; bool mScriptAccess;
bool mIsChrome; bool mIsChrome;
// the binding table owns each nsXBLPrototypeBinding // the binding table owns each nsXBLPrototypeBinding
nsObjectHashtable* mBindingTable; nsAutoPtr<nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>> mBindingTable;
// non-owning pointer to the first binding in the table // non-owning pointer to the first binding in the table
nsXBLPrototypeBinding* mFirstBinding; nsXBLPrototypeBinding* mFirstBinding;