Skip to content

Commit 06a78b5

Browse files
committed
cmd/compile: pass stack allocated bucket to makemap inside hmap
name old time/op new time/op delta NewEmptyMap 53.2ns ± 7% 48.0ns ± 5% -9.77% (p=0.000 n=20+20) NewSmallMap 111ns ± 1% 106ns ± 2% -3.78% (p=0.000 n=20+19) Change-Id: I979d21ab16eae9f6893873becca517db57e054b5 Reviewed-on: https://go-review.googlesource.com/56290 Run-TryBot: Martin Möhrmann <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent 1a2ac46 commit 06a78b5

File tree

4 files changed

+51
-37
lines changed

4 files changed

+51
-37
lines changed

src/cmd/compile/internal/gc/builtin.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/gc/builtin/runtime.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
9393
func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
9494

9595
// *byte is really *runtime.Type
96-
func makemap(mapType *byte, hint int64, mapbuf *any, bucketbuf *any) (hmap map[any]any)
96+
func makemap(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
9797
func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
9898
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
9999
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)

src/cmd/compile/internal/gc/walk.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,32 +1435,49 @@ opswitch:
14351435

14361436
case OMAKEMAP:
14371437
t := n.Type
1438+
hmapType := hmap(t)
14381439

1439-
a := nodnil() // hmap buffer
1440-
r := nodnil() // bucket buffer
1440+
// var h *hmap
1441+
var h *Node
14411442
if n.Esc == EscNone {
1442-
// Allocate hmap buffer on stack.
1443-
var_ := temp(hmap(t))
1443+
// Allocate hmap and one bucket on stack.
14441444

1445-
a = nod(OAS, var_, nil) // zero temp
1446-
a = typecheck(a, Etop)
1447-
init.Append(a)
1448-
a = nod(OADDR, var_, nil)
1445+
// var hv hmap
1446+
hv := temp(hmapType)
1447+
zero := nod(OAS, hv, nil)
1448+
zero = typecheck(zero, Etop)
1449+
init.Append(zero)
1450+
// h = &hv
1451+
h = nod(OADDR, hv, nil)
14491452

1450-
// Allocate one bucket on stack.
1453+
// Allocate one bucket pointed to by hmap.buckets on stack.
14511454
// Maximum key/value size is 128 bytes, larger objects
14521455
// are stored with an indirection. So max bucket size is 2048+eps.
1453-
var_ = temp(mapbucket(t))
14541456

1455-
r = nod(OAS, var_, nil) // zero temp
1456-
r = typecheck(r, Etop)
1457-
init.Append(r)
1458-
r = nod(OADDR, var_, nil)
1457+
// var bv bmap
1458+
bv := temp(mapbucket(t))
1459+
1460+
zero = nod(OAS, bv, nil)
1461+
zero = typecheck(zero, Etop)
1462+
init.Append(zero)
1463+
1464+
// b = &bv
1465+
b := nod(OADDR, bv, nil)
1466+
1467+
// h.buckets = b
1468+
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
1469+
na := nod(OAS, nodSym(ODOT, h, bsym), b)
1470+
na = typecheck(na, Etop)
1471+
init.Append(na)
1472+
1473+
} else {
1474+
// h = nil
1475+
h = nodnil()
14591476
}
14601477

14611478
fn := syslook("makemap")
1462-
fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
1463-
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), a, r)
1479+
fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
1480+
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), h)
14641481

14651482
case OMAKESLICE:
14661483
l := n.Left

src/runtime/hashmap.go

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ func (h *hmap) createOverflow() {
259259
// If the compiler has determined that the map or the first bucket
260260
// can be created on the stack, h and/or bucket may be non-nil.
261261
// If h != nil, the map can be created directly in h.
262-
// If bucket != nil, bucket can be used as the first bucket.
263-
func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
262+
// If h.buckets != nil, bucket pointed to can be used as the first bucket.
263+
func makemap(t *maptype, hint int64, h *hmap) *hmap {
264264
if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != t.hmap.size {
265265
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
266266
throw("bad hmap size")
@@ -312,34 +312,31 @@ func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
312312
throw("bad evacuatedN")
313313
}
314314

315+
// initialize Hmap
316+
if h == nil {
317+
h = (*hmap)(newobject(t.hmap))
318+
}
319+
h.hash0 = fastrand()
320+
315321
// find size parameter which will hold the requested # of elements
316322
B := uint8(0)
317-
for ; overLoadFactor(hint, B); B++ {
323+
for overLoadFactor(hint, B) {
324+
B++
318325
}
326+
h.B = B
319327

320328
// allocate initial hash table
321329
// if B == 0, the buckets field is allocated lazily later (in mapassign)
322330
// If hint is large zeroing this memory could take a while.
323-
buckets := bucket
324-
var extra *mapextra
325-
if B != 0 {
331+
if h.B != 0 {
326332
var nextOverflow *bmap
327-
buckets, nextOverflow = makeBucketArray(t, B)
333+
h.buckets, nextOverflow = makeBucketArray(t, h.B)
328334
if nextOverflow != nil {
329-
extra = new(mapextra)
330-
extra.nextOverflow = nextOverflow
335+
h.extra = new(mapextra)
336+
h.extra.nextOverflow = nextOverflow
331337
}
332338
}
333339

334-
// initialize Hmap
335-
if h == nil {
336-
h = (*hmap)(newobject(t.hmap))
337-
}
338-
h.B = B
339-
h.extra = extra
340-
h.hash0 = fastrand()
341-
h.buckets = buckets
342-
343340
return h
344341
}
345342

@@ -1171,7 +1168,7 @@ func ismapkey(t *_type) bool {
11711168

11721169
//go:linkname reflect_makemap reflect.makemap
11731170
func reflect_makemap(t *maptype, cap int) *hmap {
1174-
return makemap(t, int64(cap), nil, nil)
1171+
return makemap(t, int64(cap), nil)
11751172
}
11761173

11771174
//go:linkname reflect_mapaccess reflect.mapaccess

0 commit comments

Comments
 (0)