Skip to content

Commit 4ebc67d

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent b9a59d9 commit 4ebc67d

File tree

7 files changed

+15
-16
lines changed

7 files changed

+15
-16
lines changed

src/cmd/compile/internal/gc/reflect.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,12 +1247,10 @@ func dtypesym(t *types.Type) *obj.LSym {
12471247
s1 := dtypesym(t.Key())
12481248
s2 := dtypesym(t.Elem())
12491249
s3 := dtypesym(bmap(t))
1250-
s4 := dtypesym(hmap(t))
12511250
ot = dcommontype(lsym, t)
12521251
ot = dsymptr(lsym, ot, s1, 0)
12531252
ot = dsymptr(lsym, ot, s2, 0)
12541253
ot = dsymptr(lsym, ot, s3, 0)
1255-
ot = dsymptr(lsym, ot, s4, 0)
12561254
if t.Key().Width > MAXKEYSIZE {
12571255
ot = duint8(lsym, ot, uint8(Widthptr))
12581256
ot = duint8(lsym, ot, 1) // indirect

src/cmd/link/internal/ld/decodesym.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
359359
case kindChan: // reflect.chanType
360360
off += 2 * arch.PtrSize
361361
case kindMap: // reflect.mapType
362-
off += 4*arch.PtrSize + 8
362+
off += 3*arch.PtrSize + 8
363363
case kindInterface: // reflect.interfaceType
364364
off += 3 * arch.PtrSize
365365
default:

src/reflect/type.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ type mapType struct {
398398
key *rtype // map key type
399399
elem *rtype // map element (value) type
400400
bucket *rtype // internal bucket structure
401-
hmap *rtype // internal map header
402401
keysize uint8 // size of key slot
403402
indirectkey uint8 // store ptr to key instead of key itself
404403
valuesize uint8 // size of value slot

src/runtime/export_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ func (rw *RWMutex) Unlock() {
376376
rw.rw.unlock()
377377
}
378378

379+
const RuntimeHmapSize = unsafe.Sizeof(hmap{})
380+
379381
func MapBucketsCount(m map[int]int) int {
380382
h := *(**hmap)(unsafe.Pointer(&m))
381383
return 1 << h.B

src/runtime/map.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,6 @@ func makemap_small() *hmap {
296296
// If h != nil, the map can be created directly in h.
297297
// If h.buckets != nil, bucket pointed to can be used as the first bucket.
298298
func makemap(t *maptype, hint int, h *hmap) *hmap {
299-
// The size of hmap should be 48 bytes on 64 bit
300-
// and 28 bytes on 32 bit platforms.
301-
if sz := unsafe.Sizeof(hmap{}); sz != 8+5*sys.PtrSize {
302-
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
303-
throw("bad hmap size")
304-
}
305-
306299
if hint < 0 || hint > int(maxSliceCap(t.bucket.size)) {
307300
hint = 0
308301
}
@@ -1150,10 +1143,6 @@ func ismapkey(t *_type) bool {
11501143
//go:linkname reflect_makemap reflect.makemap
11511144
func reflect_makemap(t *maptype, cap int) *hmap {
11521145
// Check invariants and reflects math.
1153-
if sz := unsafe.Sizeof(hmap{}); sz != t.hmap.size {
1154-
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
1155-
throw("bad hmap size")
1156-
}
11571146
if !ismapkey(t.key) {
11581147
throw("runtime.reflect_makemap: unsupported map key type")
11591148
}

src/runtime/map_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,25 @@ import (
99
"math"
1010
"reflect"
1111
"runtime"
12+
"runtime/internal/sys"
1213
"sort"
1314
"strconv"
1415
"strings"
1516
"sync"
1617
"testing"
1718
)
1819

20+
func TestHmapSize(t *testing.T) {
21+
// The structure of hmap is defined in runtime/map.go
22+
// and in cmd/compile/internal/gc/reflect.go and must be in sync.
23+
// The size of hmap should be 48 bytes on 64 bit and 28 bytes on 32 bit platforms.
24+
var hmapSize = uintptr(8 + 5*sys.PtrSize)
25+
if runtime.RuntimeHmapSize != hmapSize {
26+
t.Errorf("sizeof(runtime.hmap{})==%d, want %d", runtime.RuntimeHmapSize, hmapSize)
27+
}
28+
29+
}
30+
1931
// negative zero is a good test because:
2032
// 1) 0 and -0 are equal, yet have distinct representations.
2133
// 2) 0 is represented as all zeros, -0 isn't.

src/runtime/type.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,6 @@ type maptype struct {
350350
key *_type
351351
elem *_type
352352
bucket *_type // internal type representing a hash bucket
353-
hmap *_type // internal type representing a hmap
354353
keysize uint8 // size of key slot
355354
indirectkey bool // store ptr to key instead of key itself
356355
valuesize uint8 // size of value slot

0 commit comments

Comments
 (0)