]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime/maps: hash copy of key instead of key itself
authorKeith Randall <khr@golang.org>
Tue, 19 Nov 2024 00:37:59 +0000 (16:37 -0800)
committerKeith Randall <khr@golang.org>
Tue, 19 Nov 2024 21:15:55 +0000 (21:15 +0000)
Hashing the key means we have to take the address of it. That inhibits
subsequent optimizations on the key variable.

By hashing a copy, we incur an extra store at the hash callsite, but
we no longer need a load of the key in the inner loop. It can live
in a register throughout. (Technically, it gets spilled around
the call to the hasher, but it gets restored outside the loop.)

Maybe one day we can have special hash functions that take
int64/int32/string instead of *int64/*int32/*string.

Change-Id: Iba3133f6e82328f53c0abcb5eec13ee47c4969d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/629419
Reviewed-by: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/internal/runtime/maps/runtime_fast32_swiss.go
src/internal/runtime/maps/runtime_fast64_swiss.go
src/internal/runtime/maps/runtime_faststr_swiss.go

index ff5815abdd1d4ddfa61bdf3b9e1cc7473c2bd3ca..15facbfe8a6bb2100372af8533f019ad4d75bbf9 100644 (file)
@@ -48,7 +48,8 @@ func runtime_mapaccess1_fast32(typ *abi.SwissMapType, m *Map, key uint32) unsafe
                return unsafe.Pointer(&zeroVal[0])
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -116,7 +117,8 @@ func runtime_mapaccess2_fast32(typ *abi.SwissMapType, m *Map, key uint32) (unsaf
                return unsafe.Pointer(&zeroVal[0]), false
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -203,7 +205,8 @@ func runtime_mapassign_fast32(typ *abi.SwissMapType, m *Map, key uint32) unsafe.
                fatal("concurrent map writes")
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Set writing after calling Hasher, since Hasher may panic, in which
        // case we have not actually done a write.
@@ -336,7 +339,8 @@ func runtime_mapassign_fast32ptr(typ *abi.SwissMapType, m *Map, key unsafe.Point
                fatal("concurrent map writes")
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Set writing after calling Hasher, since Hasher may panic, in which
        // case we have not actually done a write.
index 90e84f83d2539ab23bfce1c2b575724e9fc31b19..f08e7ef86900aa262d48d4bc6a0280702d3a30d3 100644 (file)
@@ -48,7 +48,8 @@ func runtime_mapaccess1_fast64(typ *abi.SwissMapType, m *Map, key uint64) unsafe
                return unsafe.Pointer(&zeroVal[0])
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -116,7 +117,8 @@ func runtime_mapaccess2_fast64(typ *abi.SwissMapType, m *Map, key uint64) (unsaf
                return unsafe.Pointer(&zeroVal[0]), false
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -203,7 +205,8 @@ func runtime_mapassign_fast64(typ *abi.SwissMapType, m *Map, key uint64) unsafe.
                fatal("concurrent map writes")
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Set writing after calling Hasher, since Hasher may panic, in which
        // case we have not actually done a write.
@@ -374,7 +377,8 @@ func runtime_mapassign_fast64ptr(typ *abi.SwissMapType, m *Map, key unsafe.Point
                fatal("concurrent map writes")
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Set writing after calling Hasher, since Hasher may panic, in which
        // case we have not actually done a write.
index a104945501d3745ff8fd95f7ae15a387b146af46..077c05ae8b94b765526cc22bd1d45cf56f0e3f4d 100644 (file)
@@ -124,7 +124,8 @@ func runtime_mapaccess1_faststr(typ *abi.SwissMapType, m *Map, key string) unsaf
                return elem
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -182,7 +183,8 @@ func runtime_mapaccess2_faststr(typ *abi.SwissMapType, m *Map, key string) (unsa
                return elem, true
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Select table.
        idx := m.directoryIndex(hash)
@@ -271,7 +273,8 @@ func runtime_mapassign_faststr(typ *abi.SwissMapType, m *Map, key string) unsafe
                fatal("concurrent map writes")
        }
 
-       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
+       k := key
+       hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
 
        // Set writing after calling Hasher, since Hasher may panic, in which
        // case we have not actually done a write.