Blame SOURCES/mozbug746112-no-decommit-on-large-pages.patch

f27401
# See https://bugzilla.redhat.com/show_bug.cgi?id=971519
f27401
# HG changeset patch
f27401
# User Terrence Cole <terrence@mozilla.com>
f27401
# Date 1346874025 25200
f27401
# Node ID 0558ede9693e57663e4836c7e678b55465ddc2ab
f27401
# Parent  d28e07f4bec6c16b32ae4743eaeeae2a9e2f6381
f27401
Bug 746112 - Don't decommit if page size is too large; r=billm
f27401
f27401
The powerpc architecture has 64KiB pages, which is too large to represent in the
f27401
free list.  This patch splits the page size from the arena size and disabled
f27401
decommit logic in that case.
f27401
f27401
diff -up xulrunner-17.0/mozilla-beta/js/src/gc/Heap.h.746112 xulrunner-17.0/mozilla-beta/js/src/gc/Heap.h
f27401
--- a/js/src/gc/Heap.h.746112	2012-10-17 16:32:43.000000000 +0200
f27401
+++ b/js/src/gc/Heap.h	2012-10-24 14:48:12.186640489 +0200
f27401
@@ -103,26 +103,31 @@ struct Cell
f27401
 };
f27401
 
f27401
 /*
f27401
- * Page size is 4096 by default, except for SPARC, where it is 8192.
f27401
+ * Page size must be static to support our arena pointer optimizations, so we
f27401
+ * are forced to support each platform with non-4096 pages as a special case.
f27401
+ * Note: The freelist supports a maximum arena shift of 15.
f27401
  * Note: Do not use JS_CPU_SPARC here, this header is used outside JS.
f27401
  * Bug 692267: Move page size definition to gc/Memory.h and include it
f27401
  *             directly once jsgc.h is no longer an installed header.
f27401
  */
f27401
 #if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
f27401
 const size_t PageShift = 13;
f27401
+const size_t ArenaShift = PageShift;
f27401
+#elif defined(__powerpc__)
f27401
+const size_t PageShift = 16;
f27401
+const size_t ArenaShift = 12;
f27401
 #else
f27401
 const size_t PageShift = 12;
f27401
+const size_t ArenaShift = PageShift;
f27401
 #endif
f27401
 const size_t PageSize = size_t(1) << PageShift;
f27401
+const size_t ArenaSize = size_t(1) << ArenaShift;
f27401
+const size_t ArenaMask = ArenaSize - 1;
f27401
 
f27401
 const size_t ChunkShift = 20;
f27401
 const size_t ChunkSize = size_t(1) << ChunkShift;
f27401
 const size_t ChunkMask = ChunkSize - 1;
f27401
 
f27401
-const size_t ArenaShift = PageShift;
f27401
-const size_t ArenaSize = PageSize;
f27401
-const size_t ArenaMask = ArenaSize - 1;
f27401
-
f27401
 /*
f27401
  * This is the maximum number of arenas we allow in the FreeCommitted state
f27401
  * before we trigger a GC_SHRINK to release free arenas to the OS.
f27401
diff -up xulrunner-17.0/mozilla-beta/js/src/jsgc.cpp.746112 xulrunner-17.0/mozilla-beta/js/src/jsgc.cpp
f27401
--- a/js/src/jsgc.cpp.746112	2012-10-17 16:32:44.000000000 +0200
f27401
+++ b/js/src/jsgc.cpp	2012-10-24 14:46:28.253638095 +0200
f27401
@@ -251,6 +251,13 @@ static const int BackgroundPhaseLength[]
f27401
     sizeof(BackgroundPhaseStrings) / sizeof(AllocKind)
f27401
 };
f27401
 
f27401
+/* Unused memory decommiting requires the arena size match the page size. */
f27401
+static bool
f27401
+DecommitEnabled()
f27401
+{
f27401
+    return PageSize == ArenaSize;
f27401
+}
f27401
+
f27401
 #ifdef DEBUG
f27401
 void
f27401
 ArenaHeader::checkSynchronizedWithFreeList() const
f27401
@@ -742,7 +749,8 @@ Chunk::fetchNextDecommittedArena()
f27401
     decommittedArenas.unset(offset);
f27401
 
f27401
     Arena *arena = &arenas[offset];
f27401
-    MarkPagesInUse(arena, ArenaSize);
f27401
+    if (DecommitEnabled())
f27401
+        MarkPagesInUse(arena, ArenaSize);
f27401
     arena->aheader.setAsNotAllocated();
f27401
 
f27401
     return &arena->aheader;
f27401
@@ -2731,7 +2739,7 @@ DecommitArenasFromAvailableList(JSRuntim
f27401
                 chunk->removeFromAvailableList();
f27401
 
f27401
             size_t arenaIndex = Chunk::arenaIndex(aheader->arenaAddress());
f27401
-            bool ok;
f27401
+            bool ok = true;
f27401
             {
f27401
                 /*
f27401
                  * If the main thread waits for the decommit to finish, skip
f27401
@@ -2741,7 +2749,8 @@ DecommitArenasFromAvailableList(JSRuntim
f27401
                 Maybe<AutoUnlockGC> maybeUnlock;
f27401
                 if (!rt->isHeapBusy())
f27401
                     maybeUnlock.construct(rt);
f27401
-                ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
f27401
+                if (DecommitEnabled())
f27401
+                    ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
f27401
             }
f27401
 
f27401
             if (ok) {