104 lines
3.5 KiB
Diff
104 lines
3.5 KiB
Diff
From 0128c5a9eeee0d3fc0deb9129dd20eb79338c8f4 Mon Sep 17 00:00:00 2001
|
|
From: Koen Kooi <koen.kooi@linaro.org>
|
|
Date: Mon, 2 Mar 2015 19:08:59 +0800
|
|
Subject: [PATCH 4/5] mozbug746112-no-decommit-on-large-pages
|
|
|
|
---
|
|
Upstream-status: Pending
|
|
|
|
js/src/gc/Heap.h | 15 ++++++++++-----
|
|
js/src/jsgc.cpp | 15 ++++++++++++---
|
|
2 files changed, 22 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h
|
|
index b8f8c78..1cfd269 100644
|
|
--- a/js/src/gc/Heap.h
|
|
+++ b/js/src/gc/Heap.h
|
|
@@ -103,26 +103,31 @@ struct Cell
|
|
};
|
|
|
|
/*
|
|
- * Page size is 4096 by default, except for SPARC, where it is 8192.
|
|
+ * Page size must be static to support our arena pointer optimizations, so we
|
|
+ * are forced to support each platform with non-4096 pages as a special case.
|
|
+ * Note: The freelist supports a maximum arena shift of 15.
|
|
* Note: Do not use JS_CPU_SPARC here, this header is used outside JS.
|
|
* Bug 692267: Move page size definition to gc/Memory.h and include it
|
|
* directly once jsgc.h is no longer an installed header.
|
|
*/
|
|
#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
|
|
const size_t PageShift = 13;
|
|
+const size_t ArenaShift = PageShift;
|
|
+#elif defined(__powerpc__)
|
|
+const size_t PageShift = 16;
|
|
+const size_t ArenaShift = 12;
|
|
#else
|
|
const size_t PageShift = 12;
|
|
+const size_t ArenaShift = PageShift;
|
|
#endif
|
|
const size_t PageSize = size_t(1) << PageShift;
|
|
+const size_t ArenaSize = size_t(1) << ArenaShift;
|
|
+const size_t ArenaMask = ArenaSize - 1;
|
|
|
|
const size_t ChunkShift = 20;
|
|
const size_t ChunkSize = size_t(1) << ChunkShift;
|
|
const size_t ChunkMask = ChunkSize - 1;
|
|
|
|
-const size_t ArenaShift = PageShift;
|
|
-const size_t ArenaSize = PageSize;
|
|
-const size_t ArenaMask = ArenaSize - 1;
|
|
-
|
|
/*
|
|
* This is the maximum number of arenas we allow in the FreeCommitted state
|
|
* before we trigger a GC_SHRINK to release free arenas to the OS.
|
|
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
|
|
index b3caf05..a258d2d 100644
|
|
--- a/js/src/jsgc.cpp
|
|
+++ b/js/src/jsgc.cpp
|
|
@@ -251,6 +251,13 @@ static const int BackgroundPhaseLength[] = {
|
|
sizeof(BackgroundPhaseStrings) / sizeof(AllocKind)
|
|
};
|
|
|
|
+/* Unused memory decommiting requires the arena size match the page size. */
|
|
+static bool
|
|
+DecommitEnabled()
|
|
+{
|
|
+ return PageSize == ArenaSize;
|
|
+}
|
|
+
|
|
#ifdef DEBUG
|
|
void
|
|
ArenaHeader::checkSynchronizedWithFreeList() const
|
|
@@ -742,7 +749,8 @@ Chunk::fetchNextDecommittedArena()
|
|
decommittedArenas.unset(offset);
|
|
|
|
Arena *arena = &arenas[offset];
|
|
- MarkPagesInUse(arena, ArenaSize);
|
|
+ if (DecommitEnabled())
|
|
+ MarkPagesInUse(arena, ArenaSize);
|
|
arena->aheader.setAsNotAllocated();
|
|
|
|
return &arena->aheader;
|
|
@@ -2731,7 +2739,7 @@ DecommitArenasFromAvailableList(JSRuntime *rt, Chunk **availableListHeadp)
|
|
chunk->removeFromAvailableList();
|
|
|
|
size_t arenaIndex = Chunk::arenaIndex(aheader->arenaAddress());
|
|
- bool ok;
|
|
+ bool ok = true;
|
|
{
|
|
/*
|
|
* If the main thread waits for the decommit to finish, skip
|
|
@@ -2741,7 +2749,8 @@ DecommitArenasFromAvailableList(JSRuntime *rt, Chunk **availableListHeadp)
|
|
Maybe<AutoUnlockGC> maybeUnlock;
|
|
if (!rt->isHeapBusy())
|
|
maybeUnlock.construct(rt);
|
|
- ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
|
|
+ if (DecommitEnabled())
|
|
+ ok = MarkPagesUnused(aheader->getArena(), ArenaSize);
|
|
}
|
|
|
|
if (ok) {
|
|
--
|
|
1.9.3
|
|
|