]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime/maps: return after fatal to help register allocator
authorkhr@golang.org <khr@golang.org>
Thu, 31 Oct 2024 23:04:33 +0000 (16:04 -0700)
committerKeith Randall <khr@golang.org>
Fri, 1 Nov 2024 20:11:30 +0000 (20:11 +0000)
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 <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
src/internal/runtime/maps/map.go
src/internal/runtime/maps/runtime_fast32_swiss.go
src/internal/runtime/maps/runtime_fast64_swiss.go
src/internal/runtime/maps/runtime_faststr_swiss.go
src/internal/runtime/maps/table.go

index 46439602470d528dfcbaf52170f670e2fd2c956d..9ebc72a524feb23c877e0334a04fa97559662b32 100644 (file)
@@ -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()
index 84c85772f490c20bf6238c767482886ede886e6c..95c2a5ec1f346a4e298eec5e52073276044d6734 100644 (file)
@@ -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 {
index 7c9ce87cdce5a68ee5f7183a32af6505f702a149..d00e4b625846cd59ec559dc5003edb5a42085279 100644 (file)
@@ -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 {
index ab0213ba3350e0c99eacf176383f3e87820d83b4..08172334e73196ed073e2693811e9412de79d35c 100644 (file)
@@ -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)
index 494ede79111d654bae7b27db4c7e966cce21d092..7b3895c0a173951981d2b59080bdd98d524bc370 100644 (file)
@@ -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 {