aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/stackalloc.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2022-10-18 16:07:36 -0700
committerKeith Randall <khr@google.com>2022-10-31 21:41:20 +0000
commit68bd383368b5958f8f02c49bc75134a0ef61daec (patch)
tree49c5272deb4f1416918a11644e351c491dd5a647 /src/cmd/compile/internal/ssa/stackalloc.go
parent7ddc45263c739db254a07bb04848e3e5da4982ed (diff)
downloadgo-68bd383368b5958f8f02c49bc75134a0ef61daec.tar.xz
cmd/compile: add cache of sizeable objects so they can be reused
We kind of have this mechanism already, just normalizing it and using it in a bunch of places. Previously a bunch of places cached slices only for the duration of a single function compilation. Now we can reuse slices across a whole compiler run. Use a sync.Pool of powers-of-two sizes. This lets us use not too much memory, and avoid holding onto memory we're no longer using when a GC happens. There's a few different types we need, so generate the code for it. Generics would be useful here, but we can't use generics in the compiler because of bootstrapping. Change-Id: I6cf37e7b7b2e802882aaa723a0b29770511ccd82 Reviewed-on: https://go-review.googlesource.com/c/go/+/444820 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/stackalloc.go')
-rw-r--r--src/cmd/compile/internal/ssa/stackalloc.go26
1 files changed, 4 insertions, 22 deletions
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go
index d41f3996af..3e24b48a69 100644
--- a/src/cmd/compile/internal/ssa/stackalloc.go
+++ b/src/cmd/compile/internal/ssa/stackalloc.go
@@ -25,8 +25,6 @@ type stackAllocState struct {
values []stackValState
interfere [][]ID // interfere[v.id] = values that interfere with v.
names []LocalSlot
- slots []int
- used []bool
nArgSlot, // Number of Values sourced to arg slot
nNotNeed, // Number of Values not needing a stack slot
@@ -57,12 +55,6 @@ func putStackAllocState(s *stackAllocState) {
for i := range s.names {
s.names[i] = LocalSlot{}
}
- for i := range s.slots {
- s.slots[i] = 0
- }
- for i := range s.used {
- s.used[i] = false
- }
s.f.Cache.stackAllocState = s
s.f = nil
s.live = nil
@@ -218,25 +210,15 @@ func (s *stackAllocState) stackalloc() {
// Each time we assign a stack slot to a value v, we remember
// the slot we used via an index into locations[v.Type].
- slots := s.slots
- if n := f.NumValues(); cap(slots) >= n {
- slots = slots[:n]
- } else {
- slots = make([]int, n)
- s.slots = slots
- }
+ slots := f.Cache.allocIntSlice(f.NumValues())
+ defer f.Cache.freeIntSlice(slots)
for i := range slots {
slots[i] = -1
}
// Pick a stack slot for each value needing one.
- var used []bool
- if n := f.NumValues(); cap(s.used) >= n {
- used = s.used[:n]
- } else {
- used = make([]bool, n)
- s.used = used
- }
+ used := f.Cache.allocBoolSlice(f.NumValues())
+ defer f.Cache.freeBoolSlice(used)
for _, b := range f.Blocks {
for _, v := range b.Values {
if !s.values[v.ID].needSlot {