mirror of
https://github.com/golang/go
synced 2024-11-19 13:14:42 -07:00
runtime: refactor hmap.extra.overflow array into two separate fields
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 <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
a4956248a8
commit
1d3ad6733e
@ -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]),
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user