]> Cypherpunks repositories - gostls13.git/commitdiff
Revert "cmd/compile: move hiter, hmap, and scase definitions into builtin.go"
authorMatthew Dempsky <mdempsky@google.com>
Tue, 23 Feb 2016 07:46:01 +0000 (07:46 +0000)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 23 Feb 2016 19:42:52 +0000 (19:42 +0000)
This reverts commit f28bbb776a050cc3edca2bbe1241d81217a7a251.

Change-Id: I82fb81dcff3ddcaefef72949f1ef3a41bcd22301
Reviewed-on: https://go-review.googlesource.com/19849
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
14 files changed:
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/builtin/runtime.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/range.go
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/walk.go
src/reflect/type.go
src/runtime/hashmap.go
src/runtime/runtime2.go
src/runtime/select.go
src/runtime/type.go

index d1827ef0fea6b0bbddbac7c0184cb711efbbc880..4a6e56fe47255232db3bdfc4cd9830fe29a303b2 100644 (file)
@@ -4,10 +4,6 @@ package gc
 
 const runtimeimport = "" +
        "package runtime safe\n" +
-       "type @\"\".hbucket uint8\n" +
-       "type @\"\".hmap struct { @\"\".count int; @\"\".flags uint8; B uint8; @\"\".hash0 uint32; @\"\".buckets *@\"\".hbucket; @\"\".oldbuckets *@\"\".hbucket; @\"\".nevacuate uintptr; @\"\".overflow *[2]*[]*@\"\".hbucket }\n" +
-       "type @\"\".hiter struct { @\"\".key *byte; @\"\".value *byte; @\"\".t *byte; @\"\".h *@\"\".hmap; @\"\".buckets *@\"\".hbucket; @\"\".bptr *@\"\".hbucket; @\"\".overflow [2]*[]*@\"\".hbucket; @\"\".startBucket uintptr; @\"\".offset uint8; @\"\".wrapped bool; B uint8; @\"\".i uint8; @\"\".bucket uintptr; @\"\".checkBucket uintptr }\n" +
-       "type @\"\".scase struct { @\"\".elem *byte; @\"\".c *byte; @\"\".pc uintptr; @\"\".kind uint16; @\"\".so uint16; @\"\".receivedp *bool; @\"\".releasetime int64 }\n" +
        "func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n" +
        "func @\"\".panicindex ()\n" +
        "func @\"\".panicslice ()\n" +
@@ -70,7 +66,7 @@ const runtimeimport = "" +
        "func @\"\".panicdottype (@\"\".have·1 *byte, @\"\".want·2 *byte, @\"\".iface·3 *byte)\n" +
        "func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
        "func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" +
-       "func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64, @\"\".mapbuf·4 *@\"\".hmap, @\"\".bucketbuf·5 *any) (@\"\".hmap·1 map[any]any)\n" +
+       "func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64, @\"\".mapbuf·4 *any, @\"\".bucketbuf·5 *any) (@\"\".hmap·1 map[any]any)\n" +
        "func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n" +
        "func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n" +
        "func @\"\".mapaccess1_fast64 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n" +
@@ -80,9 +76,9 @@ const runtimeimport = "" +
        "func @\"\".mapaccess2_fast64 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n" +
        "func @\"\".mapaccess2_faststr (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n" +
        "func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any, @\"\".val·4 *any)\n" +
-       "func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *@\"\".hiter)\n" +
+       "func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n" +
        "func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any)\n" +
-       "func @\"\".mapiternext (@\"\".hiter·1 *@\"\".hiter)\n" +
+       "func @\"\".mapiternext (@\"\".hiter·1 *any)\n" +
        "func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n" +
        "func @\"\".chanrecv1 (@\"\".chanType·1 *byte, @\"\".hchan·2 <-chan any, @\"\".elem·3 *any)\n" +
        "func @\"\".chanrecv2 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (? bool)\n" +
index e067d0bfa8a636c96bf3bef5e0aaded29d7551ef..0fe6242e74071a1ee389f35835e9361be1c243e6 100644 (file)
@@ -12,49 +12,6 @@ package runtime
 
 // emitted by compiler, not referred to by go programs
 
-type hbucket byte // placeholder
-
-// Changes here must also be made in src/runtime/hashmap.go.
-type hmap struct {
-       count      int
-       flags      uint8
-       B          uint8
-       hash0      uint32
-       buckets    *hbucket
-       oldbuckets *hbucket
-       nevacuate  uintptr
-       overflow   *[2]*[]*hbucket
-}
-
-// Changes here must also be made in src/runtime/hashmap.go.
-type hiter struct {
-       key         *byte // field name known to walkrange
-       value       *byte // field name known to walkrange
-       t           *byte // *maptype
-       h           *hmap
-       buckets     *hbucket
-       bptr        *hbucket
-       overflow    [2]*[]*hbucket
-       startBucket uintptr
-       offset      uint8
-       wrapped     bool
-       B           uint8
-       i           uint8
-       bucket      uintptr
-       checkBucket uintptr
-}
-
-// Changes here must also be made in src/runtime/select.go.
-type scase struct {
-       elem        *byte
-       c           *byte
-       pc          uintptr
-       kind        uint16
-       so          uint16
-       receivedp   *bool
-       releasetime int64
-}
-
 func newobject(typ *byte) *any
 func panicindex()
 func panicslice()
@@ -128,7 +85,7 @@ func ifaceeq(i1 any, i2 any) (ret bool)
 func efaceeq(i1 any, i2 any) (ret bool)
 
 // *byte is really *runtime.Type
-func makemap(mapType *byte, hint int64, mapbuf *hmap, bucketbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
 func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
 func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
 func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
@@ -138,9 +95,9 @@ func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres
 func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
 func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
 func mapassign1(mapType *byte, hmap map[any]any, key *any, val *any)
-func mapiterinit(mapType *byte, hmap map[any]any, hiter *hiter)
+func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
 func mapdelete(mapType *byte, hmap map[any]any, key *any)
-func mapiternext(hiter *hiter)
+func mapiternext(hiter *any)
 
 // *byte is really *runtime.Type
 func makechan(chanType *byte, hint int64) (hchan chan any)
index 91035b5d0739b41c798e172bc1339ca1e23ed47f..c0a1170839ab2a4704692ce37191d64dc95bdba2 100644 (file)
@@ -647,6 +647,14 @@ func typefmt(t *Type, flag int) string {
                                return fmt.Sprintf("map.bucket[%v]%v", t.Map.Down, t.Map.Type)
                        }
 
+                       if t.Map.Hmap == t {
+                               return fmt.Sprintf("map.hdr[%v]%v", t.Map.Down, t.Map.Type)
+                       }
+
+                       if t.Map.Hiter == t {
+                               return fmt.Sprintf("map.iter[%v]%v", t.Map.Down, t.Map.Type)
+                       }
+
                        Yyerror("unknown internal map type")
                }
 
index cdb976999f6c75e01f03489f21db2ae121a2091c..1523c5efb3f14218b82af2ca50b4bb52cd15712e 100644 (file)
@@ -191,7 +191,9 @@ type Type struct {
 
        // TMAP
        Bucket *Type // internal type representing a hash bucket
-       Map    *Type // link from hash bucket type back to the map type.
+       Hmap   *Type // internal type representing a Hmap (map header object)
+       Hiter  *Type // internal type representing hash iterator state
+       Map    *Type // link from the above 3 internal types back to the map type.
 
        Maplineno   int32 // first use of TFORW as map key
        Embedlineno int32 // first use of TFORW as embedded type
index 8c2eca20d4a133f635b5891a069c66c8cb45e63e..4386bcfeed27af92732a4e708695faed34dab49b 100644 (file)
@@ -223,28 +223,24 @@ func walkrange(n *Node) {
        case TMAP:
                ha := a
 
-               th := syslook("hiter", 0).Type
-               keytype := t.Down
-               valtype := t.Type
-
+               th := hiter(t)
                hit := prealloc[n]
                hit.Type = th
                n.Left = nil
-
-               // These depend on hiter's field names.  See builtin/runtime.go:hiter.
-               keyname := newname(Pkglookup("key", Runtimepkg))
-               valname := newname(Pkglookup("value", Runtimepkg))
+               keyname := newname(th.Type.Sym)      // depends on layout of iterator struct.  See reflect.go:hiter
+               valname := newname(th.Type.Down.Sym) // ditto
 
                fn := syslook("mapiterinit", 1)
-               substArgTypes(fn, keytype, valtype)
+
+               substArgTypes(fn, t.Down, t.Type, th)
                init = list(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
                n.Left = Nod(ONE, Nod(ODOT, hit, keyname), nodnil())
 
-               n.Right = mkcall("mapiternext", nil, nil, Nod(OADDR, hit, nil))
+               fn = syslook("mapiternext", 1)
+               substArgTypes(fn, th)
+               n.Right = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
 
                key := Nod(ODOT, hit, keyname)
-               key = Nod(OCONVNOP, key, nil)
-               key.Type = Ptrto(keytype)
                key = Nod(OIND, key, nil)
                if v1 == nil {
                        body = nil
@@ -252,8 +248,6 @@ func walkrange(n *Node) {
                        body = list1(Nod(OAS, v1, key))
                } else {
                        val := Nod(ODOT, hit, valname)
-                       val = Nod(OCONVNOP, val, nil)
-                       val.Type = Ptrto(valtype)
                        val = Nod(OIND, val, nil)
                        a := Nod(OAS2, nil, nil)
                        a.List = list(list1(v1), v2)
index 369d015f19e045d9d49199edea8b861b3a1ec521..8693e3c112905f2fd59cf79ab19304976e5f59d7 100644 (file)
@@ -149,6 +149,92 @@ func mapbucket(t *Type) *Type {
        return bucket
 }
 
+// Builds a type representing a Hmap structure for the given map type.
+// Make sure this stays in sync with ../../../../runtime/hashmap.go!
+func hmap(t *Type) *Type {
+       if t.Hmap != nil {
+               return t.Hmap
+       }
+
+       bucket := mapbucket(t)
+       var field [8]*Type
+       field[0] = makefield("count", Types[TINT])
+       field[1] = makefield("flags", Types[TUINT8])
+       field[2] = makefield("B", Types[TUINT8])
+       field[3] = makefield("hash0", Types[TUINT32])
+       field[4] = makefield("buckets", Ptrto(bucket))
+       field[5] = makefield("oldbuckets", Ptrto(bucket))
+       field[6] = makefield("nevacuate", Types[TUINTPTR])
+       field[7] = makefield("overflow", Types[TUNSAFEPTR])
+
+       h := typ(TSTRUCT)
+       h.Noalg = true
+       h.Local = t.Local
+       h.Type = field[0]
+       for n := int32(0); n < int32(len(field)-1); n++ {
+               field[n].Down = field[n+1]
+       }
+       field[len(field)-1].Down = nil
+       dowidth(h)
+       t.Hmap = h
+       h.Map = t
+       return h
+}
+
+func hiter(t *Type) *Type {
+       if t.Hiter != nil {
+               return t.Hiter
+       }
+
+       // build a struct:
+       // hiter {
+       //    key *Key
+       //    val *Value
+       //    t *MapType
+       //    h *Hmap
+       //    buckets *Bucket
+       //    bptr *Bucket
+       //    overflow0 unsafe.Pointer
+       //    overflow1 unsafe.Pointer
+       //    startBucket uintptr
+       //    stuff uintptr
+       //    bucket uintptr
+       //    checkBucket uintptr
+       // }
+       // must match ../../../../runtime/hashmap.go:hiter.
+       var field [12]*Type
+       field[0] = makefield("key", Ptrto(t.Down))
+
+       field[1] = makefield("val", Ptrto(t.Type))
+       field[2] = makefield("t", Ptrto(Types[TUINT8]))
+       field[3] = makefield("h", Ptrto(hmap(t)))
+       field[4] = makefield("buckets", Ptrto(mapbucket(t)))
+       field[5] = makefield("bptr", Ptrto(mapbucket(t)))
+       field[6] = makefield("overflow0", Types[TUNSAFEPTR])
+       field[7] = makefield("overflow1", Types[TUNSAFEPTR])
+       field[8] = makefield("startBucket", Types[TUINTPTR])
+       field[9] = makefield("stuff", Types[TUINTPTR]) // offset+wrapped+B+I
+       field[10] = makefield("bucket", Types[TUINTPTR])
+       field[11] = makefield("checkBucket", Types[TUINTPTR])
+
+       // build iterator struct holding the above fields
+       i := typ(TSTRUCT)
+
+       i.Noalg = true
+       i.Type = field[0]
+       for n := int32(0); n < int32(len(field)-1); n++ {
+               field[n].Down = field[n+1]
+       }
+       field[len(field)-1].Down = nil
+       dowidth(i)
+       if i.Width != int64(12*Widthptr) {
+               Yyerror("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
+       }
+       t.Hiter = i
+       i.Map = t
+       return i
+}
+
 // f is method type, with receiver.
 // return function type, receiver as first argument (or not).
 func methodfunc(f *Type, receiver *Type) *Type {
@@ -1026,11 +1112,13 @@ ok:
 
                s2 := dtypesym(t.Type)
                s3 := dtypesym(mapbucket(t))
+               s4 := dtypesym(hmap(t))
                ot = dcommontype(s, ot, t)
                xt = ot - 2*Widthptr
                ot = dsymptr(s, ot, s1, 0)
                ot = dsymptr(s, ot, s2, 0)
                ot = dsymptr(s, ot, s3, 0)
+               ot = dsymptr(s, ot, s4, 0)
                if t.Down.Width > MAXKEYSIZE {
                        ot = duint8(s, ot, uint8(Widthptr))
                        ot = duint8(s, ot, 1) // indirect
@@ -1251,10 +1339,8 @@ func dalgsym(t *Type) *Sym {
                hashfunc = typesymprefix(".hashfunc", t)
                eqfunc = typesymprefix(".eqfunc", t)
 
-               if Debug['A'] == 0 {
-                       genhash(hash, t)
-                       geneq(eq, t)
-               }
+               genhash(hash, t)
+               geneq(eq, t)
 
                // make Go funcs (closures) for calling hash and equal from Go
                dsymptr(hashfunc, 0, hash, 0)
index 9a619a6d5a6c08c3af2d714f429973eaa58d67ca..e770c8f18d5102b86af6a28376ab02bda028d2f2 100644 (file)
@@ -318,9 +318,35 @@ out:
        lineno = int32(lno)
 }
 
-// Keep in sync with src/runtime/select.go.
+// Keep in sync with src/runtime/runtime2.go and src/runtime/select.go.
 func selecttype(size int32) *Type {
-       scase := syslook("scase", 0)
+       // TODO(dvyukov): it's possible to generate SudoG and Scase only once
+       // and then cache; and also cache Select per size.
+       sudog := Nod(OTSTRUCT, nil, nil)
+
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("g")), typenod(Ptrto(Types[TUINT8]))))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("selectdone")), typenod(Ptrto(Types[TUINT8]))))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("next")), typenod(Ptrto(Types[TUINT8]))))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("prev")), typenod(Ptrto(Types[TUINT8]))))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("elem")), typenod(Ptrto(Types[TUINT8]))))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("releasetime")), typenod(Types[TUINT64])))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("nrelease")), typenod(Types[TINT32])))
+       sudog.List = list(sudog.List, Nod(ODCLFIELD, newname(Lookup("waitlink")), typenod(Ptrto(Types[TUINT8]))))
+       typecheck(&sudog, Etype)
+       sudog.Type.Noalg = true
+       sudog.Type.Local = true
+
+       scase := Nod(OTSTRUCT, nil, nil)
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("elem")), typenod(Ptrto(Types[TUINT8]))))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("chan")), typenod(Ptrto(Types[TUINT8]))))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("pc")), typenod(Types[TUINTPTR])))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("kind")), typenod(Types[TUINT16])))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("so")), typenod(Types[TUINT16])))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("receivedp")), typenod(Ptrto(Types[TUINT8]))))
+       scase.List = list(scase.List, Nod(ODCLFIELD, newname(Lookup("releasetime")), typenod(Types[TUINT64])))
+       typecheck(&scase, Etype)
+       scase.Type.Noalg = true
+       scase.Type.Local = true
 
        sel := Nod(OTSTRUCT, nil, nil)
        sel.List = list(sel.List, Nod(ODCLFIELD, newname(Lookup("tcase")), typenod(Types[TUINT16])))
index 0415fd3da20b91b2a3b9ef9a2edc41894d259eaf..b6a26489e61352533c41d402f91c211dda00dd9f 100644 (file)
@@ -1413,21 +1413,16 @@ func deep(t *Type) *Type {
        if t == nil {
                return nil
        }
-       if t.Etype == TANY {
-               nt := shallow(t)
-               nt.Copyany = true
-               return nt
-       }
-       if t.Sym != nil {
-               // share named types
-               return t
-       }
 
        var nt *Type
        switch t.Etype {
        default:
                nt = t // share from here down
 
+       case TANY:
+               nt = shallow(t)
+               nt.Copyany = true
+
        case TPTR32, TPTR64, TCHAN, TARRAY:
                nt = shallow(t)
                nt.Type = deep(t.Type)
index f3112c3a613eb8cfeea053fce66afd9f072d2330..f324d5e00f1cda05a763854e5d7fe2215883bf1b 100644 (file)
@@ -1375,7 +1375,7 @@ opswitch:
                r := nodnil() // bucket buffer
                if n.Esc == EscNone {
                        // Allocate hmap buffer on stack.
-                       var_ := temp(syslook("hmap", 0).Type)
+                       var_ := temp(hmap(t))
 
                        a = Nod(OAS, var_, nil) // zero temp
                        typecheck(&a, Etop)
@@ -1393,7 +1393,7 @@ opswitch:
                        r = Nod(OADDR, var_, nil)
                }
 
-               substArgTypes(fn, mapbucket(t), t.Down, t.Type)
+               substArgTypes(fn, hmap(t), mapbucket(t), t.Down, t.Type)
                n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
 
        case OMAKESLICE:
index 91563dcf7ed3d298e8ae9ee5715a9b016a0176c5..003c610cb14c2fc2baf561c3b7b1f215879d52cc 100644 (file)
@@ -340,6 +340,7 @@ 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 fcfcd4b607bca5d9d5bc9b22c852bf37ec905ed3..892a79a914364143124475e63001517f64928158 100644 (file)
@@ -102,7 +102,6 @@ const (
 )
 
 // A header for a Go map.
-// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
 type hmap struct {
        // Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
        // ../reflect/type.go.  Don't change this structure without also changing that code!
@@ -138,10 +137,11 @@ type bmap struct {
 }
 
 // A hash iteration structure.
-// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
+// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate
+// the layout of this structure.
 type hiter struct {
-       key         unsafe.Pointer // Write nil to indicate iteration end (see cmd/compile/internal/gc/range.go).
-       value       unsafe.Pointer
+       key         unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/internal/gc/range.go).
+       value       unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go).
        t           *maptype
        h           *hmap
        buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
@@ -188,10 +188,11 @@ func (h *hmap) createOverflow() {
 // If h != nil, the map can be created directly in h.
 // If bucket != nil, bucket can be used as the first bucket.
 func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
-       if sz := unsafe.Sizeof(hmap{}); sz > 48 {
-               println("runtime: sizeof(hmap) =", sz)
+       if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != uintptr(t.hmap.size) {
+               println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
                throw("bad hmap size")
        }
+
        if hint < 0 || int64(int32(hint)) != hint {
                panic("makemap: size out of range")
                // TODO: make hint an int, then none of this nonsense
@@ -253,7 +254,7 @@ func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
 
        // initialize Hmap
        if h == nil {
-               h = &hmap{}
+               h = (*hmap)(newobject(t.hmap))
        }
        h.count = 0
        h.B = B
index 5bc5fca7f0dd2be822cc98d3ab05788f83f1e422..6a4dfa17b8ac0fcb5f861caa481de647f554b5f7 100644 (file)
@@ -160,6 +160,8 @@ type gobuf struct {
        bp   uintptr // for GOEXPERIMENT=framepointer
 }
 
+// Known to compiler.
+// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
 type sudog struct {
        g           *g
        selectdone  *uint32
index 25ebdaa595abaa424a9479d0a1e077f5de14c45e..b6c3fea001db858c2b17621c6d280ab56a2988f3 100644 (file)
@@ -22,7 +22,7 @@ const (
 
 // Select statement header.
 // Known to compiler.
-// Changes here must also be made in src/cmd/compile/internal/gc/select.go's selecttype.
+// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
 type hselect struct {
        tcase     uint16   // total count of scase[]
        ncase     uint16   // currently filled scase[]
@@ -33,7 +33,7 @@ type hselect struct {
 
 // Select case descriptor.
 // Known to compiler.
-// Changes here must also be made in src/cmd/compile/internal/gc/builtin/runtime.go.
+// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
 type scase struct {
        elem        unsafe.Pointer // data element
        c           *hchan         // chan
index 8350976491c21e605eda54d07fced8f692af61bc..d5f3bb1ef02e06b50390153df3a950e839471753 100644 (file)
@@ -60,6 +60,7 @@ 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