mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 738868 - Switch JSObject2JSObjectMap to new HashTable; r=mrbkap
This commit is contained in:
parent
196698e430
commit
f39a8777a1
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -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___ */
|
||||
|
Loading…
Reference in New Issue
Block a user