Bug 738868 - Switch JSObject2JSObjectMap to new HashTable; r=mrbkap

This commit is contained in:
Terrence Cole 2012-03-27 09:55:55 -07:00
parent 196698e430
commit f39a8777a1
4 changed files with 45 additions and 103 deletions

View File

@ -1864,34 +1864,6 @@ WindowStateHolder::~WindowStateHolder()
NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
struct ReparentWaiverClosure
{
JSContext *mCx;
JSObject *mNewInner;
};
static JSDHashOperator
ReparentWaiverWrappers(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg)
{
ReparentWaiverClosure *closure = static_cast<ReparentWaiverClosure*>(arg);
JSObject *value = static_cast<JSObject2JSObjectMap::Entry *>(hdr)->value;
// We reparent wrappers that have as their parent an inner window whose
// outer has the new inner window as its current inner.
JSObject *parent = JS_GetParent(value);
JSObject *outer = JS_ObjectToOuterObject(closure->mCx, parent);
if (outer) {
JSObject *inner = JS_ObjectToInnerObject(closure->mCx, outer);
if (inner == closure->mNewInner && inner != parent)
JS_SetParent(closure->mCx, value, closure->mNewInner);
} else {
JS_ClearPendingException(closure->mCx);
}
return JS_DHASH_NEXT;
}
nsresult
nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
{
@ -2190,11 +2162,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (priv && priv->waiverWrapperMap) {
NS_ASSERTION(!JS_IsExceptionPending(cx),
"We might overwrite a pending exception!");
ReparentWaiverClosure closure = {
cx,
newInnerWindow->mJSObject
};
priv->waiverWrapperMap->Enumerate(ReparentWaiverWrappers, &closure);
priv->waiverWrapperMap->Reparent(cx, newInnerWindow->mJSObject);
}
}
}

View File

@ -634,18 +634,6 @@ DoDeferredRelease(nsTArray<T> &array)
}
}
static JSDHashOperator
SweepWaiverWrappers(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32_t number, void *arg)
{
JSObject *key = ((JSObject2JSObjectMap::Entry *)hdr)->key;
JSObject *value = ((JSObject2JSObjectMap::Entry *)hdr)->value;
if (JS_IsAboutToBeFinalized(key) || JS_IsAboutToBeFinalized(value))
return JS_DHASH_REMOVE;
return JS_DHASH_NEXT;
}
static PLDHashOperator
SweepExpandos(XPCWrappedNative *wn, JSObject *&expando, void *arg)
{
@ -661,7 +649,7 @@ SweepCompartment(nsCStringHashKey& aKey, JSCompartment *compartment, void *aClos
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
if (priv->waiverWrapperMap)
priv->waiverWrapperMap->Enumerate(SweepWaiverWrappers, nsnull);
priv->waiverWrapperMap->Sweep();
if (priv->expandoMap)
priv->expandoMap->Enumerate(SweepExpandos, nsnull);
return PL_DHASH_NEXT;

View File

@ -830,18 +830,3 @@ WrappedNative2WrapperMap::AddLink(JSObject* wrappedObject, Link* oldLink)
}
/***************************************************************************/
// implement JSObject2JSObjectMap...
struct JSDHashTableOps
JSObject2JSObjectMap::sOps = {
JS_DHashAllocTable,
JS_DHashFreeTable,
JS_DHashVoidPtrKeyStub,
JS_DHashMatchEntryStub,
JS_DHashMoveEntryStub,
JS_DHashClearEntryStub,
JS_DHashFinalizeStub,
nsnull
};
/***************************************************************************/

View File

@ -43,6 +43,8 @@
#ifndef xpcmaps_h___
#define xpcmaps_h___
#include "js/HashTable.h"
// Maps...
// Note that most of the declarations for hash table entries begin with
@ -744,78 +746,77 @@ private:
class JSObject2JSObjectMap
{
static struct JSDHashTableOps sOps;
typedef js::HashMap<JSObject *, JSObject *, js::PointerHasher<JSObject *, 3>,
js::SystemAllocPolicy> Map;
public:
struct Entry : public JSDHashEntryHdr
{
JSObject* key;
JSObject* value;
};
static JSObject2JSObjectMap* newMap(int size)
{
JSObject2JSObjectMap* map = new JSObject2JSObjectMap(size);
if (map && map->mTable)
if (map && map->mTable.initialized())
return map;
delete map;
return nsnull;
}
inline JSObject* Find(JSObject* key)
{
inline JSObject* Find(JSObject* key) {
NS_PRECONDITION(key, "bad param");
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, key, JS_DHASH_LOOKUP);
if (JS_DHASH_ENTRY_IS_FREE(entry))
return nsnull;
return entry->value;
if (Map::Ptr p = mTable.lookup(key))
return p->value;
return nsnull;
}
// Note: If the entry already exists, return the old value.
inline JSObject* Add(JSObject *key, JSObject *value)
{
/* Note: If the entry already exists, return the old value. */
inline JSObject* Add(JSObject *key, JSObject *value) {
NS_PRECONDITION(key,"bad param");
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, key, JS_DHASH_ADD);
if (!entry)
Map::AddPtr p = mTable.lookupForAdd(key);
if (p)
return p->value;
if (!mTable.add(p, key, value))
return nsnull;
if (entry->key)
return entry->value;
entry->key = key;
entry->value = value;
return value;
}
inline void Remove(JSObject* key)
{
inline void Remove(JSObject* key) {
NS_PRECONDITION(key,"bad param");
JS_DHashTableOperate(mTable, key, JS_DHASH_REMOVE);
mTable.remove(key);
}
inline uint32_t Count() {return mTable->entryCount;}
inline uint32_t Count() { return mTable.count(); }
inline uint32_t Enumerate(JSDHashEnumerator f, void *arg)
{
return JS_DHashTableEnumerate(mTable, f, arg);
void Sweep() {
for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
if (JS_IsAboutToBeFinalized(e.front().key) || JS_IsAboutToBeFinalized(e.front().value))
e.removeFront();
}
}
~JSObject2JSObjectMap()
{
if (mTable)
JS_DHashTableDestroy(mTable);
void Reparent(JSContext *aCx, JSObject *aNewInner) {
for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
/*
* We reparent wrappers that have as their parent an inner window
* whose outer has the new inner window as its current inner.
*/
JSObject *parent = JS_GetParent(e.front().value);
JSObject *outer = JS_ObjectToOuterObject(aCx, parent);
if (outer) {
JSObject *inner = JS_ObjectToInnerObject(aCx, outer);
if (inner == aNewInner && inner != parent)
JS_SetParent(aCx, e.front().value, aNewInner);
} else {
JS_ClearPendingException(aCx);
}
}
}
private:
JSObject2JSObjectMap(int size)
{
mTable = JS_NewDHashTable(&sOps, nsnull, sizeof(Entry), size);
JSObject2JSObjectMap() MOZ_DELETE;
JSObject2JSObjectMap(int size) {
mTable.init(size);
}
JSObject2JSObjectMap(); // no implementation
private:
JSDHashTable *mTable;
Map mTable;
};
#endif /* xpcmaps_h___ */