Bug 1288909, part 4 - Use a strong reference to the set in ClassInfo2NativeSetMap. r=billm
authorAndrew McCreight <continuation@gmail.com>
Tue, 06 Sep 2016 12:58:27 -0700
changeset 314428 5dc379423bd6bcce41dfed874a5ffc127cde1de4
parent 314427 862e46017481f434ade36618444f7eb94ac13558
child 314429 2db6d45d00706912f8671d485f3bc3fcd64e0ac3
push id20574
push usercbook@mozilla.com
push dateTue, 20 Sep 2016 10:05:16 +0000
treeherderfx-team@14705f779a46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1288909
milestone52.0a1
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
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
--- 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);
     }