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

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