Browse Source

compiler,reflect: use two bits of the meta byte for comparable/isBinary

Fixes #3683
pull/3774/head
Damian Gryski 1 year ago
committed by Ron Evans
parent
commit
37849c4897
  1. 10
      compiler/interface.go
  2. 57
      src/reflect/type.go

10
compiler/interface.go

@ -238,6 +238,16 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
c.interfaceTypes.Set(typ, global)
}
metabyte := getTypeKind(typ)
// Precompute these so we don't have to calculate them at runtime.
if types.Comparable(typ) {
metabyte |= 1 << 6
}
if hashmapIsBinaryKey(typ) {
metabyte |= 1 << 7
}
switch typ := typ.(type) {
case *types.Basic:
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}

57
src/reflect/type.go

@ -397,6 +397,8 @@ type Type interface {
const (
kindMask = 31 // mask to apply to the meta byte to get the Kind value
flagNamed = 32 // flag that is set if this is a named type
flagComparable = 64 // flag that is set if this type is comparable
flagIsBinary = 128 // flag that is set if this type uses the hashmap binary algorithm
)
// The base type struct. All type structs start with this.
@ -940,63 +942,12 @@ func (t *rawType) Implements(u Type) bool {
// Comparable returns whether values of this type can be compared to each other.
func (t *rawType) Comparable() bool {
switch t.Kind() {
case Invalid:
return false
case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return true
case Float32, Float64, Complex64, Complex128:
return true
case String:
return true
case UnsafePointer:
return true
case Chan:
return true
case Interface:
return true
case Pointer:
return true
case Slice:
return false
case Array:
return t.elem().Comparable()
case Func:
return false
case Map:
return false
case Struct:
numField := t.NumField()
for i := 0; i < numField; i++ {
if !t.rawField(i).Type.Comparable() {
return false
}
}
return true
default:
panic(TypeError{"Comparable"})
}
return (t.meta & flagComparable) == flagComparable
}
// isbinary() returns if the hashmapAlgorithmBinary functions can be used on this type
func (t *rawType) isBinary() bool {
switch t.Kind() {
case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return true
case Pointer:
return true
case Array:
return t.elem().isBinary()
case Struct:
numField := t.NumField()
for i := 0; i < numField; i++ {
if !t.rawField(i).Type.isBinary() {
return false
}
}
return true
}
return false
return (t.meta & flagIsBinary) == flagIsBinary
}
func (t *rawType) ChanDir() ChanDir {

Loading…
Cancel
Save