Patrick Williams | b48b7b4 | 2016-08-17 15:04:38 -0500 | [diff] [blame] | 1 | From 0128c5a9eeee0d3fc0deb9129dd20eb79338c8f4 Mon Sep 17 00:00:00 2001 |
| 2 | From: Koen Kooi <koen.kooi@linaro.org> |
| 3 | Date: Mon, 2 Mar 2015 19:08:59 +0800 |
| 4 | Subject: [PATCH 4/5] mozbug746112-no-decommit-on-large-pages |
| 5 | |
| 6 | --- |
| 7 | Upstream-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 | |
| 13 | diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h |
| 14 | index 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. |
| 54 | diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp |
| 55 | index 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 | -- |
| 102 | 1.9.3 |
| 103 | |