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:
David Chase 2023-02-07 17:43:34 -05:00
parent 3f9521b2f0
commit a851511947
12 changed files with 49 additions and 64 deletions

View File

@ -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",

View File

@ -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,

View File

@ -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 {

View File

@ -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:

View File

@ -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
} }

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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))