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: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 8bbae3d5
......@@ -81,6 +81,7 @@ const (
func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{})
func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{})
func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{})
if t.Sym == nil && len(methods(t)) == 0 {
return 0
......@@ -178,82 +179,106 @@ func mapbucket(t *types.Type) *types.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!
// hmap 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 *types.Type) *types.Type {
if t.MapType().Hmap != nil {
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{
makefield("count", types.Types[TINT]),
makefield("flags", types.Types[TUINT8]),
makefield("B", types.Types[TUINT8]),
makefield("noverflow", types.Types[TUINT16]),
makefield("hash0", types.Types[TUINT32]),
makefield("buckets", types.NewPtr(bucket)),
makefield("oldbuckets", types.NewPtr(bucket)),
makefield("buckets", types.NewPtr(bmap)), // Used in walk.go for makemap.
makefield("oldbuckets", types.NewPtr(bmap)),
makefield("nevacuate", types.Types[TUINTPTR]),
makefield("overflow", types.Types[TUNSAFEPTR]),
makefield("extra", types.Types[TUNSAFEPTR]),
}
h := types.New(TSTRUCT)
h.SetNoalg(true)
h.SetLocal(t.Local())
h.SetFields(fields)
dowidth(h)
t.MapType().Hmap = h
h.StructType().Map = t
return h
hmap := types.New(TSTRUCT)
hmap.SetNoalg(true)
hmap.SetLocal(t.Local())
hmap.SetFields(fields)
dowidth(hmap)
t.MapType().Hmap = hmap
hmap.StructType().Map = t
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 {
if t.MapType().Hiter != nil {
return t.MapType().Hiter
}
hmap := hmap(t)
bmap := mapbucket(t)
// build a struct:
// hiter {
// key *Key
// val *Value
// t *MapType
// h *Hmap
// buckets *Bucket
// bptr *Bucket
// overflow0 unsafe.Pointer
// overflow1 unsafe.Pointer
// type hiter struct {
// key *Key
// val *Value
// t unsafe.Pointer // *MapType
// h *hmap
// buckets *bmap
// bptr *bmap
// overflow [2]unsafe.Pointer // [2]*[]*bmap
// startBucket uintptr
// stuff uintptr
// bucket uintptr
// offset uint8
// wrapped bool
// B uint8
// i uint8
// bucket uintptr
// checkBucket uintptr
// }
// must match ../../../../runtime/hashmap.go:hiter.
var field [12]*types.Field
field[0] = makefield("key", types.NewPtr(t.Key()))
field[1] = makefield("val", types.NewPtr(t.Val()))
field[2] = makefield("t", types.NewPtr(types.Types[TUINT8]))
field[3] = makefield("h", types.NewPtr(hmap(t)))
field[4] = makefield("buckets", types.NewPtr(mapbucket(t)))
field[5] = makefield("bptr", types.NewPtr(mapbucket(t)))
field[6] = makefield("overflow0", types.Types[TUNSAFEPTR])
field[7] = makefield("overflow1", types.Types[TUNSAFEPTR])
field[8] = makefield("startBucket", types.Types[TUINTPTR])
field[9] = makefield("stuff", types.Types[TUINTPTR]) // offset+wrapped+B+I
field[10] = makefield("bucket", types.Types[TUINTPTR])
field[11] = makefield("checkBucket", types.Types[TUINTPTR])
fields := []*types.Field{
makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
makefield("val", types.NewPtr(t.Val())), // Used in range.go for TMAP.
makefield("t", types.Types[TUNSAFEPTR]),
makefield("h", types.NewPtr(hmap)),
makefield("buckets", types.NewPtr(bmap)),
makefield("bptr", types.NewPtr(bmap)),
makefield("overflow", types.NewArray(types.Types[TUNSAFEPTR], 2)),
makefield("startBucket", types.Types[TUINTPTR]),
makefield("offset", types.Types[TUINT8]),
makefield("wrapped", types.Types[TBOOL]),
makefield("B", types.Types[TUINT8]),
makefield("i", types.Types[TUINT8]),
makefield("bucket", types.Types[TUINTPTR]),
makefield("checkBucket", types.Types[TUINTPTR]),
}
// build iterator struct holding the above fields
i := types.New(TSTRUCT)
i.SetNoalg(true)
i.SetFields(field[:])
dowidth(i)
if i.Width != int64(12*Widthptr) {
Fatalf("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
}
t.MapType().Hiter = i
i.StructType().Map = t
return i
hiter := types.New(TSTRUCT)
hiter.SetNoalg(true)
hiter.SetFields(fields)
dowidth(hiter)
if hiter.Width != int64(12*Widthptr) {
Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
}
t.MapType().Hiter = hiter
hiter.StructType().Map = t
return hiter
}
// 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