Bug 1001159 (part 6) - Used ArenaCellIterImpl in Arena::finalize(). r=billm.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 29 Apr 2014 18:03:28 -0700
changeset 181543 5a056bb6be0cec7653834cee6ec0f50e4935cde3
parent 181542 be78a818fbd829f11b173a37a66d0c8e6ec6dd40
child 181544 2dabaf1087cd5e93987ccf962b04cf156e433c74
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersbillm
bugs1001159
milestone32.0a1
Bug 1001159 (part 6) - Used ArenaCellIterImpl in Arena::finalize(). r=billm.
js/src/jsgc.cpp
js/src/jsgcinlines.h
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -438,52 +438,40 @@ Arena::finalize(FreeOp *fop, AllocKind t
 
     JS_ASSERT(aheader.allocated());
     JS_ASSERT(thingKind == aheader.getAllocKind());
     JS_ASSERT(thingSize == aheader.getThingSize());
     JS_ASSERT(!aheader.hasDelayedMarking);
     JS_ASSERT(!aheader.markOverflow);
     JS_ASSERT(!aheader.allocatedDuringIncremental);
 
-    uintptr_t thing = thingsStart(thingKind);
-    uintptr_t firstThingOrSuccessorOfLastMarkedThing = thing;
+    uintptr_t firstThing = thingsStart(thingKind);
+    uintptr_t firstThingOrSuccessorOfLastMarkedThing = firstThing;
     uintptr_t lastByte = thingsEnd() - 1;
 
-    FreeSpan nextFree(aheader.getFirstFreeSpan());
-    nextFree.checkSpan();
-
     FreeSpan newListHead;
     FreeSpan *newListTail = &newListHead;
     size_t nmarked = 0;
-    for (;; thing += thingSize) {
-        JS_ASSERT(thing <= lastByte + 1);
-        if (thing == nextFree.first) {
-            JS_ASSERT(nextFree.last <= lastByte);
-            if (nextFree.last == lastByte)
-                break;
-            JS_ASSERT(Arena::isAligned(nextFree.last, thingSize));
-            thing = nextFree.last;
-            nextFree = *nextFree.nextSpan();
-            nextFree.checkSpan();
+
+    for (ArenaCellIterUnderFinalize i(&aheader); !i.done(); i.next()) {
+        T *t = i.get<T>();
+        if (t->isMarked()) {
+            uintptr_t thing = reinterpret_cast<uintptr_t>(t);
+            if (thing != firstThingOrSuccessorOfLastMarkedThing) {
+                // We just finished passing over one or more free things,
+                // so record a new FreeSpan.
+                newListTail->first = firstThingOrSuccessorOfLastMarkedThing;
+                newListTail->last = thing - thingSize;
+                newListTail = newListTail->nextSpanUnchecked(thingSize);
+            }
+            firstThingOrSuccessorOfLastMarkedThing = thing + thingSize;
+            nmarked++;
         } else {
-            T *t = reinterpret_cast<T *>(thing);
-            if (t->isMarked()) {
-                if (thing != firstThingOrSuccessorOfLastMarkedThing) {
-                    // We just finished passing over one or more free things,
-                    // so record a new FreeSpan.
-                    newListTail->first = firstThingOrSuccessorOfLastMarkedThing;
-                    newListTail->last = thing - thingSize;
-                    newListTail = newListTail->nextSpanUnchecked(thingSize);
-                }
-                firstThingOrSuccessorOfLastMarkedThing = thing + thingSize;
-                nmarked++;
-            } else {
-                t->finalize(fop);
-                JS_POISON(t, JS_SWEPT_TENURED_PATTERN, thingSize);
-            }
+            t->finalize(fop);
+            JS_POISON(t, JS_SWEPT_TENURED_PATTERN, thingSize);
         }
     }
 
     // Complete the last FreeSpan.
     newListTail->first = firstThingOrSuccessorOfLastMarkedThing;
     newListTail->last = lastByte;
 
     if (nmarked == 0) {
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -154,17 +154,17 @@ class ArenaIter
             aheader = remainingHeader;
             remainingHeader = nullptr;
         }
     }
 };
 
 class ArenaCellIterImpl
 {
-    // These three are set in init().
+    // These three are set in initUnsynchronized().
     size_t firstThingOffset;
     size_t thingSize;
 #ifdef DEBUG
     bool isInited;
 #endif
 
     // These three are set in reset() (which is called by init()).
     FreeSpan span;
@@ -183,27 +183,34 @@ class ArenaCellIterImpl
                 thing = limit;
             }
         }
     }
 
   public:
     ArenaCellIterImpl() {}
 
-    void init(ArenaHeader *aheader) {
+    void initUnsynchronized(ArenaHeader *aheader) {
         AllocKind kind = aheader->getAllocKind();
 #ifdef DEBUG
-        JS_ASSERT(aheader->zone->allocator.arenas.isSynchronizedFreeList(kind));
         isInited = true;
 #endif
         firstThingOffset = Arena::firstThingOffset(kind);
         thingSize = Arena::thingSize(kind);
         reset(aheader);
     }
 
+    void init(ArenaHeader *aheader) {
+#ifdef DEBUG
+        AllocKind kind = aheader->getAllocKind();
+        JS_ASSERT(aheader->zone->allocator.arenas.isSynchronizedFreeList(kind));
+#endif
+        initUnsynchronized(aheader);
+    }
+
     // Use this to move from an Arena of a particular kind to another Arena of
     // the same kind.
     void reset(ArenaHeader *aheader) {
         JS_ASSERT(isInited);
         span = aheader->getFirstFreeSpan();
         uintptr_t arenaAddr = aheader->arenaAddress();
         thing = arenaAddr + firstThingOffset;
         limit = arenaAddr + ArenaSize;
@@ -236,16 +243,24 @@ class ArenaCellIterUnderGC : public Aren
 {
   public:
     ArenaCellIterUnderGC(ArenaHeader *aheader) {
         JS_ASSERT(aheader->zone->runtimeFromAnyThread()->isHeapBusy());
         init(aheader);
     }
 };
 
+class ArenaCellIterUnderFinalize : public ArenaCellIterImpl
+{
+  public:
+    ArenaCellIterUnderFinalize(ArenaHeader *aheader) {
+        initUnsynchronized(aheader);
+    }
+};
+
 class ZoneCellIterImpl
 {
     ArenaIter arenaIter;
     ArenaCellIterImpl cellIter;
 
   protected:
     ZoneCellIterImpl() {}