aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2024-09-11 14:02:30 -0400
committerGopher Robot <gobot@golang.org>2024-10-29 20:37:41 +0000
commit0564fa6820097b29c54ac58ea55c2aa0609aa924 (patch)
treeac940ce8a4216f3bb3db4870990392f1d6b15b4b /src/runtime
parent0c934b5645c3220de21a5733c60c81e46d06d4e3 (diff)
downloadgo-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.go5
-rw-r--r--src/runtime/map_swiss.go62
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.