// 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
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]),
// 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
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
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
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)
}
}
// while we are iterating.
h.createOverflow()
it.overflow = h.extra.overflow
+ it.oldoverflow = h.extra.oldoverflow
}
// decide where to start
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 {
// 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
}