Skip to content

Commit

Permalink
reflect: use MapMaxKeyBytes,MapMaxElemBytes,MapBucketCount of interna…
Browse files Browse the repository at this point in the history
…l/abi

For golang#59670
  • Loading branch information
qiulaidongfeng committed Dec 17, 2023
1 parent 9b4b3e5 commit a3aa46a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 23 deletions.
32 changes: 11 additions & 21 deletions src/reflect/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1694,13 +1694,13 @@ func MapOf(key, elem Type) Type {
return typehash(ktyp, p, seed)
}
mt.Flags = 0
if ktyp.Size_ > maxKeySize {
if ktyp.Size_ > abi.MapMaxKeyBytes {
mt.KeySize = uint8(goarch.PtrSize)
mt.Flags |= 1 // indirect key
} else {
mt.KeySize = uint8(ktyp.Size_)
}
if etyp.Size_ > maxValSize {
if etyp.Size_ > abi.MapMaxElemBytes {
mt.ValueSize = uint8(goarch.PtrSize)
mt.Flags |= 2 // indirect value
} else {
Expand Down Expand Up @@ -1954,21 +1954,11 @@ func hashMightPanic(t *abi.Type) bool {
}
}

// Make sure these routines stay in sync with ../runtime/map.go!
// These types exist only for GC, so we only fill out GC relevant info.
// Currently, that's just size and the GC program. We also fill in string
// for possible debugging use.
const (
bucketSize uintptr = abi.MapBucketCount
maxKeySize uintptr = abi.MapMaxKeyBytes
maxValSize uintptr = abi.MapMaxElemBytes
)

func bucketOf(ktyp, etyp *abi.Type) *abi.Type {
if ktyp.Size_ > maxKeySize {
if ktyp.Size_ > abi.MapMaxKeyBytes {
ktyp = ptrTo(ktyp)
}
if etyp.Size_ > maxValSize {
if etyp.Size_ > abi.MapMaxElemBytes {
etyp = ptrTo(etyp)
}

Expand All @@ -1980,29 +1970,29 @@ func bucketOf(ktyp, etyp *abi.Type) *abi.Type {
var gcdata *byte
var ptrdata uintptr

size := bucketSize*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize
size := abi.MapBucketCount*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize
if size&uintptr(ktyp.Align_-1) != 0 || size&uintptr(etyp.Align_-1) != 0 {
panic("reflect: bad size computation in MapOf")
}

if ktyp.PtrBytes != 0 || etyp.PtrBytes != 0 {
nptr := (bucketSize*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize) / goarch.PtrSize
nptr := (abi.MapBucketCount*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize) / goarch.PtrSize
n := (nptr + 7) / 8

// Runtime needs pointer masks to be a multiple of uintptr in size.
n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
mask := make([]byte, n)
base := bucketSize / goarch.PtrSize
base := uintptr(abi.MapBucketCount / goarch.PtrSize)

if ktyp.PtrBytes != 0 {
emitGCMask(mask, base, ktyp, bucketSize)
emitGCMask(mask, base, ktyp, abi.MapBucketCount)
}
base += bucketSize * ktyp.Size_ / goarch.PtrSize
base += abi.MapBucketCount * ktyp.Size_ / goarch.PtrSize

if etyp.PtrBytes != 0 {
emitGCMask(mask, base, etyp, bucketSize)
emitGCMask(mask, base, etyp, abi.MapBucketCount)
}
base += bucketSize * etyp.Size_ / goarch.PtrSize
base += abi.MapBucketCount * etyp.Size_ / goarch.PtrSize

word := base
mask[word/8] |= 1 << (word % 8)
Expand Down
4 changes: 2 additions & 2 deletions src/reflect/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -1814,7 +1814,7 @@ func (v Value) MapIndex(key Value) Value {
// of unexported fields.

var e unsafe.Pointer
if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= maxValSize {
if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= abi.MapMaxElemBytes {
k := *(*string)(key.ptr)
e = mapaccess_faststr(v.typ(), v.pointer(), k)
} else {
Expand Down Expand Up @@ -2450,7 +2450,7 @@ func (v Value) SetMapIndex(key, elem Value) {
key.mustBeExported()
tt := (*mapType)(unsafe.Pointer(v.typ()))

if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= maxValSize {
if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= abi.MapMaxElemBytes {
k := *(*string)(key.ptr)
if elem.typ() == nil {
mapdelete_faststr(v.typ(), v.pointer(), k)
Expand Down

0 comments on commit a3aa46a

Please sign in to comment.