mirror of https://github.com/golang/go.git
sync: prevent (*Map).Range from always escaping
After the change from CL 426074 the Range method on Map always escape the read variable, generating 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
This commit is contained in:
parent
ffc4ccea07
commit
fcbedb467c
|
|
@ -461,7 +461,8 @@ func (m *Map) Range(f func(key, value any) bool) {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
package sync_test
|
||||
|
||||
import (
|
||||
"internal/testenv"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
|
@ -280,3 +281,16 @@ func TestCompareAndSwap_NonExistingKey(t *testing.T) {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue