Bug 1232229 - Instrument setting ArenaHeader::next to catch misuse and fix existing instrumentation. r=terrence
authorEmanuel Hoogeveen <emanuel.hoogeveen@gmail.com>
Tue, 16 Feb 2016 14:36:00 +0100
changeset 284730 e00a022829518b51d16563eba05bc06a5e0a73e8
parent 284729 156d0a87f59649dfdc181ec78de49d922f852f3c
child 284731 4a020e2e4acec77f56e1ccea319765a7e18c74c9
push id30013
push usercbook@mozilla.com
push dateFri, 19 Feb 2016 11:02:40 +0000
treeherdermozilla-central@a87d6d52c1fc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1232229
milestone47.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 1232229 - Instrument setting ArenaHeader::next to catch misuse and fix existing instrumentation. r=terrence
js/src/jsgc.cpp
js/src/jsgc.h
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -918,16 +918,17 @@ GCRuntime::updateOnArenaFree(const Chunk
 {
     ++numArenasFreeCommitted;
 }
 
 void
 Chunk::addArenaToFreeList(JSRuntime* rt, ArenaHeader* aheader)
 {
     MOZ_ASSERT(!aheader->allocated());
+    MOZ_RELEASE_ASSERT(uintptr_t(info.freeArenasHead) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
     aheader->next = info.freeArenasHead;
     info.freeArenasHead = aheader;
     ++info.numArenasFreeCommitted;
     ++info.numArenasFree;
     rt->gc.updateOnArenaFree(info);
 }
 
 void
@@ -2250,16 +2251,17 @@ ArenaList::relocateArenas(ArenaHeader* t
                           gcstats::Statistics& stats)
 {
     check();
 
     while (ArenaHeader* arena = toRelocate) {
         toRelocate = arena->next;
         RelocateArena(arena, sliceBudget);
         // Prepend to list of relocated arenas
+        MOZ_RELEASE_ASSERT(uintptr_t(relocated) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
         arena->next = relocated;
         relocated = arena;
         stats.count(gcstats::STAT_ARENA_RELOCATED);
     }
 
     check();
 
     return relocated;
@@ -2798,16 +2800,18 @@ GCRuntime::updatePointersToRelocatedCell
 void
 GCRuntime::protectAndHoldArenas(ArenaHeader* arenaList)
 {
     for (ArenaHeader* arena = arenaList; arena; ) {
         MOZ_ASSERT(arena->allocated());
         ArenaHeader* next = arena->next;
         if (!next) {
             // Prepend to hold list before we protect the memory.
+            MOZ_RELEASE_ASSERT(
+                uintptr_t(relocatedArenasToRelease) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
             arena->next = relocatedArenasToRelease;
             relocatedArenasToRelease = arenaList;
         }
         ProtectPages(arena, ArenaSize);
         arena = next;
     }
 }
 
@@ -3427,17 +3431,17 @@ GCRuntime::sweepBackgroundThings(ZoneLis
     // We must finalize thing kinds in the order specified by BackgroundFinalizePhases.
     ArenaHeader* emptyArenas = nullptr;
     FreeOp fop(rt, threadType);
     for (unsigned phase = 0 ; phase < ArrayLength(BackgroundFinalizePhases) ; ++phase) {
         for (Zone* zone = zones.front(); zone; zone = zone->nextZone()) {
             for (unsigned index = 0 ; index < BackgroundFinalizePhases[phase].length ; ++index) {
                 AllocKind kind = BackgroundFinalizePhases[phase].kinds[index];
                 ArenaHeader* arenas = zone->arenas.arenaListsToSweep[kind];
-                MOZ_RELEASE_ASSERT(uintptr_t(arenas) != uintptr_t(-1));
+                MOZ_RELEASE_ASSERT(uintptr_t(arenas) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
                 if (arenas)
                     ArenaLists::backgroundFinalize(&fop, arenas, &emptyArenas);
             }
         }
     }
 
     AutoLockGC lock(rt);
     ReleaseArenaList(rt, emptyArenas, lock);
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -301,26 +301,28 @@ struct SortedArenaListSegment
     bool isEmpty() const {
         return tailp == &head;
     }
 
     // Appends |aheader| to this segment.
     void append(ArenaHeader* aheader) {
         MOZ_ASSERT(aheader);
         MOZ_ASSERT_IF(head, head->getAllocKind() == aheader->getAllocKind());
+        MOZ_RELEASE_ASSERT(uintptr_t(aheader) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
         *tailp = aheader;
         tailp = &aheader->next;
     }
 
     // Points the tail of this segment at |aheader|, which may be null. Note
     // that this does not change the tail itself, but merely which arena
     // follows it. This essentially turns the tail into a cursor (see also the
     // description of ArenaList), but from the perspective of a SortedArenaList
     // this makes no difference.
     void linkTo(ArenaHeader* aheader) {
+        MOZ_RELEASE_ASSERT(uintptr_t(aheader) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
         *tailp = aheader;
     }
 };
 
 /*
  * Arena lists have a head and a cursor. The cursor conceptually lies on arena
  * boundaries, i.e. before the first arena, between two arenas, or after the
  * last arena.
@@ -539,16 +541,17 @@ class SortedArenaList
         MOZ_ASSERT(nfree <= thingsPerArena_);
         segments[nfree].append(aheader);
     }
 
     // Remove all empty arenas, inserting them as a linked list.
     void extractEmpty(ArenaHeader** empty) {
         SortedArenaListSegment& segment = segments[thingsPerArena_];
         if (segment.head) {
+            MOZ_RELEASE_ASSERT(uintptr_t(*empty) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b)));
             *segment.tailp = *empty;
             *empty = segment.head;
             segment.clear();
         }
     }
 
     // Links up the tail of each non-empty segment to the head of the next
     // non-empty segment, creating a contiguous list that is returned as an