blob: 8bd35d40555c799352dff3529763e85fb96b0e48 [file] [log] [blame]
Patrick Williamsb48b7b42016-08-17 15:04:38 -05001From 0128c5a9eeee0d3fc0deb9129dd20eb79338c8f4 Mon Sep 17 00:00:00 2001
2From: Koen Kooi <koen.kooi@linaro.org>
3Date: Mon, 2 Mar 2015 19:08:59 +0800
4Subject: [PATCH 4/5] mozbug746112-no-decommit-on-large-pages
5
6---
7Upstream-status: Pending
8
9 js/src/gc/Heap.h | 15 ++++++++++-----
10 js/src/jsgc.cpp | 15 ++++++++++++---
11 2 files changed, 22 insertions(+), 8 deletions(-)
12
13diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h
14index b8f8c78..1cfd269 100644
15--- a/js/src/gc/Heap.h
16+++ b/js/src/gc/Heap.h
17@@ -103,26 +103,31 @@ struct Cell
18 };
19
20 /*
21- * Page size is 4096 by default, except for SPARC, where it is 8192.
22+ * Page size must be static to support our arena pointer optimizations, so we
23+ * are forced to support each platform with non-4096 pages as a special case.
24+ * Note: The freelist supports a maximum arena shift of 15.
25 * Note: Do not use JS_CPU_SPARC here, this header is used outside JS.
26 * Bug 692267: Move page size definition to gc/Memory.h and include it
27 * directly once jsgc.h is no longer an installed header.
28 */
29 #if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
30 const size_t PageShift = 13;
31+const size_t ArenaShift = PageShift;
32+#elif defined(__powerpc__)
33+const size_t PageShift = 16;
34+const size_t ArenaShift = 12;
35 #else
36 const size_t PageShift = 12;
37+const size_t ArenaShift = PageShift;
38 #endif
39 const size_t PageSize = size_t(1) << PageShift;
40+const size_t ArenaSize = size_t(1) << ArenaShift;
41+const size_t ArenaMask = ArenaSize - 1;
42
43 const size_t ChunkShift = 20;
44 const size_t ChunkSize = size_t(1) << ChunkShift;
45 const size_t ChunkMask = ChunkSize - 1;
46
47-const size_t ArenaShift = PageShift;
48-const size_t ArenaSize = PageSize;
49-const size_t ArenaMask = ArenaSize - 1;
50-
51 /*
52 * This is the maximum number of arenas we allow in the FreeCommitted state
53 * before we trigger a GC_SHRINK to release free arenas to the OS.
54diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
55index b3caf05..a258d2d 100644
56--- a/js/src/jsgc.cpp
57+++ b/js/src/jsgc.cpp
58@@ -251,6 +251,13 @@ static const int BackgroundPhaseLength[] = {
59 sizeof(BackgroundPhaseStrings) / sizeof(AllocKind)
60 };
61
62+/* Unused memory decommiting requires the arena size match the page size. */
63+static bool
64+DecommitEnabled()
65+{
66+ return PageSize == ArenaSize;
67+}
68+
69 #ifdef DEBUG
70 void
71 ArenaHeader::checkSynchronizedWithFreeList() const
72@@ -742,7 +749,8 @@ Chunk::fetchNextDecommittedArena()
73 decommittedArenas.unset(offset);
74
75 Arena *arena = &arenas[offset];
76- MarkPagesInUse(arena, ArenaSize);
77+ if (DecommitEnabled())
78+ MarkPagesInUse(arena, ArenaSize);
79 arena->aheader.setAsNotAllocated();
80
81 return &arena->aheader;
82@@ -2731,7 +2739,7 @@ DecommitArenasFromAvailableList(JSRuntime *rt, Chunk **availableListHeadp)
83 chunk->removeFromAvailableList();
84
85 size_t arenaIndex = Chunk::arenaIndex(aheader->arenaAddress());
86- bool ok;
87+ bool ok = true;
88 {
89 /*
90 * If the main thread waits for the decommit to finish, skip
91@@ -2741,7 +2749,8 @@ DecommitArenasFromAvailableList(JSRuntime *rt, Chunk **availableListHeadp)
92 Maybe<AutoUnlockGC> maybeUnlock;
93 if (!rt->isHeapBusy())
94 maybeUnlock.construct(rt);
95- ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
96+ if (DecommitEnabled())
97+ ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
98 }
99
100 if (ok) {
101--
1021.9.3
103