mirror of https://github.com/golang/go.git
remove Elem() optimization
This commit is contained in:
parent
27a902127c
commit
64d2ac5bb2
|
|
@ -415,14 +415,6 @@ var kinds = []abi.Kind{
|
|||
types.TUNSAFEPTR: abi.UnsafePointer,
|
||||
}
|
||||
|
||||
var elemKinds = []abi.Kind{
|
||||
abi.Array,
|
||||
abi.Chan,
|
||||
abi.Map,
|
||||
abi.Pointer,
|
||||
abi.Slice,
|
||||
}
|
||||
|
||||
var (
|
||||
memhashvarlen *obj.LSym
|
||||
memequalvarlen *obj.LSym
|
||||
|
|
@ -481,14 +473,6 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
|
|||
tflag |= abi.TFlagGCMaskOnDemand
|
||||
}
|
||||
|
||||
kind := kinds[t.Kind()]
|
||||
if slices.Contains(elemKinds, kind) {
|
||||
tflag |= abi.TFlagHasElem
|
||||
if kind == abi.Map {
|
||||
tflag |= abi.TFlagHasElemSecond
|
||||
}
|
||||
}
|
||||
|
||||
exported := false
|
||||
p := t.NameString()
|
||||
// If we're writing out type T,
|
||||
|
|
@ -526,6 +510,7 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
|
|||
c.Field("Align_").WriteUint8(uint8(t.Alignment()))
|
||||
c.Field("FieldAlign_").WriteUint8(uint8(t.Alignment()))
|
||||
|
||||
kind := kinds[t.Kind()]
|
||||
if types.IsDirectIface(t) {
|
||||
kind |= abi.KindDirectIface
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
package abi
|
||||
|
||||
import (
|
||||
"internal/goarch"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
|
@ -126,12 +125,6 @@ const (
|
|||
// has type **byte instead of *byte. The runtime will store a
|
||||
// pointer to the GC pointer bitmask in *GCData.
|
||||
TFlagGCMaskOnDemand TFlag = 1 << 4
|
||||
|
||||
// TFlagHasElem signals that the Type has an Elem.
|
||||
TFlagHasElem TFlag = 1 << 5
|
||||
|
||||
// TFlagHasElem signals that the Type has an Elem, but at an PtrBytes higher offset.
|
||||
TFlagHasElemSecond TFlag = 1 << 6
|
||||
)
|
||||
|
||||
// NameOff is the offset to a name from moduledata.types. See resolveNameOff in runtime.
|
||||
|
|
@ -383,25 +376,24 @@ func (t *Type) Uncommon() *UncommonType {
|
|||
}
|
||||
}
|
||||
|
||||
// Compile time asserts for (*Type).Elem().
|
||||
func _() {
|
||||
const _, _ = unsafe.Offsetof(ChanType{}.Elem) - baseElemOffset, baseElemOffset - unsafe.Offsetof(ChanType{}.Elem)
|
||||
const _, _ = unsafe.Offsetof(mapType{}.Elem) - baseElemOffset + goarch.PtrSize, baseElemOffset + goarch.PtrSize - unsafe.Offsetof(mapType{}.Elem)
|
||||
const _, _ = unsafe.Offsetof(PtrType{}.Elem) - baseElemOffset, baseElemOffset - unsafe.Offsetof(PtrType{}.Elem)
|
||||
const _, _ = unsafe.Offsetof(SliceType{}.Elem) - baseElemOffset, baseElemOffset - unsafe.Offsetof(SliceType{}.Elem)
|
||||
var _, _, _, _, _ *Type = ArrayType{}.Elem, ChanType{}.Elem, mapType{}.Elem, PtrType{}.Elem, SliceType{}.Elem
|
||||
}
|
||||
|
||||
const baseElemOffset = unsafe.Offsetof(ArrayType{}.Elem)
|
||||
|
||||
// Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.
|
||||
func (t *Type) Elem() *Type {
|
||||
if t.TFlag&TFlagHasElem != 0 {
|
||||
// Unfortunately, the mapType does not have the Elem field at the same offset as other
|
||||
// types do, it is PtrBytes ahead. So we have to calculate the offset based on TFlagHasElemSecond flag.
|
||||
// Currently we can't really change the definition of mapType to reorder these fields,
|
||||
// because mapType is referenced with linknames from other modules (non-std).
|
||||
return *(**Type)(unsafe.Add(unsafe.Pointer(t), baseElemOffset+(goarch.PtrSize*uintptr((t.TFlag&TFlagHasElemSecond)>>6))))
|
||||
switch t.Kind() {
|
||||
case Array:
|
||||
tt := (*ArrayType)(unsafe.Pointer(t))
|
||||
return tt.Elem
|
||||
case Chan:
|
||||
tt := (*ChanType)(unsafe.Pointer(t))
|
||||
return tt.Elem
|
||||
case Map:
|
||||
tt := (*mapType)(unsafe.Pointer(t))
|
||||
return tt.Elem
|
||||
case Pointer:
|
||||
tt := (*PtrType)(unsafe.Pointer(t))
|
||||
return tt.Elem
|
||||
case Slice:
|
||||
tt := (*SliceType)(unsafe.Pointer(t))
|
||||
return tt.Elem
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func MapOf(key, elem Type) Type {
|
|||
var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
|
||||
mt := **(**mapType)(unsafe.Pointer(&imap))
|
||||
mt.Str = resolveReflectName(newName(s, "", false, false))
|
||||
mt.TFlag = abi.TFlagHasElem | abi.TFlagHasElemSecond
|
||||
mt.TFlag = 0
|
||||
mt.Hash = fnv1(etyp.Hash, 'm', byte(ktyp.Hash>>24), byte(ktyp.Hash>>16), byte(ktyp.Hash>>8), byte(ktyp.Hash))
|
||||
mt.Key = ktyp
|
||||
mt.Elem = etyp
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func MapOf(key, elem Type) Type {
|
|||
var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
|
||||
mt := **(**mapType)(unsafe.Pointer(&imap))
|
||||
mt.Str = resolveReflectName(newName(s, "", false, false))
|
||||
mt.TFlag = abi.TFlagHasElem | abi.TFlagHasElemSecond
|
||||
mt.TFlag = 0
|
||||
mt.Hash = fnv1(etyp.Hash, 'm', byte(ktyp.Hash>>24), byte(ktyp.Hash>>16), byte(ktyp.Hash>>8), byte(ktyp.Hash))
|
||||
mt.Key = ktyp
|
||||
mt.Elem = etyp
|
||||
|
|
|
|||
|
|
@ -1361,7 +1361,6 @@ func (t *rtype) ptrTo() *abi.Type {
|
|||
|
||||
pp.Str = resolveReflectName(newName(s, "", false, false))
|
||||
pp.PtrToThis = 0
|
||||
pp.TFlag = abi.TFlagHasElem
|
||||
|
||||
// For the type structures linked into the binary, the
|
||||
// compiler provides a good hash of the string.
|
||||
|
|
@ -2086,7 +2085,7 @@ func SliceOf(t Type) Type {
|
|||
var islice any = ([]unsafe.Pointer)(nil)
|
||||
prototype := *(**sliceType)(unsafe.Pointer(&islice))
|
||||
slice := *prototype
|
||||
slice.TFlag = abi.TFlagHasElem
|
||||
slice.TFlag = 0
|
||||
slice.Str = resolveReflectName(newName(s, "", false, false))
|
||||
slice.Hash = fnv1(typ.Hash, '[')
|
||||
slice.Elem = typ
|
||||
|
|
@ -2472,9 +2471,9 @@ func StructOf(fields []StructField) Type {
|
|||
|
||||
typ.Str = resolveReflectName(newName(str, "", false, false))
|
||||
if isRegularMemory(toType(&typ.Type)) {
|
||||
typ.TFlag = abi.TFlagRegularMemory & abi.TFlagHasElem
|
||||
typ.TFlag = abi.TFlagRegularMemory
|
||||
} else {
|
||||
typ.TFlag = abi.TFlagHasElem
|
||||
typ.TFlag = 0
|
||||
}
|
||||
typ.Hash = hash
|
||||
typ.Size_ = size
|
||||
|
|
@ -2612,7 +2611,7 @@ func ArrayOf(length int, elem Type) Type {
|
|||
var iarray any = [1]unsafe.Pointer{}
|
||||
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
|
||||
array := *prototype
|
||||
array.TFlag = (typ.TFlag & abi.TFlagRegularMemory) | abi.TFlagHasElem
|
||||
array.TFlag = typ.TFlag & abi.TFlagRegularMemory
|
||||
array.Str = resolveReflectName(newName(s, "", false, false))
|
||||
array.Hash = fnv1(typ.Hash, '[')
|
||||
for n := uint32(length); n > 0; n >>= 8 {
|
||||
|
|
|
|||
|
|
@ -118,13 +118,6 @@ func BenchmarkTypeForError(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkSliceTypeElem(b *testing.B) {
|
||||
slice := reflect.TypeFor[[]int]()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sinkType = slice.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
func TestType_CanSeq(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Reference in New Issue