Commit d4dc26c0 authored by Martin Möhrmann's avatar Martin Möhrmann

cmd/compile: extend documentation and sync hiter and hmap with runtime

Change-Id: I71b24dd0293dd1e26a5c799161a7f9af48fb3c7d
Reviewed-on: https://go-review.googlesource.com/57295
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 8bbae3d5
...@@ -81,6 +81,7 @@ const ( ...@@ -81,6 +81,7 @@ const (
func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{}) func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{})
func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{}) func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{})
func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{}) func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{})
if t.Sym == nil && len(methods(t)) == 0 { if t.Sym == nil && len(methods(t)) == 0 {
return 0 return 0
...@@ -178,82 +179,106 @@ func mapbucket(t *types.Type) *types.Type { ...@@ -178,82 +179,106 @@ func mapbucket(t *types.Type) *types.Type {
return bucket return bucket
} }
// Builds a type representing a Hmap structure for the given map type. // hmap builds a type representing a Hmap structure for the given map type.
// Make sure this stays in sync with ../../../../runtime/hashmap.go! // Make sure this stays in sync with ../../../../runtime/hashmap.go.
func hmap(t *types.Type) *types.Type { func hmap(t *types.Type) *types.Type {
if t.MapType().Hmap != nil { if t.MapType().Hmap != nil {
return t.MapType().Hmap return t.MapType().Hmap
} }
bucket := mapbucket(t) bmap := mapbucket(t)
// build a struct:
// type hmap struct {
// count int
// flags uint8
// B uint8
// noverflow uint16
// hash0 uint32
// buckets *bmap
// oldbuckets *bmap
// nevacuate uintptr
// extra unsafe.Pointer // *mapextra
// }
// must match ../../../../runtime/hashmap.go:hmap.
fields := []*types.Field{ fields := []*types.Field{
makefield("count", types.Types[TINT]), makefield("count", types.Types[TINT]),
makefield("flags", types.Types[TUINT8]), makefield("flags", types.Types[TUINT8]),
makefield("B", types.Types[TUINT8]), makefield("B", types.Types[TUINT8]),
makefield("noverflow", types.Types[TUINT16]), makefield("noverflow", types.Types[TUINT16]),
makefield("hash0", types.Types[TUINT32]), makefield("hash0", types.Types[TUINT32]),
makefield("buckets", types.NewPtr(bucket)), makefield("buckets", types.NewPtr(bmap)), // Used in walk.go for makemap.
makefield("oldbuckets", types.NewPtr(bucket)), makefield("oldbuckets", types.NewPtr(bmap)),
makefield("nevacuate", types.Types[TUINTPTR]), makefield("nevacuate", types.Types[TUINTPTR]),
makefield("overflow", types.Types[TUNSAFEPTR]), makefield("extra", types.Types[TUNSAFEPTR]),
} }
h := types.New(TSTRUCT) hmap := types.New(TSTRUCT)
h.SetNoalg(true) hmap.SetNoalg(true)
h.SetLocal(t.Local()) hmap.SetLocal(t.Local())
h.SetFields(fields) hmap.SetFields(fields)
dowidth(h) dowidth(hmap)
t.MapType().Hmap = h t.MapType().Hmap = hmap
h.StructType().Map = t hmap.StructType().Map = t
return h return hmap
} }
// hiter builds a type representing an Hiter structure for the given map type.
// Make sure this stays in sync with ../../../../runtime/hashmap.go.
func hiter(t *types.Type) *types.Type { func hiter(t *types.Type) *types.Type {
if t.MapType().Hiter != nil { if t.MapType().Hiter != nil {
return t.MapType().Hiter return t.MapType().Hiter
} }
hmap := hmap(t)
bmap := mapbucket(t)
// build a struct: // build a struct:
// hiter { // type hiter struct {
// key *Key // key *Key
// val *Value // val *Value
// t *MapType // t unsafe.Pointer // *MapType
// h *Hmap // h *hmap
// buckets *Bucket // buckets *bmap
// bptr *Bucket // bptr *bmap
// overflow0 unsafe.Pointer // overflow [2]unsafe.Pointer // [2]*[]*bmap
// overflow1 unsafe.Pointer
// startBucket uintptr // startBucket uintptr
// stuff uintptr // offset uint8
// bucket uintptr // wrapped bool
// B uint8
// i uint8
// bucket uintptr
// checkBucket uintptr // checkBucket uintptr
// } // }
// must match ../../../../runtime/hashmap.go:hiter. // must match ../../../../runtime/hashmap.go:hiter.
var field [12]*types.Field fields := []*types.Field{
field[0] = makefield("key", types.NewPtr(t.Key())) makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
field[1] = makefield("val", types.NewPtr(t.Val())) makefield("val", types.NewPtr(t.Val())), // Used in range.go for TMAP.
field[2] = makefield("t", types.NewPtr(types.Types[TUINT8])) makefield("t", types.Types[TUNSAFEPTR]),
field[3] = makefield("h", types.NewPtr(hmap(t))) makefield("h", types.NewPtr(hmap)),
field[4] = makefield("buckets", types.NewPtr(mapbucket(t))) makefield("buckets", types.NewPtr(bmap)),
field[5] = makefield("bptr", types.NewPtr(mapbucket(t))) makefield("bptr", types.NewPtr(bmap)),
field[6] = makefield("overflow0", types.Types[TUNSAFEPTR]) makefield("overflow", types.NewArray(types.Types[TUNSAFEPTR], 2)),
field[7] = makefield("overflow1", types.Types[TUNSAFEPTR]) makefield("startBucket", types.Types[TUINTPTR]),
field[8] = makefield("startBucket", types.Types[TUINTPTR]) makefield("offset", types.Types[TUINT8]),
field[9] = makefield("stuff", types.Types[TUINTPTR]) // offset+wrapped+B+I makefield("wrapped", types.Types[TBOOL]),
field[10] = makefield("bucket", types.Types[TUINTPTR]) makefield("B", types.Types[TUINT8]),
field[11] = makefield("checkBucket", types.Types[TUINTPTR]) makefield("i", types.Types[TUINT8]),
makefield("bucket", types.Types[TUINTPTR]),
makefield("checkBucket", types.Types[TUINTPTR]),
}
// build iterator struct holding the above fields // build iterator struct holding the above fields
i := types.New(TSTRUCT) hiter := types.New(TSTRUCT)
i.SetNoalg(true) hiter.SetNoalg(true)
i.SetFields(field[:]) hiter.SetFields(fields)
dowidth(i) dowidth(hiter)
if i.Width != int64(12*Widthptr) { if hiter.Width != int64(12*Widthptr) {
Fatalf("hash_iter size not correct %d %d", i.Width, 12*Widthptr) Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
} }
t.MapType().Hiter = i t.MapType().Hiter = hiter
i.StructType().Map = t hiter.StructType().Map = t
return i return hiter
} }
// f is method type, with receiver. // f is method type, with receiver.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment