From 1d3ad6733e7b1417444bfe1c5ca85b6108e9ac6c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20M=C3=B6hrmann?= Date: Sun, 10 Sep 2017 12:55:16 +0200 Subject: [PATCH] runtime: refactor hmap.extra.overflow array into two separate fields MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This makes it easier to deduce from the field names which overflow field corresponds to h.buckets and which to h.oldbuckets by aligning the naming with the buckets fields in hmap. Change-Id: I8d6a729229a190db0212bac012ead1a3c13cf5d0 Reviewed-on: https://go-review.googlesource.com/62411 Run-TryBot: Martin Möhrmann TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/gc/reflect.go | 6 +++-- src/runtime/hashmap.go | 33 ++++++++++++++------------ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index c4ab1df62d..0bc0c53631 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -295,7 +295,8 @@ func hiter(t *types.Type) *types.Type { // h *hmap // buckets *bmap // bptr *bmap - // overflow [2]unsafe.Pointer // [2]*[]*bmap + // overflow unsafe.Pointer // *[]*bmap + // oldoverflow unsafe.Pointer // *[]*bmap // startBucket uintptr // offset uint8 // wrapped bool @@ -312,7 +313,8 @@ func hiter(t *types.Type) *types.Type { makefield("h", types.NewPtr(hmap)), makefield("buckets", types.NewPtr(bmap)), makefield("bptr", types.NewPtr(bmap)), - makefield("overflow", types.NewArray(types.Types[TUNSAFEPTR], 2)), + makefield("overflow", types.Types[TUNSAFEPTR]), + makefield("oldoverflow", types.Types[TUNSAFEPTR]), makefield("startBucket", types.Types[TUINTPTR]), makefield("offset", types.Types[TUINT8]), makefield("wrapped", types.Types[TBOOL]), diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index 4f47838cd4..db8505f6db 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -126,12 +126,13 @@ type mapextra struct { // If both key and value do not contain pointers and are inline, then we mark bucket // type as containing no pointers. This avoids scanning such maps. // However, bmap.overflow is a pointer. In order to keep overflow buckets - // alive, we store pointers to all overflow buckets in hmap.overflow. - // Overflow is used only if key and value do not contain pointers. - // overflow[0] contains overflow buckets for hmap.buckets. - // overflow[1] contains overflow buckets for hmap.oldbuckets. + // alive, we store pointers to all overflow buckets in hmap.overflow and h.map.oldoverflow. + // overflow and oldoverflow are only used if key and value do not contain pointers. + // overflow contains overflow buckets for hmap.buckets. + // oldoverflow contains overflow buckets for hmap.oldbuckets. // The indirection allows to store a pointer to the slice in hiter. - overflow [2]*[]*bmap + overflow *[]*bmap + oldoverflow *[]*bmap // nextOverflow holds a pointer to a free overflow bucket. nextOverflow *bmap @@ -160,7 +161,8 @@ type hiter struct { h *hmap buckets unsafe.Pointer // bucket ptr at hash_iter initialization time bptr *bmap // current bucket - overflow [2]*[]*bmap // keeps overflow buckets alive + overflow *[]*bmap // keeps overflow buckets of hmap.buckets alive + oldoverflow *[]*bmap // keeps overflow buckets of hmap.oldbuckets alive startBucket uintptr // bucket iteration started at offset uint8 // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1) wrapped bool // already wrapped around from end of bucket array to beginning @@ -257,7 +259,7 @@ func (h *hmap) newoverflow(t *maptype, b *bmap) *bmap { h.incrnoverflow() if t.bucket.kind&kindNoPointers != 0 { h.createOverflow() - *h.extra.overflow[0] = append(*h.extra.overflow[0], ovf) + *h.extra.overflow = append(*h.extra.overflow, ovf) } b.setoverflow(t, ovf) return ovf @@ -267,8 +269,8 @@ func (h *hmap) createOverflow() { if h.extra == nil { h.extra = new(mapextra) } - if h.extra.overflow[0] == nil { - h.extra.overflow[0] = new([]*bmap) + if h.extra.overflow == nil { + h.extra.overflow = new([]*bmap) } } @@ -703,6 +705,7 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) { // while we are iterating. h.createOverflow() it.overflow = h.extra.overflow + it.oldoverflow = h.extra.oldoverflow } // decide where to start @@ -904,13 +907,13 @@ func hashGrow(t *maptype, h *hmap) { h.nevacuate = 0 h.noverflow = 0 - if h.extra != nil && h.extra.overflow[0] != nil { + if h.extra != nil && h.extra.overflow != nil { // Promote current overflow buckets to the old generation. - if h.extra.overflow[1] != nil { - throw("overflow is not nil") + if h.extra.oldoverflow != nil { + throw("oldoverflow is not nil") } - h.extra.overflow[1] = h.extra.overflow[0] - h.extra.overflow[0] = nil + h.extra.oldoverflow = h.extra.overflow + h.extra.overflow = nil } if nextOverflow != nil { if h.extra == nil { @@ -1123,7 +1126,7 @@ func advanceEvacuationMark(h *hmap, t *maptype, newbit uintptr) { // If they are still referenced by an iterator, // then the iterator holds a pointers to the slice. if h.extra != nil { - h.extra.overflow[1] = nil + h.extra.oldoverflow = nil } h.flags &^= sameSizeGrow } -- 2.48.1