compiler,reflect: use two bits of the meta byte for comparable/isBinary
Fixes #3683
Этот коммит содержится в:
родитель
213e73ad84
коммит
37849c4897
2 изменённых файлов: 16 добавлений и 55 удалений
|
@ -238,6 +238,16 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||||
c.interfaceTypes.Set(typ, global)
|
c.interfaceTypes.Set(typ, global)
|
||||||
}
|
}
|
||||||
metabyte := getTypeKind(typ)
|
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) {
|
switch typ := typ.(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
|
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
|
||||||
|
|
|
@ -395,8 +395,10 @@ type Type interface {
|
||||||
|
|
||||||
// Constants for the 'meta' byte.
|
// Constants for the 'meta' byte.
|
||||||
const (
|
const (
|
||||||
kindMask = 31 // mask to apply to the meta byte to get the Kind value
|
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
|
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.
|
// 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.
|
// Comparable returns whether values of this type can be compared to each other.
|
||||||
func (t *rawType) Comparable() bool {
|
func (t *rawType) Comparable() bool {
|
||||||
switch t.Kind() {
|
return (t.meta & flagComparable) == flagComparable
|
||||||
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"})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// isbinary() returns if the hashmapAlgorithmBinary functions can be used on this type
|
// isbinary() returns if the hashmapAlgorithmBinary functions can be used on this type
|
||||||
func (t *rawType) isBinary() bool {
|
func (t *rawType) isBinary() bool {
|
||||||
switch t.Kind() {
|
return (t.meta & flagIsBinary) == flagIsBinary
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *rawType) ChanDir() ChanDir {
|
func (t *rawType) ChanDir() ChanDir {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче