After the change from CL 426074 the Range method on Map always
escape the read variable, leading to an allocation.
Since the compiler doesn't do live-range splitting for local variables we
need to use some hints to only escape in that particular branch.
Fixes #62404
Change-Id: I938a5e593647455fa827e3dd3ed8ea22c7365df1
GitHub-Last-Rev:
fcbedb467c7b4e6f1d49e299d243cad70deb34e9
GitHub-Pull-Request: golang/go#62408
Reviewed-on: https://go-review.googlesource.com/c/go/+/524976
Auto-Submit: Bryan Mills <bcmills@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
read = m.loadReadOnly()
if read.amended {
read = readOnly{m: m.dirty}
- m.read.Store(&read)
+ copyRead := read
+ m.read.Store(©Read)
m.dirty = nil
m.misses = 0
}
package sync_test
import (
+ "internal/testenv"
"math/rand"
"reflect"
"runtime"
t.Fatalf("CompareAndSwap on an non-existing key succeeded")
}
}
+
+func TestMapRangeNoAllocations(t *testing.T) { // Issue 62404
+ testenv.SkipIfOptimizationOff(t)
+ var m sync.Map
+ allocs := testing.AllocsPerRun(10, func() {
+ m.Range(func(key, value any) bool {
+ return true
+ })
+ })
+ if allocs > 0 {
+ t.Errorf("AllocsPerRun of m.Range = %v; want 0", allocs)
+ }
+}