diff options
| author | Cherry Mui <cherryyz@google.com> | 2025-06-22 15:40:02 -0400 |
|---|---|---|
| committer | Cherry Mui <cherryyz@google.com> | 2025-09-26 17:13:31 -0700 |
| commit | 53009b26dd2e8b75fba8b44849e1d323ddb2a31f (patch) | |
| tree | 09416fd14429b1519dbce83fcd79034cd60596c6 /src/runtime/mpagealloc_test.go | |
| parent | 3a5df9d2b20c0f059c463b5d51e89be17a2c685b (diff) | |
| download | go-53009b26dd2e8b75fba8b44849e1d323ddb2a31f.tar.xz | |
runtime: use a smaller arena size on Wasm
On Wasm, some programs have very small heap. Currently,
we use 4 MB arena size (like all other 32-bit platforms).
For a very small program, it needs to allocate one heap
arena, 4 MB size at a 4 MB aligned address. So we'll
need 8 MB of linear memory, whereas only a smaller
portion is actually used by the program. On Wasm, samll
programs are not uncommon (e.g. WASI plugins), and
users are concerned about the memory usage.
This CL switches to a smaller arena size, as well as a
smaller page allocator chunk size (both are now 512 KB).
So the heap will be grown in 512 KB granularity. For a
helloworld program, it now uses less than 3 MB of
linear memory, instead of 8 MB.
Change-Id: Ibd66c1fa6e794a12c00906cbacc8f2e410f196c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/683296
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/mpagealloc_test.go')
| -rw-r--r-- | src/runtime/mpagealloc_test.go | 217 |
1 files changed, 112 insertions, 105 deletions
diff --git a/src/runtime/mpagealloc_test.go b/src/runtime/mpagealloc_test.go index f2b82e3f50..ded7a79922 100644 --- a/src/runtime/mpagealloc_test.go +++ b/src/runtime/mpagealloc_test.go @@ -343,38 +343,6 @@ func TestPageAllocAlloc(t *testing.T) { BaseChunkIdx: {{0, 25}}, }, }, - "AllFree64": { - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {}, - }, - scav: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{21, 1}, {63, 65}}, - }, - hits: []hit{ - {64, PageBase(BaseChunkIdx, 0), 2 * PageSize}, - {64, PageBase(BaseChunkIdx, 64), 64 * PageSize}, - {64, PageBase(BaseChunkIdx, 128), 0}, - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, 192}}, - }, - }, - "AllFree65": { - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {}, - }, - scav: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{129, 1}}, - }, - hits: []hit{ - {65, PageBase(BaseChunkIdx, 0), 0}, - {65, PageBase(BaseChunkIdx, 65), PageSize}, - {65, PageBase(BaseChunkIdx, 130), 0}, - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, 195}}, - }, - }, "ExhaustPallocChunkPages-3": { before: map[ChunkIdx][]BitRange{ BaseChunkIdx: {}, @@ -410,25 +378,6 @@ func TestPageAllocAlloc(t *testing.T) { BaseChunkIdx: {{0, PallocChunkPages}}, }, }, - "StraddlePallocChunkPages": { - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages / 2}}, - BaseChunkIdx + 1: {{PallocChunkPages / 2, PallocChunkPages / 2}}, - }, - scav: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {}, - BaseChunkIdx + 1: {{3, 100}}, - }, - hits: []hit{ - {PallocChunkPages, PageBase(BaseChunkIdx, PallocChunkPages/2), 100 * PageSize}, - {PallocChunkPages, 0, 0}, - {1, 0, 0}, - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages}}, - BaseChunkIdx + 1: {{0, PallocChunkPages}}, - }, - }, "StraddlePallocChunkPages+1": { before: map[ChunkIdx][]BitRange{ BaseChunkIdx: {{0, PallocChunkPages / 2}}, @@ -489,28 +438,6 @@ func TestPageAllocAlloc(t *testing.T) { BaseChunkIdx + 0x41: {{0, PallocChunkPages}}, }, }, - "StraddlePallocChunkPages*2": { - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages / 2}}, - BaseChunkIdx + 1: {}, - BaseChunkIdx + 2: {{PallocChunkPages / 2, PallocChunkPages / 2}}, - }, - scav: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, 7}}, - BaseChunkIdx + 1: {{3, 5}, {121, 10}}, - BaseChunkIdx + 2: {{PallocChunkPages/2 + 12, 2}}, - }, - hits: []hit{ - {PallocChunkPages * 2, PageBase(BaseChunkIdx, PallocChunkPages/2), 15 * PageSize}, - {PallocChunkPages * 2, 0, 0}, - {1, 0, 0}, - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages}}, - BaseChunkIdx + 1: {{0, PallocChunkPages}}, - BaseChunkIdx + 2: {{0, PallocChunkPages}}, - }, - }, "StraddlePallocChunkPages*5/4": { before: map[ChunkIdx][]BitRange{ BaseChunkIdx: {{0, PallocChunkPages}}, @@ -536,7 +463,60 @@ func TestPageAllocAlloc(t *testing.T) { BaseChunkIdx + 3: {{0, PallocChunkPages}}, }, }, - "AllFreePallocChunkPages*7+5": { + } + if PallocChunkPages >= 512 { + tests["AllFree64"] = test{ + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{21, 1}, {63, 65}}, + }, + hits: []hit{ + {64, PageBase(BaseChunkIdx, 0), 2 * PageSize}, + {64, PageBase(BaseChunkIdx, 64), 64 * PageSize}, + {64, PageBase(BaseChunkIdx, 128), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 192}}, + }, + } + tests["AllFree65"] = test{ + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{129, 1}}, + }, + hits: []hit{ + {65, PageBase(BaseChunkIdx, 0), 0}, + {65, PageBase(BaseChunkIdx, 65), PageSize}, + {65, PageBase(BaseChunkIdx, 130), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 195}}, + }, + } + tests["StraddlePallocChunkPages"] = test{ + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {{3, 100}}, + }, + hits: []hit{ + {PallocChunkPages, PageBase(BaseChunkIdx, PallocChunkPages/2), 100 * PageSize}, + {PallocChunkPages, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + } + tests["AllFreePallocChunkPages*7+5"] = test{ before: map[ChunkIdx][]BitRange{ BaseChunkIdx: {}, BaseChunkIdx + 1: {}, @@ -572,7 +552,29 @@ func TestPageAllocAlloc(t *testing.T) { BaseChunkIdx + 6: {{0, PallocChunkPages}}, BaseChunkIdx + 7: {{0, 6}}, }, - }, + } + tests["StraddlePallocChunkPages*2"] = test{ + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 7}}, + BaseChunkIdx + 1: {{3, 5}, {121, 10}}, + BaseChunkIdx + 2: {{PallocChunkPages/2 + 12, 2}}, + }, + hits: []hit{ + {PallocChunkPages * 2, PageBase(BaseChunkIdx, PallocChunkPages/2), 15 * PageSize}, + {PallocChunkPages * 2, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + } } // Disable these tests on iOS since we have a small address space. // See #46860. @@ -754,12 +756,13 @@ func TestPageAllocFree(t *testing.T) { if GOOS == "openbsd" && testing.Short() { t.Skip("skipping because virtual memory is limited; see #36210") } - tests := map[string]struct { + type test struct { before map[ChunkIdx][]BitRange after map[ChunkIdx][]BitRange npages uintptr frees []uintptr - }{ + } + tests := map[string]test{ "Free1": { npages: 1, before: map[ChunkIdx][]BitRange{ @@ -840,34 +843,6 @@ func TestPageAllocFree(t *testing.T) { BaseChunkIdx: {{25, PallocChunkPages - 25}}, }, }, - "Free64": { - npages: 64, - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages}}, - }, - frees: []uintptr{ - PageBase(BaseChunkIdx, 0), - PageBase(BaseChunkIdx, 64), - PageBase(BaseChunkIdx, 128), - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{192, PallocChunkPages - 192}}, - }, - }, - "Free65": { - npages: 65, - before: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{0, PallocChunkPages}}, - }, - frees: []uintptr{ - PageBase(BaseChunkIdx, 0), - PageBase(BaseChunkIdx, 65), - PageBase(BaseChunkIdx, 130), - }, - after: map[ChunkIdx][]BitRange{ - BaseChunkIdx: {{195, PallocChunkPages - 195}}, - }, - }, "FreePallocChunkPages": { npages: PallocChunkPages, before: map[ChunkIdx][]BitRange{ @@ -965,6 +940,38 @@ func TestPageAllocFree(t *testing.T) { }, }, } + if PallocChunkPages >= 512 { + // avoid constant overflow when PallocChunkPages is small + var PallocChunkPages uint = PallocChunkPages + tests["Free64"] = test{ + npages: 64, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 64), + PageBase(BaseChunkIdx, 128), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{192, PallocChunkPages - 192}}, + }, + } + tests["Free65"] = test{ + npages: 65, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 65), + PageBase(BaseChunkIdx, 130), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{195, PallocChunkPages - 195}}, + }, + } + } for name, v := range tests { v := v t.Run(name, func(t *testing.T) { |
