Bug 1609054 - Check whether arenas have been reallocated in a different zone in the incremental marking verifier r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 15 Jan 2020 10:47:16 +0000
changeset 510334 dbd45b7bb4495f9d0cdb232ce959adfc2f895c34
parent 510333 f4bba00d59cef29deb745e608689e58d45b80394
child 510335 79bce5e9d341d605c6a0c7cc4547be812cefba4a
push id37020
push userccoroiu@mozilla.com
push dateWed, 15 Jan 2020 21:36:21 +0000
treeherdermozilla-central@c35bb210b8ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1609054
milestone74.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 1609054 - Check whether arenas have been reallocated in a different zone in the incremental marking verifier r=sfink Differential Revision: https://phabricator.services.mozilla.com/D59908
js/src/gc/Verifier.cpp
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -472,18 +472,24 @@ class js::gc::MarkingValidator {
   void nonIncrementalMark(AutoGCSession& session);
   void validate();
 
  private:
   GCRuntime* gc;
   bool initialized;
 
   using MarkBits = UniquePtr<uint8_t>;
+
+  struct ArenaInfo {
+    Zone* zone;
+    MarkBits markBits;
+  };
+
   using MarkBitsMap =
-      HashMap<Arena*, MarkBits, DefaultHasher<Arena*>, SystemAllocPolicy>;
+      HashMap<Arena*, ArenaInfo, DefaultHasher<Arena*>, SystemAllocPolicy>;
   MarkBitsMap map;
 };
 
 js::gc::MarkingValidator::MarkingValidator(GCRuntime* gc)
     : gc(gc), initialized(false) {}
 
 void js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) {
   /*
@@ -511,17 +517,19 @@ void js::gc::MarkingValidator::nonIncrem
         Arena* arena = aiter.get();
         size_t thingCount = arena->getThingsPerArena();
         MarkBits markBits(js_pod_malloc<uint8_t>(thingCount));
         if (!markBits) {
           return;
         }
 
         mozilla::PodCopy(markBits.get(), arena->markBits(), thingCount);
-        if (!map.putNew(arena, std::move(markBits))) {
+
+        ArenaInfo info = {zone, std::move(markBits)};
+        if (!map.putNew(arena, std::move(info))) {
           return;
         }
       }
     }
   }
 
   /*
    * Temporarily clear the weakmaps' mark flags for the compartments we are
@@ -630,17 +638,17 @@ void js::gc::MarkingValidator::nonIncrem
   /* Take a copy of the non-incremental mark state and restore the original. */
   const size_t maxThingsPerArena = ArenaSize / MinCellSize;
   uint8_t temp[maxThingsPerArena];
   for (GCZonesIter zone(gc); !zone.done(); zone.next()) {
     for (auto thingKind : AllAllocKinds()) {
       for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) {
         Arena* arena = aiter.get();
         size_t thingCount = arena->getThingsPerArena();
-        uint8_t* savedMarkBits = map.lookup(arena)->value().get();
+        uint8_t* savedMarkBits = map.lookup(arena)->value().markBits.get();
         mozilla::PodCopy(temp, arena->markBits(), thingCount);
         mozilla::PodCopy(arena->markBits(), savedMarkBits, thingCount);
         mozilla::PodCopy(savedMarkBits, temp, thingCount);
       }
     }
   }
 
   for (GCZonesIter zone(gc); !zone.done(); zone.next()) {
@@ -680,22 +688,27 @@ void js::gc::MarkingValidator::validate(
 
   gc->waitBackgroundSweepEnd();
 
   for (SweepGroupZonesIter zone(gc); !zone.done(); zone.next()) {
     for (auto thingKind : AllAllocKinds()) {
       for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) {
         Arena* arena = aiter.get();
 
+        /*
+         * It's possible for the arena to have been freshly allocated since we
+         * did the non-incremental mark, or to have been freed and reallocated
+         * in a new zone.
+         */
         MarkBitsMap::Ptr ptr = map.lookup(arena);
-        if (!ptr) {
-          continue; /* Allocated after we did the non-incremental mark. */
+        if (!ptr || ptr->value().zone != zone) {
+          continue;
         }
 
-        uint8_t* markBits = ptr->value().get();
+        uint8_t* markBits = ptr->value().markBits.get();
         uint8_t* incMarkBits = arena->markBits();
 
         size_t thingCount = arena->getThingsPerArena();
 
         for (size_t i = 0; i < thingCount; i++) {
           /*
            * If a non-incremental GC wouldn't have collected a cell, then an
            * incremental GC won't collect it.