You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The variable sh in Hasher.Hash escapes to the heap, causing an allocation.
# github.com/nussjustin/scache/internal/sharding
./hash_go114.go:11:6: can inline NewHasher as: func() Hasher { return Hasher literal }
./hash_go114.go:17:6: cannot inline Hasher.Hash: function too complex: cost 154 exceeds budget 80
./hash_go114.go:19:12: inlining call to maphash.(*Hash).SetSeed method(*maphash.Hash) func(maphash.Seed) { if maphash.seed.s == uint64(0) { panic(string("maphash: use of uninitialized Seed")) }; maphash.h.seed = maphash.seed; maphash.h.state = maphash.seed; maphash.h.n = int(0) }
./hash_go114.go:18:6: sh escapes to heap:
./hash_go114.go:18:6: flow: {heap} = &sh:
./hash_go114.go:18:6: from sh (address-of) at ./hash_go114.go:20:4
./hash_go114.go:18:6: from sh.WriteString(s) (call parameter) at ./hash_go114.go:20:16
./hash_go114.go:18:6: sh escapes to heap:
./hash_go114.go:18:6: flow: {heap} = &sh:
./hash_go114.go:18:6: from sh (address-of) at ./hash_go114.go:21:11
./hash_go114.go:18:6: from sh.Sum64() (call parameter) at ./hash_go114.go:21:17
./hash_go114.go:17:22: s does not escape
./hash_go114.go:18:6: moved to heap: sh
<autogenerated>:1: .this does not escape
./hash_go114.go:17:22: s does not escape
The WriteString causes *maphash.Hash to escape because it calls flush internally:
./maphash.go:100:7: parameter h leaks to {heap} with derefs=0:
./maphash.go:100:7: flow: {heap} = h:
./maphash.go:100:7: from h.flush() (call parameter) at ./maphash.go:106:10
./maphash.go:100:7: leaking param: h
./maphash.go:100:28: s does not escape
flush itself calls rthash which calls runtime_memhash (imported from runtime.memhash) which causes the array h.buf and thus the *maphash.Hash to escape:
./maphash.go:141:7: parameter h leaks to {heap} with derefs=0:
./maphash.go:141:7: flow: b = h:
./maphash.go:141:7: from h.buf (dot of pointer) at ./maphash.go:146:22
./maphash.go:141:7: from h.buf (address-of) at ./maphash.go:146:26
./maphash.go:141:7: from h.buf[:] (slice) at ./maphash.go:146:26
./maphash.go:141:7: from b, seed = <N> (assign-pair) at ./maphash.go:146:20
./maphash.go:141:7: flow: {heap} = b:
./maphash.go:141:7: from b[0] (dot of pointer) at ./maphash.go:146:20
./maphash.go:141:7: from &b[0] (address-of) at ./maphash.go:146:20
./maphash.go:141:7: from runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b))) (call parameter) at ./maphash.go:146:20
./maphash.go:141:7: leaking param: h
Sum64 also calls rthash which causes the *maphash.Hash to escape:
./maphash.go:157:7: parameter h leaks to {heap} with derefs=0:
./maphash.go:157:7: flow: b = h:
./maphash.go:157:7: from h.buf (dot of pointer) at ./maphash.go:159:17
./maphash.go:157:7: from h.buf (address-of) at ./maphash.go:159:21
./maphash.go:157:7: from h.buf[:h.n] (slice) at ./maphash.go:159:21
./maphash.go:157:7: from b, seed = <N> (assign-pair) at ./maphash.go:159:15
./maphash.go:157:7: flow: {heap} = b:
./maphash.go:157:7: from b[0] (dot of pointer) at ./maphash.go:159:15
./maphash.go:157:7: from &b[0] (address-of) at ./maphash.go:159:15
./maphash.go:157:7: from runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b))) (call parameter) at ./maphash.go:159:15
./maphash.go:157:7: leaking param: h
Adding //go:noescape to the declaration of runtime_memhash in hash/maphash/maphash.go:196 makes the *maphash.Hash not escape and removes the allocation.
Based on my understanding of runtime.memhash and escape analysis this should be safe, but I'm not 100% sure.
The text was updated successfully, but these errors were encountered:
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
n/a
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
No allocations for hashing.
What did you see instead?
The variable
sh
inHasher.Hash
escapes to the heap, causing an allocation.The
WriteString
causes*maphash.Hash
to escape because it callsflush
internally:flush
itself callsrthash
which callsruntime_memhash
(imported fromruntime.memhash
) which causes the arrayh.buf
and thus the*maphash.Hash
to escape:Sum64
also callsrthash
which causes the*maphash.Hash
to escape:Adding
//go:noescape
to the declaration ofruntime_memhash
inhash/maphash/maphash.go:196
makes the*maphash.Hash
not escape and removes the allocation.Based on my understanding of
runtime.memhash
and escape analysis this should be safe, but I'm not 100% sure.The text was updated successfully, but these errors were encountered: