diff options
| author | Keith Randall <khr@golang.org> | 2025-02-11 18:58:13 -0800 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2025-04-04 10:53:05 -0700 |
| commit | 5fc596ebe7c34b9f68c33da5ffc4f3645c38ef72 (patch) | |
| tree | 11e46010c5f48d0e2361f7f3f2bb79ec3659efdb /src/cmd/compile/internal/test | |
| parent | 6839e71d82e0f2c93e043820db6c0238a65ae0fa (diff) | |
| download | go-5fc596ebe7c34b9f68c33da5ffc4f3645c38ef72.tar.xz | |
cmd/compile: aggregate scalar allocations for heap escapes
If multiple small scalars escape to the heap, allocate them together
with a single allocation. They are going to be aggregated together
in the tiny allocator anyway, might as well do just one runtime call.
Change-Id: I4317e29235af63de378a26436a18d7fb0c39e41f
Reviewed-on: https://go-review.googlesource.com/c/go/+/648536
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/compile/internal/test')
| -rw-r--r-- | src/cmd/compile/internal/test/locals_test.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/test/locals_test.go b/src/cmd/compile/internal/test/locals_test.go new file mode 100644 index 0000000000..a5eafc6116 --- /dev/null +++ b/src/cmd/compile/internal/test/locals_test.go @@ -0,0 +1,76 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package test + +import "testing" + +func locals() { + var x int64 + var y int32 + var z int16 + var w int8 + sink64 = &x + sink32 = &y + sink16 = &z + sink8 = &w +} + +//go:noinline +func args(x int64, y int32, z int16, w int8) { + sink64 = &x + sink32 = &y + sink16 = &z + sink8 = &w + +} + +//go:noinline +func half(x int64, y int16) { + var z int32 + var w int8 + sink64 = &x + sink16 = &y + sink32 = &z + sink8 = &w +} + +//go:noinline +func closure() func() { + var x int64 + var y int32 + var z int16 + var w int8 + _, _, _, _ = x, y, z, w + return func() { + x = 1 + y = 2 + z = 3 + w = 4 + } +} + +var sink64 *int64 +var sink32 *int32 +var sink16 *int16 +var sink8 *int8 + +func TestLocalAllocations(t *testing.T) { + type test struct { + name string + f func() + want int + } + for _, tst := range []test{ + {"locals", locals, 1}, + {"args", func() { args(1, 2, 3, 4) }, 1}, + {"half", func() { half(1, 2) }, 1}, + {"closure", func() { _ = closure() }, 2}, + } { + allocs := testing.AllocsPerRun(100, tst.f) + if allocs != float64(tst.want) { + t.Errorf("test %s uses %v allocs, want %d", tst.name, allocs, tst.want) + } + } +} |
