diff options
| author | Michael Pratt <mpratt@google.com> | 2024-09-11 14:02:30 -0400 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-10-29 20:37:41 +0000 |
| commit | 0564fa6820097b29c54ac58ea55c2aa0609aa924 (patch) | |
| tree | ac940ce8a4216f3bb3db4870990392f1d6b15b4b /src/runtime | |
| parent | 0c934b5645c3220de21a5733c60c81e46d06d4e3 (diff) | |
| download | go-0564fa6820097b29c54ac58ea55c2aa0609aa924.tar.xz | |
runtime: move mapaccess1 and mapassign to internal/runtime/maps
This enables manual inlining Map.Get/table.getWithoutKey to create a
simple fast path with no calls.
For #54766.
Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest-swissmap
Change-Id: Ic208dd4c02c7554f312b85b5fadccaf82b23545c
Reviewed-on: https://go-review.googlesource.com/c/go/+/616455
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/alg.go | 5 | ||||
| -rw-r--r-- | src/runtime/map_swiss.go | 62 |
2 files changed, 19 insertions, 48 deletions
diff --git a/src/runtime/alg.go b/src/runtime/alg.go index 07c115f74d..14ac7e8df3 100644 --- a/src/runtime/alg.go +++ b/src/runtime/alg.go @@ -256,6 +256,11 @@ func mapKeyError(t *maptype, p unsafe.Pointer) error { return mapKeyError2(t.Key, p) } +//go:linkname maps_mapKeyError internal/runtime/maps.mapKeyError +func maps_mapKeyError(t *maptype, p unsafe.Pointer) error { + return mapKeyError(t, p) +} + func mapKeyError2(t *_type, p unsafe.Pointer) error { if t.TFlag&abi.TFlagRegularMemory != 0 { return nil diff --git a/src/runtime/map_swiss.go b/src/runtime/map_swiss.go index 3ea82b547f..9556690a06 100644 --- a/src/runtime/map_swiss.go +++ b/src/runtime/map_swiss.go @@ -22,6 +22,9 @@ const ( type maptype = abi.SwissMapType +//go:linkname maps_errNilAssign internal/runtime/maps.errNilAssign +var maps_errNilAssign error = plainError("assignment to entry in nil map") + func makemap64(t *abi.SwissMapType, hint int64, m *maps.Map) *maps.Map { if int64(int(hint)) != hint { hint = 0 @@ -100,34 +103,12 @@ func alignUpPow2(n uint64) (uint64, bool) { // the key is not in the map. // NOTE: The returned pointer may keep the whole map live, so don't // hold onto it for very long. -func mapaccess1(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) unsafe.Pointer { - // TODO: concurrent checks. - if raceenabled && m != nil { - callerpc := sys.GetCallerPC() - pc := abi.FuncPCABIInternal(mapaccess1) - racereadpc(unsafe.Pointer(m), callerpc, pc) - raceReadObjectPC(t.Key, key, callerpc, pc) - } - if msanenabled && m != nil { - msanread(key, t.Key.Size_) - } - if asanenabled && m != nil { - asanread(key, t.Key.Size_) - } - - if m == nil || m.Used() == 0 { - if err := mapKeyError(t, key); err != nil { - panic(err) // see issue 23734 - } - return unsafe.Pointer(&zeroVal[0]) - } - - elem, ok := m.Get(t, key) - if !ok { - return unsafe.Pointer(&zeroVal[0]) - } - return elem -} +// +// mapaccess1 is pushed from internal/runtime/maps. We could just call it, but +// we want to avoid one layer of call. +// +//go:linkname mapaccess1 +func mapaccess1(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) unsafe.Pointer func mapaccess2(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) (unsafe.Pointer, bool) { // TODO: concurrent checks. @@ -174,26 +155,11 @@ func mapaccess2_fat(t *abi.SwissMapType, m *maps.Map, key, zero unsafe.Pointer) return e, true } -func mapassign(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) unsafe.Pointer { - // TODO: concurrent checks. - if m == nil { - panic(plainError("assignment to entry in nil map")) - } - if raceenabled { - callerpc := sys.GetCallerPC() - pc := abi.FuncPCABIInternal(mapassign) - racewritepc(unsafe.Pointer(m), callerpc, pc) - raceReadObjectPC(t.Key, key, callerpc, pc) - } - if msanenabled { - msanread(key, t.Key.Size_) - } - if asanenabled { - asanread(key, t.Key.Size_) - } - - return m.PutSlot(t, key) -} +// mapassign is pushed from internal/runtime/maps. We could just call it, but +// we want to avoid one layer of call. +// +//go:linkname mapassign +func mapassign(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) unsafe.Pointer func mapdelete(t *abi.SwissMapType, m *maps.Map, key unsafe.Pointer) { // TODO: concurrent checks. |
