typs[58] = types.Types[TUNSAFEPTR]
typs[59] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[58]), anonfield(typs[58])}, []*Node{anonfield(typs[11])})
typs[60] = types.NewMap(typs[2], typs[2])
- typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[60])})
+ typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[60])})
typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
// *byte is really *runtime.Type
-func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int64, mapbuf *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)
case OMAKEMAP:
t := n.Type
+ hmapType := hmap(t)
- a := nodnil() // hmap buffer
- r := nodnil() // bucket buffer
+ // var h *hmap
+ var h *Node
if n.Esc == EscNone {
- // Allocate hmap buffer on stack.
- var_ := temp(hmap(t))
+ // Allocate hmap and one bucket on stack.
- a = nod(OAS, var_, nil) // zero temp
- a = typecheck(a, Etop)
- init.Append(a)
- a = nod(OADDR, var_, nil)
+ // var hv hmap
+ hv := temp(hmapType)
+ zero := nod(OAS, hv, nil)
+ zero = typecheck(zero, Etop)
+ init.Append(zero)
+ // h = &hv
+ h = nod(OADDR, hv, nil)
- // Allocate one bucket on stack.
+ // Allocate one bucket pointed to by hmap.buckets on stack.
// Maximum key/value size is 128 bytes, larger objects
// are stored with an indirection. So max bucket size is 2048+eps.
- var_ = temp(mapbucket(t))
- r = nod(OAS, var_, nil) // zero temp
- r = typecheck(r, Etop)
- init.Append(r)
- r = nod(OADDR, var_, nil)
+ // var bv bmap
+ bv := temp(mapbucket(t))
+
+ zero = nod(OAS, bv, nil)
+ zero = typecheck(zero, Etop)
+ init.Append(zero)
+
+ // b = &bv
+ b := nod(OADDR, bv, nil)
+
+ // h.buckets = b
+ bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
+ na := nod(OAS, nodSym(ODOT, h, bsym), b)
+ na = typecheck(na, Etop)
+ init.Append(na)
+
+ } else {
+ // h = nil
+ h = nodnil()
}
fn := syslook("makemap")
- fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
- n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), a, r)
+ fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
+ n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), h)
case OMAKESLICE:
l := n.Left
// If the compiler has determined that the map or the first bucket
// can be created on the stack, h and/or bucket may be non-nil.
// 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 h.buckets != nil, bucket pointed to can be used as the first bucket.
+func makemap(t *maptype, hint int64, h *hmap) *hmap {
if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != t.hmap.size {
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
throw("bad hmap size")
throw("bad evacuatedN")
}
+ // initialize Hmap
+ if h == nil {
+ h = (*hmap)(newobject(t.hmap))
+ }
+ h.hash0 = fastrand()
+
// find size parameter which will hold the requested # of elements
B := uint8(0)
- for ; overLoadFactor(hint, B); B++ {
+ for overLoadFactor(hint, B) {
+ B++
}
+ h.B = B
// allocate initial hash table
// if B == 0, the buckets field is allocated lazily later (in mapassign)
// If hint is large zeroing this memory could take a while.
- buckets := bucket
- var extra *mapextra
- if B != 0 {
+ if h.B != 0 {
var nextOverflow *bmap
- buckets, nextOverflow = makeBucketArray(t, B)
+ h.buckets, nextOverflow = makeBucketArray(t, h.B)
if nextOverflow != nil {
- extra = new(mapextra)
- extra.nextOverflow = nextOverflow
+ h.extra = new(mapextra)
+ h.extra.nextOverflow = nextOverflow
}
}
- // initialize Hmap
- if h == nil {
- h = (*hmap)(newobject(t.hmap))
- }
- h.B = B
- h.extra = extra
- h.hash0 = fastrand()
- h.buckets = buckets
-
return h
}
//go:linkname reflect_makemap reflect.makemap
func reflect_makemap(t *maptype, cap int) *hmap {
- return makemap(t, int64(cap), nil, nil)
+ return makemap(t, int64(cap), nil)
}
//go:linkname reflect_mapaccess reflect.mapaccess