mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: if key type is reflexive, don't call equal(k, k)
Most types are reflexive (k == k for all k of type t), so don't bother calling equal(k, k) when the key type is reflexive. Change-Id: Ia716b4198b8b298687843b94b878dbc5e8fc2c65 Reviewed-on: https://go-review.googlesource.com/1480 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
324f38a222
commit
df1739c77d
4 changed files with 81 additions and 3 deletions
|
|
@ -345,6 +345,7 @@ type mapType struct {
|
|||
valuesize uint8 // size of value slot
|
||||
indirectvalue uint8 // store ptr to value instead of value itself
|
||||
bucketsize uint16 // size of bucket
|
||||
reflexivekey bool // true if k==k for all keys
|
||||
}
|
||||
|
||||
// ptrType represents a pointer type.
|
||||
|
|
@ -1489,6 +1490,7 @@ func MapOf(key, elem Type) Type {
|
|||
mt.indirectvalue = 0
|
||||
}
|
||||
mt.bucketsize = uint16(mt.bucket.size)
|
||||
mt.reflexivekey = isReflexive(ktyp)
|
||||
mt.uncommonType = nil
|
||||
mt.ptrToThis = nil
|
||||
mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
|
||||
|
|
@ -1496,6 +1498,31 @@ func MapOf(key, elem Type) Type {
|
|||
return cachePut(ckey, &mt.rtype)
|
||||
}
|
||||
|
||||
// isReflexive reports whether the == operation on the type is reflexive.
|
||||
// That is, x == x for all values x of type t.
|
||||
func isReflexive(t *rtype) bool {
|
||||
switch t.Kind() {
|
||||
case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer:
|
||||
return true
|
||||
case Float32, Float64, Complex64, Complex128, Interface:
|
||||
return false
|
||||
case Array:
|
||||
tt := (*arrayType)(unsafe.Pointer(t))
|
||||
return isReflexive(tt.elem)
|
||||
case Struct:
|
||||
tt := (*structType)(unsafe.Pointer(t))
|
||||
for _, f := range tt.fields {
|
||||
if !isReflexive(f.typ) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
// Func, Map, Slice, Invalid
|
||||
panic("isReflexive called on non-key type " + t.String())
|
||||
}
|
||||
}
|
||||
|
||||
// gcProg is a helper type for generatation of GC pointer info.
|
||||
type gcProg struct {
|
||||
gc []byte
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue