Bug 1225298 - Use GCHashSet for InnerViewTable, r=terrence
authorSteve Fink <sfink@mozilla.com>
Thu, 19 Nov 2015 11:20:53 -0800
changeset 309220 0de6760991317cf984ac966622775a5ff74c7e41
parent 309219 d38ecc7f68f3fd401e75321d66ac601eccebf127
child 309221 d07d5bec1748035cda8e9ff83310909eb7678a14
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1225298
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1225298 - Use GCHashSet for InnerViewTable, r=terrence
js/src/jscompartment.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -662,23 +662,23 @@ JSCompartment::traceRoots(JSTracer* trc,
 }
 
 void
 JSCompartment::sweepAfterMinorGC()
 {
     globalWriteBarriered = false;
 
     if (innerViews.needsSweepAfterMinorGC())
-        innerViews.sweepAfterMinorGC(runtimeFromMainThread());
+        innerViews.sweepAfterMinorGC();
 }
 
 void
 JSCompartment::sweepInnerViews()
 {
-    innerViews.sweep(runtimeFromAnyThread());
+    innerViews.sweep();
 }
 
 void
 JSCompartment::sweepSavedStacks()
 {
     savedStacks_.sweep(runtimeFromAnyThread());
 }
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1109,17 +1109,17 @@ void
 InnerViewTable::removeViews(ArrayBufferObject* buffer)
 {
     Map::Ptr p = map.lookup(buffer);
     MOZ_ASSERT(p);
 
     map.remove(p);
 }
 
-bool
+/* static */ bool
 InnerViewTable::sweepEntry(JSObject** pkey, ViewVector& views)
 {
     if (IsAboutToBeFinalizedUnbarriered(pkey))
         return true;
 
     MOZ_ASSERT(!views.empty());
     for (size_t i = 0; i < views.length(); i++) {
         if (IsAboutToBeFinalizedUnbarriered(&views[i])) {
@@ -1127,31 +1127,24 @@ InnerViewTable::sweepEntry(JSObject** pk
             views.popBack();
         }
     }
 
     return views.empty();
 }
 
 void
-InnerViewTable::sweep(JSRuntime* rt)
+InnerViewTable::sweep()
 {
     MOZ_ASSERT(nurseryKeys.empty());
-
-    if (!map.initialized())
-        return;
-
-    for (Map::Enum e(map); !e.empty(); e.popFront()) {
-        if (sweepEntry(&e.front().mutableKey(), e.front().value()))
-            e.removeFront();
-    }
+    map.sweep();
 }
 
 void
-InnerViewTable::sweepAfterMinorGC(JSRuntime* rt)
+InnerViewTable::sweepAfterMinorGC()
 {
     MOZ_ASSERT(needsSweepAfterMinorGC());
 
     if (nurseryKeysValid) {
         for (size_t i = 0; i < nurseryKeys.length(); i++) {
             JSObject* buffer = MaybeForwarded(nurseryKeys[i]);
             Map::Ptr p = map.lookup(buffer);
             if (!p)
@@ -1159,17 +1152,17 @@ InnerViewTable::sweepAfterMinorGC(JSRunt
 
             if (sweepEntry(&p->mutableKey(), p->value()))
                 map.remove(buffer);
         }
         nurseryKeys.clear();
     } else {
         // Do the required sweeping by looking at every map entry.
         nurseryKeys.clear();
-        sweep(rt);
+        sweep();
 
         nurseryKeysValid = true;
     }
 }
 
 size_t
 InnerViewTable::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
 {
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ArrayBufferObject_h
 #define vm_ArrayBufferObject_h
 
 #include "jsobj.h"
 
 #include "builtin/TypedObjectConstants.h"
+#include "js/GCHashTable.h"
 #include "vm/Runtime.h"
 #include "vm/SharedMem.h"
 
 typedef struct JSProperty JSProperty;
 
 namespace js {
 
 class ArrayBufferViewObject;
@@ -496,59 +497,66 @@ template<> inline bool TypeIsUnsigned<ui
 class InnerViewTable
 {
   public:
     typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
 
     friend class ArrayBufferObject;
 
   private:
+    struct MapGCPolicy {
+        static bool needsSweep(JSObject** key, ViewVector* value) {
+            return InnerViewTable::sweepEntry(key, *value);
+        }
+    };
+
     // This key is a raw pointer and not a ReadBarriered because the post-
     // barrier would hold nursery-allocated entries live unconditionally. It is
     // a very common pattern in low-level and performance-oriented JavaScript
     // to create hundreds or thousands of very short lived temporary views on a
     // larger buffer; having to tenured all of these would be a catastrophic
     // performance regression. Thus, it is vital that nursery pointers in this
     // map not be held live. Special support is required in the minor GC,
     // implemented in sweepAfterMinorGC.
-    typedef HashMap<JSObject*,
-                    ViewVector,
-                    MovableCellHasher<JSObject*>,
-                    SystemAllocPolicy> Map;
+    typedef GCHashMap<JSObject*,
+                      ViewVector,
+                      MovableCellHasher<JSObject*>,
+                      SystemAllocPolicy,
+                      MapGCPolicy> Map;
 
     // For all objects sharing their storage with some other view, this maps
     // the object to the list of such views. All entries in this map are weak.
     Map map;
 
     // List of keys from innerViews where either the source or at least one
     // target is in the nursery. The raw pointer to a JSObject is allowed here
     // because this vector is cleared after every minor collection. Users in
     // sweepAfterMinorCollection must be careful to use MaybeForwarded before
     // touching these pointers.
     Vector<JSObject*, 0, SystemAllocPolicy> nurseryKeys;
 
     // Whether nurseryKeys is a complete list.
     bool nurseryKeysValid;
 
     // Sweep an entry during GC, returning whether the entry should be removed.
-    bool sweepEntry(JSObject** pkey, ViewVector& views);
+    static bool sweepEntry(JSObject** pkey, ViewVector& views);
 
     bool addView(JSContext* cx, ArrayBufferObject* obj, ArrayBufferViewObject* view);
     ViewVector* maybeViewsUnbarriered(ArrayBufferObject* obj);
     void removeViews(ArrayBufferObject* obj);
 
   public:
     InnerViewTable()
       : nurseryKeysValid(true)
     {}
 
     // Remove references to dead objects in the table and update table entries
     // to reflect moved objects.
-    void sweep(JSRuntime* rt);
-    void sweepAfterMinorGC(JSRuntime* rt);
+    void sweep();
+    void sweepAfterMinorGC();
 
     bool needsSweepAfterMinorGC() {
         return !nurseryKeys.empty() || !nurseryKeysValid;
     }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
 };