aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/abi/map_noswiss.go1
-rw-r--r--src/internal/abi/map_swiss.go48
-rw-r--r--src/internal/coverage/pkid.go1
-rw-r--r--src/internal/runtime/maps/export_noswiss_test.go50
-rw-r--r--src/internal/runtime/maps/export_swiss_test.go19
-rw-r--r--src/internal/runtime/maps/export_test.go42
-rw-r--r--src/internal/runtime/maps/group.go2
-rw-r--r--src/internal/runtime/maps/internal/abi/map_swiss.go44
-rw-r--r--src/internal/runtime/maps/map_test.go9
-rw-r--r--src/internal/runtime/maps/table.go2
-rw-r--r--src/internal/runtime/maps/table_debug.go8
11 files changed, 109 insertions, 117 deletions
diff --git a/src/internal/abi/map_noswiss.go b/src/internal/abi/map_noswiss.go
index 97afd9da4a..ff8609efcf 100644
--- a/src/internal/abi/map_noswiss.go
+++ b/src/internal/abi/map_noswiss.go
@@ -52,4 +52,3 @@ func (mt *OldMapType) NeedKeyUpdate() bool { // true if we need to update key on
func (mt *OldMapType) HashMightPanic() bool { // true if hash function might panic
return mt.Flags&16 != 0
}
-
diff --git a/src/internal/abi/map_swiss.go b/src/internal/abi/map_swiss.go
index 3f58040a18..d69aefbb29 100644
--- a/src/internal/abi/map_swiss.go
+++ b/src/internal/abi/map_swiss.go
@@ -11,45 +11,31 @@ import (
// Map constants common to several packages
// runtime/runtime-gdb.py:MapTypePrinter contains its own copy
const (
- // Maximum number of key/elem pairs a bucket can hold.
- SwissMapBucketCountBits = 3 // log2 of number of elements in a bucket.
- SwissMapBucketCount = 1 << SwissMapBucketCountBits
-
- // Maximum key or elem size to keep inline (instead of mallocing per element).
- // Must fit in a uint8.
- // Note: fast map functions cannot handle big elems (bigger than MapMaxElemBytes).
- SwissMapMaxKeyBytes = 128
- SwissMapMaxElemBytes = 128 // Must fit in a uint8.
+ // Number of slots in a group.
+ SwissMapGroupSlots = 8
)
type SwissMapType struct {
Type
- Key *Type
- Elem *Type
- Bucket *Type // internal type representing a hash bucket
+ Key *Type
+ Elem *Type
+ Group *Type // internal type representing a slot group
// function for hashing keys (ptr to key, seed) -> hash
- Hasher func(unsafe.Pointer, uintptr) uintptr
- KeySize uint8 // size of key slot
- ValueSize uint8 // size of elem slot
- BucketSize uint16 // size of bucket
- Flags uint32
+ Hasher func(unsafe.Pointer, uintptr) uintptr
+ SlotSize uintptr // size of key/elem slot
+ ElemOff uintptr // offset of elem in key/elem slot
+ Flags uint32
}
-// Note: flag values must match those used in the TMAP case
-// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
-func (mt *SwissMapType) IndirectKey() bool { // store ptr to key instead of key itself
- return mt.Flags&1 != 0
-}
-func (mt *SwissMapType) IndirectElem() bool { // store ptr to elem instead of elem itself
- return mt.Flags&2 != 0
-}
-func (mt *SwissMapType) ReflexiveKey() bool { // true if k==k for all keys
- return mt.Flags&4 != 0
-}
+// Flag values
+const (
+ SwissMapNeedKeyUpdate = 1 << iota
+ SwissMapHashMightPanic
+)
+
func (mt *SwissMapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
- return mt.Flags&8 != 0
+ return mt.Flags&SwissMapNeedKeyUpdate != 0
}
func (mt *SwissMapType) HashMightPanic() bool { // true if hash function might panic
- return mt.Flags&16 != 0
+ return mt.Flags&SwissMapHashMightPanic != 0
}
-
diff --git a/src/internal/coverage/pkid.go b/src/internal/coverage/pkid.go
index d2449a65ac..f68523a348 100644
--- a/src/internal/coverage/pkid.go
+++ b/src/internal/coverage/pkid.go
@@ -52,6 +52,7 @@ var rtPkgs = [...]string{
"internal/chacha8rand",
"internal/runtime/sys",
"internal/abi",
+ "internal/runtime/maps",
"internal/runtime/math",
"internal/bytealg",
"internal/goexperiment",
diff --git a/src/internal/runtime/maps/export_noswiss_test.go b/src/internal/runtime/maps/export_noswiss_test.go
new file mode 100644
index 0000000000..32d6d13412
--- /dev/null
+++ b/src/internal/runtime/maps/export_noswiss_test.go
@@ -0,0 +1,50 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !goexperiment.swissmap
+
+// This file allows non-GOEXPERIMENT=swissmap builds (i.e., old map builds) to
+// construct a swissmap table for running the tests in this package.
+
+package maps
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+type instantiatedGroup[K comparable, V any] struct {
+ ctrls ctrlGroup
+ slots [abi.SwissMapGroupSlots]instantiatedSlot[K, V]
+}
+
+type instantiatedSlot[K comparable, V any] struct {
+ key K
+ elem V
+}
+
+func NewTestTable[K comparable, V any](length uint64) *table {
+ var m map[K]V
+ mTyp := abi.TypeOf(m)
+ omt := (*abi.OldMapType)(unsafe.Pointer(mTyp))
+
+ var grp instantiatedGroup[K, V]
+ var slot instantiatedSlot[K, V]
+
+ mt := &abi.SwissMapType{
+ Key: omt.Key,
+ Elem: omt.Elem,
+ Group: abi.TypeOf(grp),
+ Hasher: omt.Hasher,
+ SlotSize: unsafe.Sizeof(slot),
+ ElemOff: unsafe.Offsetof(slot.elem),
+ }
+ if omt.NeedKeyUpdate() {
+ mt.Flags |= abi.SwissMapNeedKeyUpdate
+ }
+ if omt.HashMightPanic() {
+ mt.Flags |= abi.SwissMapHashMightPanic
+ }
+ return newTable(mt, length)
+}
diff --git a/src/internal/runtime/maps/export_swiss_test.go b/src/internal/runtime/maps/export_swiss_test.go
new file mode 100644
index 0000000000..9a123240d5
--- /dev/null
+++ b/src/internal/runtime/maps/export_swiss_test.go
@@ -0,0 +1,19 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.swissmap
+
+package maps
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+func NewTestTable[K comparable, V any](length uint64) *table {
+ var m map[K]V
+ mTyp := abi.TypeOf(m)
+ mt := (*abi.SwissMapType)(unsafe.Pointer(mTyp))
+ return newTable(mt, length)
+}
diff --git a/src/internal/runtime/maps/export_test.go b/src/internal/runtime/maps/export_test.go
index e2512d332a..2856a7314e 100644
--- a/src/internal/runtime/maps/export_test.go
+++ b/src/internal/runtime/maps/export_test.go
@@ -6,7 +6,6 @@ package maps
import (
"internal/abi"
- sabi "internal/runtime/maps/internal/abi"
"unsafe"
)
@@ -16,41 +15,16 @@ const DebugLog = debugLog
var AlignUpPow2 = alignUpPow2
-type instantiatedGroup[K comparable, V any] struct {
- ctrls ctrlGroup
- slots [sabi.SwissMapGroupSlots]instantiatedSlot[K, V]
-}
-
-type instantiatedSlot[K comparable, V any] struct {
- key K
- elem V
+func (t *table) Type() *abi.SwissMapType {
+ return t.typ
}
-func NewTestTable[K comparable, V any](length uint64) *table {
- var m map[K]V
- mTyp := abi.TypeOf(m)
- omt := (*abi.OldMapType)(unsafe.Pointer(mTyp))
-
- var grp instantiatedGroup[K, V]
- var slot instantiatedSlot[K, V]
-
- mt := &sabi.SwissMapType{
- Key: omt.Key,
- Elem: omt.Elem,
- Group: abi.TypeOf(grp),
- Hasher: omt.Hasher,
- SlotSize: unsafe.Sizeof(slot),
- ElemOff: unsafe.Offsetof(slot.elem),
- }
- if omt.NeedKeyUpdate() {
- mt.Flags |= sabi.SwissMapNeedKeyUpdate
- }
- if omt.HashMightPanic() {
- mt.Flags |= sabi.SwissMapHashMightPanic
- }
- return newTable(mt, length)
+// Returns the start address of the groups array.
+func (t *table) GroupsStart() unsafe.Pointer {
+ return t.groups.data
}
-func (t *table) Type() *sabi.SwissMapType {
- return t.typ
+// Returns the length of the groups array.
+func (t *table) GroupsLength() uintptr {
+ return uintptr(t.groups.lengthMask + 1)
}
diff --git a/src/internal/runtime/maps/group.go b/src/internal/runtime/maps/group.go
index 822e3773ea..e03ed98c94 100644
--- a/src/internal/runtime/maps/group.go
+++ b/src/internal/runtime/maps/group.go
@@ -5,8 +5,8 @@
package maps
import (
+ "internal/abi"
"internal/goarch"
- "internal/runtime/maps/internal/abi"
"internal/runtime/sys"
"unsafe"
)
diff --git a/src/internal/runtime/maps/internal/abi/map_swiss.go b/src/internal/runtime/maps/internal/abi/map_swiss.go
deleted file mode 100644
index caa08274e1..0000000000
--- a/src/internal/runtime/maps/internal/abi/map_swiss.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2023 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package abi is a temporary copy of the swissmap abi. It will be eliminated
-// once swissmaps are integrated into the runtime.
-package abi
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-// Map constants common to several packages
-// runtime/runtime-gdb.py:MapTypePrinter contains its own copy
-const (
- // Number of slots in a group.
- SwissMapGroupSlots = 8
-)
-
-type SwissMapType struct {
- abi.Type
- Key *abi.Type
- Elem *abi.Type
- Group *abi.Type // internal type representing a slot group
- // function for hashing keys (ptr to key, seed) -> hash
- Hasher func(unsafe.Pointer, uintptr) uintptr
- SlotSize uintptr // size of key/elem slot
- ElemOff uintptr // offset of elem in key/elem slot
- Flags uint32
-}
-
-// Flag values
-const (
- SwissMapNeedKeyUpdate = 1 << iota
- SwissMapHashMightPanic
-)
-
-func (mt *SwissMapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
- return mt.Flags&SwissMapNeedKeyUpdate != 0
-}
-func (mt *SwissMapType) HashMightPanic() bool { // true if hash function might panic
- return mt.Flags&SwissMapHashMightPanic != 0
-}
diff --git a/src/internal/runtime/maps/map_test.go b/src/internal/runtime/maps/map_test.go
index 53b4a62071..d11535657b 100644
--- a/src/internal/runtime/maps/map_test.go
+++ b/src/internal/runtime/maps/map_test.go
@@ -6,8 +6,8 @@ package maps_test
import (
"fmt"
+ "internal/abi"
"internal/runtime/maps"
- "internal/runtime/maps/internal/abi"
"math"
"testing"
"unsafe"
@@ -444,4 +444,11 @@ func TestTableZeroSizeSlot(t *testing.T) {
if gotElem != elem {
t.Errorf("Get(%d) got elem %d want %d", key, gotElem, elem)
}
+
+ start := tab.GroupsStart()
+ length := tab.GroupsLength()
+ end := unsafe.Pointer(uintptr(start) + length*tab.Type().Group.Size() - 1) // inclusive to ensure we have a valid pointer
+ if uintptr(got) < uintptr(start) || uintptr(got) > uintptr(end) {
+ t.Errorf("elem address outside groups allocation; got %p want [%p, %p]", got, start, end)
+ }
}
diff --git a/src/internal/runtime/maps/table.go b/src/internal/runtime/maps/table.go
index 3516b92fba..2c13be8468 100644
--- a/src/internal/runtime/maps/table.go
+++ b/src/internal/runtime/maps/table.go
@@ -6,7 +6,7 @@
package maps
import (
- "internal/runtime/maps/internal/abi"
+ "internal/abi"
"unsafe"
)
diff --git a/src/internal/runtime/maps/table_debug.go b/src/internal/runtime/maps/table_debug.go
index 7170fb68fe..b800858e55 100644
--- a/src/internal/runtime/maps/table_debug.go
+++ b/src/internal/runtime/maps/table_debug.go
@@ -6,7 +6,7 @@
package maps
import (
- sabi "internal/runtime/maps/internal/abi"
+ "internal/abi"
"unsafe"
)
@@ -24,7 +24,7 @@ func (t *table) checkInvariants() {
var empty uint64
for i := uint64(0); i <= t.groups.lengthMask; i++ {
g := t.groups.group(i)
- for j := uint32(0); j < sabi.SwissMapGroupSlots; j++ {
+ for j := uint32(0); j < abi.SwissMapGroupSlots; j++ {
c := g.ctrls().get(j)
switch {
case c == ctrlDeleted:
@@ -60,7 +60,7 @@ func (t *table) checkInvariants() {
panic("invariant failed: found mismatched used slot count")
}
- growthLeft := (t.capacity*maxAvgGroupLoad)/sabi.SwissMapGroupSlots - t.used - deleted
+ growthLeft := (t.capacity*maxAvgGroupLoad)/abi.SwissMapGroupSlots - t.used - deleted
if growthLeft != t.growthLeft {
print("invariant failed: found ", t.growthLeft, " growthLeft, but expected ", growthLeft, "\n")
t.Print()
@@ -93,7 +93,7 @@ func (t *table) Print() {
g := t.groups.group(i)
ctrls := g.ctrls()
- for j := uint32(0); j < sabi.SwissMapGroupSlots; j++ {
+ for j := uint32(0); j < abi.SwissMapGroupSlots; j++ {
print("\t\t\tslot ", j, "\n")
c := ctrls.get(j)