aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorArsenySamoylov <samoylov.arseny@gmail.com>2026-01-13 13:06:28 +0300
committerGopher Robot <gobot@golang.org>2026-02-02 13:24:26 -0800
commit62d08234b797806796af0d51051f2e13caa42e2a (patch)
treef37768122ffc5e31fddd6c47548ccf776fd69c92 /src/internal
parent35abaf75c35adc9b22038885781b8be70a8476e0 (diff)
downloadgo-62d08234b797806796af0d51051f2e13caa42e2a.tar.xz
internal/maps,cmd/compile/internal/walk: replace calls to mapaccess1* with mapaccess2*
mapaccess1* and mapaccess2* functions share the same implementation and differ only in whether the boolean "found" is returned. This change replaces mapaccess1* calls with mapaccess2*. We can do this transparently, since the call site can safely discard the second (boolean) result. Ideally, mapacces1* functions could be removed entirely, but this change keeps them as thin wrappers for compatibility. Fixes #73196 Change-Id: I07c3423d22ed1095ac3666d00e134c2747b2f9c1 Reviewed-on: https://go-review.googlesource.com/c/go/+/736020 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/runtime/maps/runtime.go78
-rw-r--r--src/internal/runtime/maps/runtime_fast32.go68
-rw-r--r--src/internal/runtime/maps/runtime_fast64.go68
-rw-r--r--src/internal/runtime/maps/runtime_faststr.go58
4 files changed, 9 insertions, 263 deletions
diff --git a/src/internal/runtime/maps/runtime.go b/src/internal/runtime/maps/runtime.go
index 8bba23f070..039f4f0510 100644
--- a/src/internal/runtime/maps/runtime.go
+++ b/src/internal/runtime/maps/runtime.go
@@ -38,9 +38,6 @@ func newobject(typ *abi.Type) unsafe.Pointer
//go:linkname errNilAssign
var errNilAssign error
-// Pull from runtime. It is important that is this the exact same copy as the
-// runtime because runtime.mapaccess1_fat compares the returned pointer with
-// &runtime.zeroVal[0].
// TODO: move zeroVal to internal/abi?
//
//go:linkname zeroVal runtime.zeroVal
@@ -54,84 +51,15 @@ var zeroVal [abi.ZeroValSize]byte
//
//go:linkname runtime_mapaccess1 runtime.mapaccess1
func runtime_mapaccess1(typ *abi.MapType, m *Map, key unsafe.Pointer) unsafe.Pointer {
- if race.Enabled && m != nil {
- callerpc := sys.GetCallerPC()
- pc := abi.FuncPCABIInternal(runtime_mapaccess1)
- race.ReadPC(unsafe.Pointer(m), callerpc, pc)
- race.ReadObjectPC(typ.Key, key, callerpc, pc)
- }
- if msan.Enabled && m != nil {
- msan.Read(key, typ.Key.Size_)
- }
- if asan.Enabled && m != nil {
- asan.Read(key, typ.Key.Size_)
- }
-
- if m == nil || m.Used() == 0 {
- if err := mapKeyError(typ, key); err != nil {
- panic(err) // see issue 23734
- }
- return unsafe.Pointer(&zeroVal[0])
- }
-
- if m.writing != 0 {
- fatal("concurrent map read and map write")
- }
-
- hash := typ.Hasher(key, m.seed)
-
- if m.dirLen <= 0 {
- _, elem, ok := m.getWithKeySmall(typ, hash, key)
- if !ok {
- return unsafe.Pointer(&zeroVal[0])
- }
- return elem
- }
-
- // Select table.
- idx := m.directoryIndex(hash)
- t := m.directoryAt(idx)
-
- // Probe table.
- seq := makeProbeSeq(h1(hash), t.groups.lengthMask)
- h2Hash := h2(hash)
- for ; ; seq = seq.next() {
- g := t.groups.group(typ, seq.offset)
-
- match := g.ctrls().matchH2(h2Hash)
-
- for match != 0 {
- i := match.first()
-
- slotKey := g.key(typ, i)
- slotKeyOrig := slotKey
- if typ.IndirectKey() {
- slotKey = *((*unsafe.Pointer)(slotKey))
- }
- if typ.Key.Equal(key, slotKey) {
- slotElem := unsafe.Pointer(uintptr(slotKeyOrig) + typ.ElemOff)
- if typ.IndirectElem() {
- slotElem = *((*unsafe.Pointer)(slotElem))
- }
- return slotElem
- }
- match = match.removeFirst()
- }
-
- match = g.ctrls().matchEmpty()
- if match != 0 {
- // Finding an empty slot means we've reached the end of
- // the probe sequence.
- return unsafe.Pointer(&zeroVal[0])
- }
- }
+ p, _ := runtime_mapaccess2(typ, m, key)
+ return p
}
//go:linkname runtime_mapaccess2 runtime.mapaccess2
func runtime_mapaccess2(typ *abi.MapType, m *Map, key unsafe.Pointer) (unsafe.Pointer, bool) {
if race.Enabled && m != nil {
callerpc := sys.GetCallerPC()
- pc := abi.FuncPCABIInternal(runtime_mapaccess1)
+ pc := abi.FuncPCABIInternal(runtime_mapaccess2)
race.ReadPC(unsafe.Pointer(m), callerpc, pc)
race.ReadObjectPC(typ.Key, key, callerpc, pc)
}
diff --git a/src/internal/runtime/maps/runtime_fast32.go b/src/internal/runtime/maps/runtime_fast32.go
index d5be04afd4..a185dca510 100644
--- a/src/internal/runtime/maps/runtime_fast32.go
+++ b/src/internal/runtime/maps/runtime_fast32.go
@@ -13,72 +13,8 @@ import (
//go:linkname runtime_mapaccess1_fast32 runtime.mapaccess1_fast32
func runtime_mapaccess1_fast32(typ *abi.MapType, m *Map, key uint32) unsafe.Pointer {
- if race.Enabled && m != nil {
- callerpc := sys.GetCallerPC()
- pc := abi.FuncPCABIInternal(runtime_mapaccess1_fast32)
- race.ReadPC(unsafe.Pointer(m), callerpc, pc)
- }
-
- if m == nil || m.Used() == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
-
- if m.writing != 0 {
- fatal("concurrent map read and map write")
- return nil
- }
-
- if m.dirLen == 0 {
- g := groupReference{
- data: m.dirPtr,
- }
- full := g.ctrls().matchFull()
- slotKey := g.key(typ, 0)
- slotSize := typ.SlotSize
- for full != 0 {
- if key == *(*uint32)(slotKey) && full.lowestSet() {
- slotElem := unsafe.Pointer(uintptr(slotKey) + typ.ElemOff)
- return slotElem
- }
- slotKey = unsafe.Pointer(uintptr(slotKey) + slotSize)
- full = full.shiftOutLowest()
- }
- return unsafe.Pointer(&zeroVal[0])
- }
-
- k := key
- hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
-
- // Select table.
- idx := m.directoryIndex(hash)
- t := m.directoryAt(idx)
-
- // Probe table.
- seq := makeProbeSeq(h1(hash), t.groups.lengthMask)
- h2Hash := h2(hash)
- for ; ; seq = seq.next() {
- g := t.groups.group(typ, seq.offset)
-
- match := g.ctrls().matchH2(h2Hash)
-
- for match != 0 {
- i := match.first()
-
- slotKey := g.key(typ, i)
- if key == *(*uint32)(slotKey) {
- slotElem := unsafe.Pointer(uintptr(slotKey) + typ.ElemOff)
- return slotElem
- }
- match = match.removeFirst()
- }
-
- match = g.ctrls().matchEmpty()
- if match != 0 {
- // Finding an empty slot means we've reached the end of
- // the probe sequence.
- return unsafe.Pointer(&zeroVal[0])
- }
- }
+ p, _ := runtime_mapaccess2_fast32(typ, m, key)
+ return p
}
//go:linkname runtime_mapaccess2_fast32 runtime.mapaccess2_fast32
diff --git a/src/internal/runtime/maps/runtime_fast64.go b/src/internal/runtime/maps/runtime_fast64.go
index 2bee2d4be0..6e1e0ea25d 100644
--- a/src/internal/runtime/maps/runtime_fast64.go
+++ b/src/internal/runtime/maps/runtime_fast64.go
@@ -13,72 +13,8 @@ import (
//go:linkname runtime_mapaccess1_fast64 runtime.mapaccess1_fast64
func runtime_mapaccess1_fast64(typ *abi.MapType, m *Map, key uint64) unsafe.Pointer {
- if race.Enabled && m != nil {
- callerpc := sys.GetCallerPC()
- pc := abi.FuncPCABIInternal(runtime_mapaccess1_fast64)
- race.ReadPC(unsafe.Pointer(m), callerpc, pc)
- }
-
- if m == nil || m.Used() == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
-
- if m.writing != 0 {
- fatal("concurrent map read and map write")
- return nil
- }
-
- if m.dirLen == 0 {
- g := groupReference{
- data: m.dirPtr,
- }
- full := g.ctrls().matchFull()
- slotKey := g.key(typ, 0)
- slotSize := typ.SlotSize
- for full != 0 {
- if key == *(*uint64)(slotKey) && full.lowestSet() {
- slotElem := unsafe.Pointer(uintptr(slotKey) + 8)
- return slotElem
- }
- slotKey = unsafe.Pointer(uintptr(slotKey) + slotSize)
- full = full.shiftOutLowest()
- }
- return unsafe.Pointer(&zeroVal[0])
- }
-
- k := key
- hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
-
- // Select table.
- idx := m.directoryIndex(hash)
- t := m.directoryAt(idx)
-
- // Probe table.
- seq := makeProbeSeq(h1(hash), t.groups.lengthMask)
- h2Hash := h2(hash)
- for ; ; seq = seq.next() {
- g := t.groups.group(typ, seq.offset)
-
- match := g.ctrls().matchH2(h2Hash)
-
- for match != 0 {
- i := match.first()
-
- slotKey := g.key(typ, i)
- if key == *(*uint64)(slotKey) {
- slotElem := unsafe.Pointer(uintptr(slotKey) + 8)
- return slotElem
- }
- match = match.removeFirst()
- }
-
- match = g.ctrls().matchEmpty()
- if match != 0 {
- // Finding an empty slot means we've reached the end of
- // the probe sequence.
- return unsafe.Pointer(&zeroVal[0])
- }
- }
+ p, _ := runtime_mapaccess2_fast64(typ, m, key)
+ return p
}
//go:linkname runtime_mapaccess2_fast64 runtime.mapaccess2_fast64
diff --git a/src/internal/runtime/maps/runtime_faststr.go b/src/internal/runtime/maps/runtime_faststr.go
index 374468b664..4a50c46106 100644
--- a/src/internal/runtime/maps/runtime_faststr.go
+++ b/src/internal/runtime/maps/runtime_faststr.go
@@ -99,62 +99,8 @@ func stringPtr(s string) unsafe.Pointer {
//go:linkname runtime_mapaccess1_faststr runtime.mapaccess1_faststr
func runtime_mapaccess1_faststr(typ *abi.MapType, m *Map, key string) unsafe.Pointer {
- if race.Enabled && m != nil {
- callerpc := sys.GetCallerPC()
- pc := abi.FuncPCABIInternal(runtime_mapaccess1_faststr)
- race.ReadPC(unsafe.Pointer(m), callerpc, pc)
- }
-
- if m == nil || m.Used() == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
-
- if m.writing != 0 {
- fatal("concurrent map read and map write")
- return nil
- }
-
- if m.dirLen <= 0 {
- elem := m.getWithoutKeySmallFastStr(typ, key)
- if elem == nil {
- return unsafe.Pointer(&zeroVal[0])
- }
- return elem
- }
-
- k := key
- hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&k)), m.seed)
-
- // Select table.
- idx := m.directoryIndex(hash)
- t := m.directoryAt(idx)
-
- // Probe table.
- seq := makeProbeSeq(h1(hash), t.groups.lengthMask)
- h2Hash := h2(hash)
- for ; ; seq = seq.next() {
- g := t.groups.group(typ, seq.offset)
-
- match := g.ctrls().matchH2(h2Hash)
-
- for match != 0 {
- i := match.first()
-
- slotKey := g.key(typ, i)
- if key == *(*string)(slotKey) {
- slotElem := unsafe.Pointer(uintptr(slotKey) + 2*goarch.PtrSize)
- return slotElem
- }
- match = match.removeFirst()
- }
-
- match = g.ctrls().matchEmpty()
- if match != 0 {
- // Finding an empty slot means we've reached the end of
- // the probe sequence.
- return unsafe.Pointer(&zeroVal[0])
- }
- }
+ p, _ := runtime_mapaccess2_faststr(typ, m, key)
+ return p
}
//go:linkname runtime_mapaccess2_faststr runtime.mapaccess2_faststr