1
0
mirror of https://github.com/golang/go synced 2024-10-02 00:28:33 -06:00

runtime: remove hmap field from maptypes

The hmap field in the maptype is only used by the runtime to check the sizes of
the hmap structure created by the compiler and runtime agree.

Comments are already present about the hmap structure definitions in the
compiler and runtime needing to be in sync.

Add a test that checks the runtimes hmap size is as expected to detect
when the compilers and runtimes hmap sizes diverge instead of checking
this at runtime when a map is created.

Change-Id: I974945ebfdb66883a896386a17bbcae62a18cf2a
Reviewed-on: https://go-review.googlesource.com/91796
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Martin Möhrmann 2018-01-29 21:40:57 +01:00
parent b9a59d9f2e
commit 4ebc67d334
7 changed files with 15 additions and 16 deletions

View File

@ -1247,12 +1247,10 @@ func dtypesym(t *types.Type) *obj.LSym {
s1 := dtypesym(t.Key())
s2 := dtypesym(t.Elem())
s3 := dtypesym(bmap(t))
s4 := dtypesym(hmap(t))
ot = dcommontype(lsym, t)
ot = dsymptr(lsym, ot, s1, 0)
ot = dsymptr(lsym, ot, s2, 0)
ot = dsymptr(lsym, ot, s3, 0)
ot = dsymptr(lsym, ot, s4, 0)
if t.Key().Width > MAXKEYSIZE {
ot = duint8(lsym, ot, uint8(Widthptr))
ot = duint8(lsym, ot, 1) // indirect

View File

@ -359,7 +359,7 @@ func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
case kindChan: // reflect.chanType
off += 2 * arch.PtrSize
case kindMap: // reflect.mapType
off += 4*arch.PtrSize + 8
off += 3*arch.PtrSize + 8
case kindInterface: // reflect.interfaceType
off += 3 * arch.PtrSize
default:

View File

@ -398,7 +398,6 @@ type mapType struct {
key *rtype // map key type
elem *rtype // map element (value) type
bucket *rtype // internal bucket structure
hmap *rtype // internal map header
keysize uint8 // size of key slot
indirectkey uint8 // store ptr to key instead of key itself
valuesize uint8 // size of value slot

View File

@ -376,6 +376,8 @@ func (rw *RWMutex) Unlock() {
rw.rw.unlock()
}
const RuntimeHmapSize = unsafe.Sizeof(hmap{})
func MapBucketsCount(m map[int]int) int {
h := *(**hmap)(unsafe.Pointer(&m))
return 1 << h.B

View File

@ -296,13 +296,6 @@ func makemap_small() *hmap {
// If h != nil, the map can be created directly in h.
// If h.buckets != nil, bucket pointed to can be used as the first bucket.
func makemap(t *maptype, hint int, h *hmap) *hmap {
// The size of hmap should be 48 bytes on 64 bit
// and 28 bytes on 32 bit platforms.
if sz := unsafe.Sizeof(hmap{}); sz != 8+5*sys.PtrSize {
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
throw("bad hmap size")
}
if hint < 0 || hint > int(maxSliceCap(t.bucket.size)) {
hint = 0
}
@ -1150,10 +1143,6 @@ func ismapkey(t *_type) bool {
//go:linkname reflect_makemap reflect.makemap
func reflect_makemap(t *maptype, cap int) *hmap {
// Check invariants and reflects math.
if sz := unsafe.Sizeof(hmap{}); sz != t.hmap.size {
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
throw("bad hmap size")
}
if !ismapkey(t.key) {
throw("runtime.reflect_makemap: unsupported map key type")
}

View File

@ -9,6 +9,7 @@ import (
"math"
"reflect"
"runtime"
"runtime/internal/sys"
"sort"
"strconv"
"strings"
@ -16,6 +17,17 @@ import (
"testing"
)
func TestHmapSize(t *testing.T) {
// The structure of hmap is defined in runtime/map.go
// and in cmd/compile/internal/gc/reflect.go and must be in sync.
// The size of hmap should be 48 bytes on 64 bit and 28 bytes on 32 bit platforms.
var hmapSize = uintptr(8 + 5*sys.PtrSize)
if runtime.RuntimeHmapSize != hmapSize {
t.Errorf("sizeof(runtime.hmap{})==%d, want %d", runtime.RuntimeHmapSize, hmapSize)
}
}
// negative zero is a good test because:
// 1) 0 and -0 are equal, yet have distinct representations.
// 2) 0 is represented as all zeros, -0 isn't.

View File

@ -350,7 +350,6 @@ type maptype struct {
key *_type
elem *_type
bucket *_type // internal type representing a hash bucket
hmap *_type // internal type representing a hmap
keysize uint8 // size of key slot
indirectkey bool // store ptr to key instead of key itself
valuesize uint8 // size of value slot