Bug 1288909, part 4 - Use a strong reference to the set in ClassInfo2NativeSetMap. r=billm
Entries should end up getting cleared out from this table before the
value dies, so let's just make the reference strong so that any
mistakes will result in leaks and not use-after-frees.
Using smart pointer classes with PLDHashtable is a little
questionable, and I don't want to convert this one hash table to
nsTHashtable, so I use manual addref and release.
MozReview-Commit-ID: Kfg9veS6r11
--- a/js/xpconnect/src/XPCMaps.cpp
+++ b/js/xpconnect/src/XPCMaps.cpp
@@ -197,24 +197,51 @@ IID2NativeInterfaceMap::SizeOfIncludingT
}
return n;
}
/***************************************************************************/
// implement ClassInfo2NativeSetMap...
// static
+bool ClassInfo2NativeSetMap::Entry::Match(const PLDHashEntryHdr* aEntry,
+ const void* aKey)
+{
+ return static_cast<const Entry*>(aEntry)->key == aKey;
+}
+
+// static
+void ClassInfo2NativeSetMap::Entry::Clear(PLDHashTable* aTable,
+ PLDHashEntryHdr* aEntry)
+{
+ auto entry = static_cast<Entry*>(aEntry);
+ NS_RELEASE(entry->value);
+
+ entry->key = nullptr;
+ entry->value = nullptr;
+}
+
+const PLDHashTableOps ClassInfo2NativeSetMap::Entry::sOps =
+{
+ PLDHashTable::HashVoidPtrKeyStub,
+ Match,
+ PLDHashTable::MoveEntryStub,
+ Clear,
+ nullptr
+};
+
+// static
ClassInfo2NativeSetMap*
ClassInfo2NativeSetMap::newMap(int length)
{
return new ClassInfo2NativeSetMap(length);
}
ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length)
- : mTable(PLDHashTable::StubOps(), sizeof(Entry), length)
+ : mTable(&ClassInfo2NativeSetMap::Entry::sOps, sizeof(Entry), length)
{
}
size_t
ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
{
size_t n = mallocSizeOf(this);
n += mTable.ShallowSizeOfExcludingThis(mallocSizeOf);
--- a/js/xpconnect/src/XPCMaps.h
+++ b/js/xpconnect/src/XPCMaps.h
@@ -273,17 +273,22 @@ private:
/*************************/
class ClassInfo2NativeSetMap
{
public:
struct Entry : public PLDHashEntryHdr
{
nsIClassInfo* key;
- XPCNativeSet* value;
+ XPCNativeSet* value; // strong reference
+ static const PLDHashTableOps sOps;
+
+ private:
+ static bool Match(const PLDHashEntryHdr* aEntry, const void* aKey);
+ static void Clear(PLDHashTable* aTable, PLDHashEntryHdr* aEntry);
};
static ClassInfo2NativeSetMap* newMap(int length);
inline XPCNativeSet* Find(nsIClassInfo* info)
{
auto entry = static_cast<Entry*>(mTable.Search(info));
return entry ? entry->value : nullptr;
@@ -293,17 +298,17 @@ public:
{
NS_PRECONDITION(info,"bad param");
auto entry = static_cast<Entry*>(mTable.Add(info, mozilla::fallible));
if (!entry)
return nullptr;
if (entry->key)
return entry->value;
entry->key = info;
- entry->value = set;
+ NS_ADDREF(entry->value = set);
return set;
}
inline void Remove(nsIClassInfo* info)
{
NS_PRECONDITION(info,"bad param");
mTable.Remove(info);
}