mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/gc: allocate non-escaping maps on stack
Extend escape analysis to make(map[k]v). If it does not escape, allocate temp buffer for hmap and one bucket on stack. There are 75 cases of non-escaping maps in std lib. benchmark old allocs new allocs delta BenchmarkConcurrentStmtQuery 16161 15161 -6.19% BenchmarkConcurrentTxQuery 17658 16658 -5.66% BenchmarkConcurrentTxStmtQuery 16157 15156 -6.20% BenchmarkConcurrentRandom 13637 13114 -3.84% BenchmarkManyConcurrentQueries 22 20 -9.09% BenchmarkDecodeComplex128Slice 250 188 -24.80% BenchmarkDecodeFloat64Slice 250 188 -24.80% BenchmarkDecodeInt32Slice 250 188 -24.80% BenchmarkDecodeStringSlice 2250 2188 -2.76% BenchmarkNewEmptyMap 1 0 -100.00% BenchmarkNewSmallMap 2 0 -100.00% benchmark old ns/op new ns/op delta BenchmarkNewEmptyMap 124 55.7 -55.08% BenchmarkNewSmallMap 317 148 -53.31% benchmark old allocs new allocs delta BenchmarkNewEmptyMap 1 0 -100.00% BenchmarkNewSmallMap 2 0 -100.00% benchmark old bytes new bytes delta BenchmarkNewEmptyMap 48 0 -100.00% BenchmarkNewSmallMap 192 0 -100.00% Fixes #5449 Change-Id: I24fa66f949d2f138885d9e66a0d160240dc9e8fa Reviewed-on: https://go-review.googlesource.com/3508 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
aed88be021
commit
b3be360f16
12 changed files with 178 additions and 168 deletions
|
|
@ -182,8 +182,14 @@ func (h *hmap) createOverflow() {
|
|||
}
|
||||
}
|
||||
|
||||
func makemap(t *maptype, hint int64) *hmap {
|
||||
// makemap implements a Go map creation make(map[k]v, hint)
|
||||
// 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 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")
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +244,7 @@ func makemap(t *maptype, hint int64) *hmap {
|
|||
// 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.
|
||||
var buckets unsafe.Pointer
|
||||
buckets := bucket
|
||||
if B != 0 {
|
||||
if checkgc {
|
||||
memstats.next_gc = memstats.heap_alloc
|
||||
|
|
@ -250,7 +256,9 @@ func makemap(t *maptype, hint int64) *hmap {
|
|||
if checkgc {
|
||||
memstats.next_gc = memstats.heap_alloc
|
||||
}
|
||||
h := (*hmap)(newobject(t.hmap))
|
||||
if h == nil {
|
||||
h = (*hmap)(newobject(t.hmap))
|
||||
}
|
||||
h.count = 0
|
||||
h.B = B
|
||||
h.flags = 0
|
||||
|
|
@ -956,7 +964,7 @@ func ismapkey(t *_type) bool {
|
|||
|
||||
//go:linkname reflect_makemap reflect.makemap
|
||||
func reflect_makemap(t *maptype) *hmap {
|
||||
return makemap(t, 0)
|
||||
return makemap(t, 0, nil, nil)
|
||||
}
|
||||
|
||||
//go:linkname reflect_mapaccess reflect.mapaccess
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue