]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: remove hmap field from maptypes
authorMartin Möhrmann <moehrmann@google.com>
Mon, 29 Jan 2018 20:40:57 +0000 (21:40 +0100)
committerMartin Möhrmann <moehrmann@google.com>
Sun, 6 May 2018 05:46:06 +0000 (05:46 +0000)
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>
src/cmd/compile/internal/gc/reflect.go
src/cmd/link/internal/ld/decodesym.go
src/reflect/type.go
src/runtime/export_test.go
src/runtime/map.go
src/runtime/map_test.go
src/runtime/type.go

index df6f8dc151c78e327e10540f2d4f604a13f65294..cbd65c2934a0666ccc87c19ee11bf8a5013c7f50 100644 (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
index 3afb38948f5833c21bdac43bf428f176c39d4512..b5025831b8c12c9261d4915e8ea5edaf81b4a47c 100644 (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:
index 021258e63bb4e1508c08b2c27db6ac6a326cb588..f432c0fcb8953239bf5a5a718462ee9b4db383f8 100644 (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
index 2575df1e3999a13ebaed614875d6f6c97a92b295..8c428dc1197f48151fef9137d9cb04a5cc8ecb5e 100644 (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
index 2ffd59cb250adf9f5b704171a4c2e10e114a4637..1926123458816e36605f5adf13cf87dd16a4acdc 100644 (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")
        }
index 5c6bbc5c31db4e9c5945c5c3fef1aa1f81d8b14c..0f20c84e77c51c997ac9473e29e26b6982de3c3c 100644 (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.
index b72f5c06d697d18844e0b392985ae5c11ac4e0ce..d44a4f38832cdd6b8bcb5a7aa55362e940b7fce9 100644 (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