From: khr@golang.org Date: Thu, 31 Oct 2024 23:04:33 +0000 (-0700) Subject: internal/runtime/maps: return after fatal to help register allocator X-Git-Tag: go1.24rc1~505 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=43725ba2835d3c0f695d0b74d7d796e562b9aae2;p=gostls13.git internal/runtime/maps: return after fatal to help register allocator Seems simple, but putting the return after fatal ensures that at the point of the small group loop, no call has happened so the key is still in a register. This ensures that we don't have to restore the key from the stack before the comparison on each iteration. That gets rid of a load from the inner loop. name old time/op new time/op delta MapAccessHit/Key=int64/Elem=int64/len=6-8 4.01ns ± 6% 3.85ns ± 3% -3.92% (p=0.001 n=10+10) Change-Id: Ia23ac48e6c5522be88f7d9be0ff3489b2dfc52fc Reviewed-on: https://go-review.googlesource.com/c/go/+/624255 Reviewed-by: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- diff --git a/src/internal/runtime/maps/map.go b/src/internal/runtime/maps/map.go index 4643960247..9ebc72a524 100644 --- a/src/internal/runtime/maps/map.go +++ b/src/internal/runtime/maps/map.go @@ -560,6 +560,7 @@ func (m *Map) putSlotSmall(typ *abi.SwissMapType, hash uintptr, key unsafe.Point match = g.ctrls().matchEmptyOrDeleted() if match == 0 { fatal("small map with no empty slot (concurrent map writes?)") + return nil } i := match.first() diff --git a/src/internal/runtime/maps/runtime_fast32_swiss.go b/src/internal/runtime/maps/runtime_fast32_swiss.go index 84c85772f4..95c2a5ec1f 100644 --- a/src/internal/runtime/maps/runtime_fast32_swiss.go +++ b/src/internal/runtime/maps/runtime_fast32_swiss.go @@ -27,6 +27,7 @@ func runtime_mapaccess1_fast32(typ *abi.SwissMapType, m *Map, key uint32) unsafe if m.writing != 0 { fatal("concurrent map read and map write") + return nil } if m.dirLen == 0 { @@ -91,6 +92,7 @@ func runtime_mapaccess2_fast32(typ *abi.SwissMapType, m *Map, key uint32) (unsaf if m.writing != 0 { fatal("concurrent map read and map write") + return nil, false } if m.dirLen == 0 { diff --git a/src/internal/runtime/maps/runtime_fast64_swiss.go b/src/internal/runtime/maps/runtime_fast64_swiss.go index 7c9ce87cdc..d00e4b6258 100644 --- a/src/internal/runtime/maps/runtime_fast64_swiss.go +++ b/src/internal/runtime/maps/runtime_fast64_swiss.go @@ -27,6 +27,7 @@ func runtime_mapaccess1_fast64(typ *abi.SwissMapType, m *Map, key uint64) unsafe if m.writing != 0 { fatal("concurrent map read and map write") + return nil } if m.dirLen == 0 { @@ -91,6 +92,7 @@ func runtime_mapaccess2_fast64(typ *abi.SwissMapType, m *Map, key uint64) (unsaf if m.writing != 0 { fatal("concurrent map read and map write") + return nil, false } if m.dirLen == 0 { diff --git a/src/internal/runtime/maps/runtime_faststr_swiss.go b/src/internal/runtime/maps/runtime_faststr_swiss.go index ab0213ba33..08172334e7 100644 --- a/src/internal/runtime/maps/runtime_faststr_swiss.go +++ b/src/internal/runtime/maps/runtime_faststr_swiss.go @@ -55,6 +55,7 @@ func runtime_mapaccess1_faststr(typ *abi.SwissMapType, m *Map, key string) unsaf if m.writing != 0 { fatal("concurrent map read and map write") + return nil } hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed) @@ -112,6 +113,7 @@ func runtime_mapaccess2_faststr(typ *abi.SwissMapType, m *Map, key string) (unsa if m.writing != 0 { fatal("concurrent map read and map write") + return nil, false } hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed) diff --git a/src/internal/runtime/maps/table.go b/src/internal/runtime/maps/table.go index 494ede7911..7b3895c0a1 100644 --- a/src/internal/runtime/maps/table.go +++ b/src/internal/runtime/maps/table.go @@ -608,6 +608,7 @@ func (it *Iter) Next() { if it.m.writing != 0 { fatal("concurrent map iteration and map write") + return } if it.dirIdx < 0 {