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

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