mirror of https://github.com/golang/go.git
internal/abi: common up ArrayType
This refactoring is more problematic because the client package wrap abi.Type, thus the self-referential fields within ArrayType need to be downcast to the client wrappers in several places. It's not clear to me this is worthwhile; this CL is for additional comment, before I attempt similar changes for other self-referential types. Change-Id: I41e517e6d851b32560c41676b91b76d7eb17c951 Reviewed-on: https://go-review.googlesource.com/c/go/+/466236 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
3f9521b2f0
commit
a851511947
|
|
@ -1803,7 +1803,7 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
|
||||||
// Needed by the prettyprinter code for interface inspection.
|
// Needed by the prettyprinter code for interface inspection.
|
||||||
for _, typ := range []string{
|
for _, typ := range []string{
|
||||||
"type:runtime._type",
|
"type:runtime._type",
|
||||||
"type:runtime.arraytype",
|
"type:internal/abi.ArrayType",
|
||||||
"type:runtime.chantype",
|
"type:runtime.chantype",
|
||||||
"type:runtime.functype",
|
"type:runtime.functype",
|
||||||
"type:runtime.maptype",
|
"type:runtime.maptype",
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ func TestRuntimeTypesPresent(t *testing.T) {
|
||||||
|
|
||||||
want := map[string]bool{
|
want := map[string]bool{
|
||||||
"runtime._type": true,
|
"runtime._type": true,
|
||||||
"runtime.arraytype": true,
|
// "runtime.arraytype": true,
|
||||||
"runtime.chantype": true,
|
"runtime.chantype": true,
|
||||||
"runtime.functype": true,
|
"runtime.functype": true,
|
||||||
"runtime.maptype": true,
|
"runtime.maptype": true,
|
||||||
|
|
|
||||||
|
|
@ -131,12 +131,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// arrayType represents a fixed array type.
|
// arrayType represents a fixed array type.
|
||||||
type arrayType struct {
|
type arrayType = abi.ArrayType
|
||||||
rtype
|
|
||||||
elem *rtype // array element type
|
|
||||||
slice *rtype // slice type
|
|
||||||
len uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// chanType represents a channel type.
|
// chanType represents a channel type.
|
||||||
type chanType struct {
|
type chanType struct {
|
||||||
|
|
@ -507,7 +502,7 @@ func (t *rtype) Elem() Type {
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return toType(tt.elem)
|
return toType((*rtype)(tt.Elem))
|
||||||
case Chan:
|
case Chan:
|
||||||
tt := (*chanType)(unsafe.Pointer(t))
|
tt := (*chanType)(unsafe.Pointer(t))
|
||||||
return toType(tt.elem)
|
return toType(tt.elem)
|
||||||
|
|
@ -545,7 +540,7 @@ func (t *rtype) Len() int {
|
||||||
panic("reflect: Len of non-array type")
|
panic("reflect: Len of non-array type")
|
||||||
}
|
}
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return int(tt.len)
|
return int(tt.Len)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *rtype) NumField() int {
|
func (t *rtype) NumField() int {
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@ func (v Value) Len() int {
|
||||||
switch k {
|
switch k {
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
||||||
return int(tt.len)
|
return int(tt.Len)
|
||||||
case Chan:
|
case Chan:
|
||||||
return chanlen(v.pointer())
|
return chanlen(v.pointer())
|
||||||
case Map:
|
case Map:
|
||||||
|
|
|
||||||
|
|
@ -222,14 +222,14 @@ func (a *abiSeq) regAssign(t *rtype, offset uintptr) bool {
|
||||||
return a.assignIntN(offset, goarch.PtrSize, 3, 0b001)
|
return a.assignIntN(offset, goarch.PtrSize, 3, 0b001)
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
switch tt.len {
|
switch tt.Len {
|
||||||
case 0:
|
case 0:
|
||||||
// There's nothing to assign, so don't modify
|
// There's nothing to assign, so don't modify
|
||||||
// a.steps but succeed so the caller doesn't
|
// a.steps but succeed so the caller doesn't
|
||||||
// try to stack-assign this value.
|
// try to stack-assign this value.
|
||||||
return true
|
return true
|
||||||
case 1:
|
case 1:
|
||||||
return a.regAssign(tt.elem, offset)
|
return a.regAssign((*rtype)(tt.Elem), offset)
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,12 +297,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// arrayType represents a fixed array type.
|
// arrayType represents a fixed array type.
|
||||||
type arrayType struct {
|
type arrayType = abi.ArrayType
|
||||||
rtype
|
|
||||||
elem *rtype // array element type
|
|
||||||
slice *rtype // slice type
|
|
||||||
len uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// chanType represents a channel type.
|
// chanType represents a channel type.
|
||||||
type chanType struct {
|
type chanType struct {
|
||||||
|
|
@ -875,7 +870,7 @@ func (t *rtype) Elem() Type {
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return toType(tt.elem)
|
return toType((*rtype)(tt.Elem))
|
||||||
case Chan:
|
case Chan:
|
||||||
tt := (*chanType)(unsafe.Pointer(t))
|
tt := (*chanType)(unsafe.Pointer(t))
|
||||||
return toType(tt.elem)
|
return toType(tt.elem)
|
||||||
|
|
@ -945,7 +940,7 @@ func (t *rtype) Len() int {
|
||||||
panic("reflect: Len of non-array type " + t.String())
|
panic("reflect: Len of non-array type " + t.String())
|
||||||
}
|
}
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return int(tt.len)
|
return int(tt.Len)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *rtype) NumField() int {
|
func (t *rtype) NumField() int {
|
||||||
|
|
@ -2071,7 +2066,7 @@ func isReflexive(t *rtype) bool {
|
||||||
return false
|
return false
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return isReflexive(tt.elem)
|
return isReflexive((*rtype)(tt.Elem))
|
||||||
case Struct:
|
case Struct:
|
||||||
tt := (*structType)(unsafe.Pointer(t))
|
tt := (*structType)(unsafe.Pointer(t))
|
||||||
for _, f := range tt.fields {
|
for _, f := range tt.fields {
|
||||||
|
|
@ -2098,7 +2093,7 @@ func needKeyUpdate(t *rtype) bool {
|
||||||
return true
|
return true
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return needKeyUpdate(tt.elem)
|
return needKeyUpdate((*rtype)(tt.Elem))
|
||||||
case Struct:
|
case Struct:
|
||||||
tt := (*structType)(unsafe.Pointer(t))
|
tt := (*structType)(unsafe.Pointer(t))
|
||||||
for _, f := range tt.fields {
|
for _, f := range tt.fields {
|
||||||
|
|
@ -2120,7 +2115,7 @@ func hashMightPanic(t *rtype) bool {
|
||||||
return true
|
return true
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
return hashMightPanic(tt.elem)
|
return hashMightPanic((*rtype)(tt.Elem))
|
||||||
case Struct:
|
case Struct:
|
||||||
tt := (*structType)(unsafe.Pointer(t))
|
tt := (*structType)(unsafe.Pointer(t))
|
||||||
for _, f := range tt.fields {
|
for _, f := range tt.fields {
|
||||||
|
|
@ -2826,7 +2821,7 @@ func ArrayOf(length int, elem Type) Type {
|
||||||
s := "[" + strconv.Itoa(length) + "]" + typ.String()
|
s := "[" + strconv.Itoa(length) + "]" + typ.String()
|
||||||
for _, tt := range typesByString(s) {
|
for _, tt := range typesByString(s) {
|
||||||
array := (*arrayType)(unsafe.Pointer(tt))
|
array := (*arrayType)(unsafe.Pointer(tt))
|
||||||
if array.elem == typ {
|
if (*rtype)(array.Elem) == typ {
|
||||||
ti, _ := lookupCache.LoadOrStore(ckey, tt)
|
ti, _ := lookupCache.LoadOrStore(ckey, tt)
|
||||||
return ti.(Type)
|
return ti.(Type)
|
||||||
}
|
}
|
||||||
|
|
@ -2843,7 +2838,7 @@ func ArrayOf(length int, elem Type) Type {
|
||||||
array.Hash = fnv1(array.Hash, byte(n))
|
array.Hash = fnv1(array.Hash, byte(n))
|
||||||
}
|
}
|
||||||
array.Hash = fnv1(array.Hash, ']')
|
array.Hash = fnv1(array.Hash, ']')
|
||||||
array.elem = typ
|
array.Elem = (*abi.Type)(typ)
|
||||||
array.PtrToThis = 0
|
array.PtrToThis = 0
|
||||||
if typ.Size_ > 0 {
|
if typ.Size_ > 0 {
|
||||||
max := ^uintptr(0) / typ.Size_
|
max := ^uintptr(0) / typ.Size_
|
||||||
|
|
@ -2857,8 +2852,8 @@ func ArrayOf(length int, elem Type) Type {
|
||||||
}
|
}
|
||||||
array.Align_ = typ.Align_
|
array.Align_ = typ.Align_
|
||||||
array.FieldAlign_ = typ.FieldAlign_
|
array.FieldAlign_ = typ.FieldAlign_
|
||||||
array.len = uintptr(length)
|
array.Len = uintptr(length)
|
||||||
array.slice = SliceOf(elem).(*rtype)
|
array.Slice = (*abi.Type)(SliceOf(elem).(*rtype))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case typ.PtrBytes == 0 || array.Size_ == 0:
|
case typ.PtrBytes == 0 || array.Size_ == 0:
|
||||||
|
|
@ -2880,7 +2875,7 @@ func ArrayOf(length int, elem Type) Type {
|
||||||
// Runtime needs pointer masks to be a multiple of uintptr in size.
|
// Runtime needs pointer masks to be a multiple of uintptr in size.
|
||||||
n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
|
n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
|
||||||
mask := make([]byte, n)
|
mask := make([]byte, n)
|
||||||
emitGCMask(mask, 0, typ, array.len)
|
emitGCMask(mask, 0, typ, array.Len)
|
||||||
array.GCData = &mask[0]
|
array.GCData = &mask[0]
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -2940,7 +2935,7 @@ func ArrayOf(length int, elem Type) Type {
|
||||||
array.Kind_ &^= kindDirectIface
|
array.Kind_ &^= kindDirectIface
|
||||||
}
|
}
|
||||||
|
|
||||||
ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype)
|
ti, _ := lookupCache.LoadOrStore(ckey, (*rtype)(&array.Type))
|
||||||
return ti.(Type)
|
return ti.(Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3084,8 +3079,8 @@ func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
|
||||||
case Array:
|
case Array:
|
||||||
// repeat inner type
|
// repeat inner type
|
||||||
tt := (*arrayType)(unsafe.Pointer(t))
|
tt := (*arrayType)(unsafe.Pointer(t))
|
||||||
for i := 0; i < int(tt.len); i++ {
|
for i := 0; i < int(tt.Len); i++ {
|
||||||
addTypeBits(bv, offset+uintptr(i)*tt.elem.Size_, tt.elem)
|
addTypeBits(bv, offset+uintptr(i)*tt.Elem.Size_, (*rtype)(tt.Elem))
|
||||||
}
|
}
|
||||||
|
|
||||||
case Struct:
|
case Struct:
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ func (v Value) bytesSlow() []byte {
|
||||||
panic("reflect.Value.Bytes of unaddressable byte array")
|
panic("reflect.Value.Bytes of unaddressable byte array")
|
||||||
}
|
}
|
||||||
p := (*byte)(v.ptr)
|
p := (*byte)(v.ptr)
|
||||||
n := int((*arrayType)(unsafe.Pointer(v.typ)).len)
|
n := int((*arrayType)(unsafe.Pointer(v.typ)).Len)
|
||||||
return unsafe.Slice(p, n)
|
return unsafe.Slice(p, n)
|
||||||
}
|
}
|
||||||
panic(&ValueError{"reflect.Value.Bytes", v.kind()})
|
panic(&ValueError{"reflect.Value.Bytes", v.kind()})
|
||||||
|
|
@ -1391,10 +1391,10 @@ func (v Value) Index(i int) Value {
|
||||||
switch v.kind() {
|
switch v.kind() {
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
||||||
if uint(i) >= uint(tt.len) {
|
if uint(i) >= uint(tt.Len) {
|
||||||
panic("reflect: array index out of range")
|
panic("reflect: array index out of range")
|
||||||
}
|
}
|
||||||
typ := tt.elem
|
typ := (*rtype)(tt.Elem)
|
||||||
offset := uintptr(i) * typ.Size_
|
offset := uintptr(i) * typ.Size_
|
||||||
|
|
||||||
// Either flagIndir is set and v.ptr points at array,
|
// Either flagIndir is set and v.ptr points at array,
|
||||||
|
|
@ -1697,7 +1697,7 @@ func (v Value) lenNonSlice() int {
|
||||||
switch k := v.kind(); k {
|
switch k := v.kind(); k {
|
||||||
case Array:
|
case Array:
|
||||||
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
||||||
return int(tt.len)
|
return int(tt.Len)
|
||||||
case Chan:
|
case Chan:
|
||||||
return chanlen(v.pointer())
|
return chanlen(v.pointer())
|
||||||
case Map:
|
case Map:
|
||||||
|
|
@ -2457,8 +2457,8 @@ func (v Value) Slice(i, j int) Value {
|
||||||
panic("reflect.Value.Slice: slice of unaddressable array")
|
panic("reflect.Value.Slice: slice of unaddressable array")
|
||||||
}
|
}
|
||||||
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
||||||
cap = int(tt.len)
|
cap = int(tt.Len)
|
||||||
typ = (*sliceType)(unsafe.Pointer(tt.slice))
|
typ = (*sliceType)(unsafe.Pointer(tt.Slice))
|
||||||
base = v.ptr
|
base = v.ptr
|
||||||
|
|
||||||
case Slice:
|
case Slice:
|
||||||
|
|
@ -2519,8 +2519,8 @@ func (v Value) Slice3(i, j, k int) Value {
|
||||||
panic("reflect.Value.Slice3: slice of unaddressable array")
|
panic("reflect.Value.Slice3: slice of unaddressable array")
|
||||||
}
|
}
|
||||||
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
tt := (*arrayType)(unsafe.Pointer(v.typ))
|
||||||
cap = int(tt.len)
|
cap = int(tt.Len)
|
||||||
typ = (*sliceType)(unsafe.Pointer(tt.slice))
|
typ = (*sliceType)(unsafe.Pointer(tt.Slice))
|
||||||
base = v.ptr
|
base = v.ptr
|
||||||
|
|
||||||
case Slice:
|
case Slice:
|
||||||
|
|
|
||||||
|
|
@ -173,8 +173,8 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
|
||||||
return interhash(p, h)
|
return interhash(p, h)
|
||||||
case kindArray:
|
case kindArray:
|
||||||
a := (*arraytype)(unsafe.Pointer(t))
|
a := (*arraytype)(unsafe.Pointer(t))
|
||||||
for i := uintptr(0); i < a.len; i++ {
|
for i := uintptr(0); i < a.Len; i++ {
|
||||||
h = typehash(a.elem, add(p, i*a.elem.Size_), h)
|
h = typehash((*_type)(a.Elem), add(p, i*a.Elem.Size_), h)
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
case kindStruct:
|
case kindStruct:
|
||||||
|
|
|
||||||
|
|
@ -463,15 +463,15 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
|
||||||
case kindArray:
|
case kindArray:
|
||||||
at := (*arraytype)(unsafe.Pointer(t))
|
at := (*arraytype)(unsafe.Pointer(t))
|
||||||
if !indir {
|
if !indir {
|
||||||
if at.len != 1 {
|
if at.Len != 1 {
|
||||||
throw("can't happen")
|
throw("can't happen")
|
||||||
}
|
}
|
||||||
cgoCheckArg(at.elem, p, at.elem.Kind_&kindDirectIface == 0, top, msg)
|
cgoCheckArg((*_type)(at.Elem), p, at.Elem.Kind_&kindDirectIface == 0, top, msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := uintptr(0); i < at.len; i++ {
|
for i := uintptr(0); i < at.Len; i++ {
|
||||||
cgoCheckArg(at.elem, p, true, top, msg)
|
cgoCheckArg((*_type)(at.Elem), p, true, top, msg)
|
||||||
p = add(p, at.elem.Size_)
|
p = add(p, at.Elem.Size_)
|
||||||
}
|
}
|
||||||
case kindChan, kindMap:
|
case kindChan, kindMap:
|
||||||
// These types contain internal pointers that will
|
// These types contain internal pointers that will
|
||||||
|
|
|
||||||
|
|
@ -247,16 +247,16 @@ func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
|
||||||
throw("can't happen")
|
throw("can't happen")
|
||||||
case kindArray:
|
case kindArray:
|
||||||
at := (*arraytype)(unsafe.Pointer(typ))
|
at := (*arraytype)(unsafe.Pointer(typ))
|
||||||
for i := uintptr(0); i < at.len; i++ {
|
for i := uintptr(0); i < at.Len; i++ {
|
||||||
if off < at.elem.Size_ {
|
if off < at.Elem.Size_ {
|
||||||
cgoCheckUsingType(at.elem, src, off, size)
|
cgoCheckUsingType((*_type)(at.Elem), src, off, size)
|
||||||
}
|
}
|
||||||
src = add(src, at.elem.Size_)
|
src = add(src, at.Elem.Size_)
|
||||||
skipped := off
|
skipped := off
|
||||||
if skipped > at.elem.Size_ {
|
if skipped > at.Elem.Size_ {
|
||||||
skipped = at.elem.Size_
|
skipped = at.Elem.Size_
|
||||||
}
|
}
|
||||||
checked := at.elem.Size_ - skipped
|
checked := at.Elem.Size_ - skipped
|
||||||
off -= skipped
|
off -= skipped
|
||||||
if size <= checked {
|
if size <= checked {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,8 @@ func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
|
||||||
}
|
}
|
||||||
case kindArray:
|
case kindArray:
|
||||||
at := (*arraytype)(unsafe.Pointer(t))
|
at := (*arraytype)(unsafe.Pointer(t))
|
||||||
if at.len == 1 {
|
if at.Len == 1 {
|
||||||
return p.tryRegAssignArg(at.elem, offset)
|
return p.tryRegAssignArg((*_type)(at.Elem), offset)
|
||||||
}
|
}
|
||||||
case kindStruct:
|
case kindStruct:
|
||||||
st := (*structtype)(unsafe.Pointer(t))
|
st := (*structtype)(unsafe.Pointer(t))
|
||||||
|
|
|
||||||
|
|
@ -332,12 +332,7 @@ func (mt *maptype) hashMightPanic() bool { // true if hash function might panic
|
||||||
return mt.flags&16 != 0
|
return mt.flags&16 != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type arraytype struct {
|
type arraytype = abi.ArrayType
|
||||||
typ _type
|
|
||||||
elem *_type
|
|
||||||
slice *_type
|
|
||||||
len uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type chantype struct {
|
type chantype struct {
|
||||||
typ _type
|
typ _type
|
||||||
|
|
@ -559,7 +554,7 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
|
||||||
case kindArray:
|
case kindArray:
|
||||||
at := (*arraytype)(unsafe.Pointer(t))
|
at := (*arraytype)(unsafe.Pointer(t))
|
||||||
av := (*arraytype)(unsafe.Pointer(v))
|
av := (*arraytype)(unsafe.Pointer(v))
|
||||||
return typesEqual(at.elem, av.elem, seen) && at.len == av.len
|
return typesEqual((*_type)(at.Elem), (*_type)(av.Elem), seen) && at.Len == av.Len
|
||||||
case kindChan:
|
case kindChan:
|
||||||
ct := (*chantype)(unsafe.Pointer(t))
|
ct := (*chantype)(unsafe.Pointer(t))
|
||||||
cv := (*chantype)(unsafe.Pointer(v))
|
cv := (*chantype)(unsafe.Pointer(v))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue