Skip to content

Commit f7d167f

Browse files
committed
internal/abi: move direct/indirect flag from Kind to TFlag
This info makes more sense in the flags instead of as a high bit of the kind. This makes kind access simpler because we now don't need to mask anything. Cleaned up most direct field accesses to use methods instead. (reflect making new types is the only remaining direct accessor.) IfaceIndir -> !IsDirectIface everywhere. gocore has been updated to handle the new location. So has delve. TODO: any other tools need updating? Change-Id: I123f97a4d4bdd0bff1641ee7e276d1cc0bd7e8eb Reviewed-on: https://go-review.googlesource.com/c/go/+/681936 Reviewed-by: Keith Randall <[email protected]> Reviewed-by: David Chase <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent e0b07dc commit f7d167f

29 files changed

+95
-110
lines changed

src/cmd/compile/internal/reflectdata/reflect.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
491491
exported = types.IsExported(t.Elem().Sym().Name)
492492
}
493493
}
494+
if types.IsDirectIface(t) {
495+
tflag |= abi.TFlagDirectIface
496+
}
494497

495498
if tflag != abi.TFlag(uint8(tflag)) {
496499
// this should optimize away completely
@@ -511,9 +514,6 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
511514
c.Field("FieldAlign_").WriteUint8(uint8(t.Alignment()))
512515

513516
kind := kinds[t.Kind()]
514-
if types.IsDirectIface(t) {
515-
kind |= abi.KindDirectIface
516-
}
517517
c.Field("Kind_").WriteUint8(uint8(kind))
518518

519519
c.Field("Equal").WritePtr(eqfunc)

src/cmd/compile/internal/test/inl_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ func TestIntendedInlining(t *testing.T) {
4747
"getMCache",
4848
"heapSetTypeNoHeader",
4949
"heapSetTypeSmallHeader",
50-
"isDirectIface",
5150
"itabHashFunc",
5251
"nextslicecap",
5352
"noescape",
@@ -109,6 +108,7 @@ func TestIntendedInlining(t *testing.T) {
109108
"(*Buffer).tryGrowByReslice",
110109
},
111110
"internal/abi": {
111+
"(*Type).IsDirectIface",
112112
"UseInterfaceSwitchCache",
113113
},
114114
"internal/runtime/math": {

src/cmd/link/internal/ld/decodesym.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func uncommonSize(arch *sys.Arch) int { return int(abi.UncommonSize()) }
3838

3939
// Type.commonType.kind
4040
func decodetypeKind(arch *sys.Arch, p []byte) abi.Kind {
41-
return abi.Kind(p[2*arch.PtrSize+7]) & abi.KindMask // 0x13 / 0x1f
41+
return abi.Kind(p[2*arch.PtrSize+7]) // 0x13
4242
}
4343

4444
// Type.commonType.size

src/internal/abi/type.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type Type struct {
2424
TFlag TFlag // extra type information flags
2525
Align_ uint8 // alignment of variable with this type
2626
FieldAlign_ uint8 // alignment of struct field with this type
27-
Kind_ Kind // enumeration for C
27+
Kind_ Kind // what kind of type this is (string, int, ...)
2828
// function for comparing objects of this type
2929
// (ptr to object A, ptr to object B) -> ==?
3030
Equal func(unsafe.Pointer, unsafe.Pointer) bool
@@ -78,12 +78,6 @@ const (
7878
UnsafePointer
7979
)
8080

81-
const (
82-
// TODO (khr, drchase) why aren't these in TFlag? Investigate, fix if possible.
83-
KindDirectIface Kind = 1 << 5
84-
KindMask Kind = (1 << 5) - 1
85-
)
86-
8781
// TFlag is used by a Type to signal what extra type information is
8882
// available in the memory directly following the Type value.
8983
type TFlag uint8
@@ -125,6 +119,15 @@ const (
125119
// has type **byte instead of *byte. The runtime will store a
126120
// pointer to the GC pointer bitmask in *GCData.
127121
TFlagGCMaskOnDemand TFlag = 1 << 4
122+
123+
// TFlagDirectIface means that a value of this type is stored directly
124+
// in the data field of an interface, instead of indirectly. Normally
125+
// this means the type is pointer-ish.
126+
TFlagDirectIface TFlag = 1 << 5
127+
128+
// Leaving this breadcrumb behind for dlv. It should not be used, and no
129+
// Kind should be big enough to set this bit.
130+
KindDirectIface Kind = 1 << 5
128131
)
129132

130133
// NameOff is the offset to a name from moduledata.types. See resolveNameOff in runtime.
@@ -190,7 +193,7 @@ func TypeFor[T any]() *Type {
190193
return (*PtrType)(unsafe.Pointer(TypeOf((*T)(nil)))).Elem
191194
}
192195

193-
func (t *Type) Kind() Kind { return t.Kind_ & KindMask }
196+
func (t *Type) Kind() Kind { return t.Kind_ }
194197

195198
func (t *Type) HasName() bool {
196199
return t.TFlag&TFlagNamed != 0
@@ -199,14 +202,9 @@ func (t *Type) HasName() bool {
199202
// Pointers reports whether t contains pointers.
200203
func (t *Type) Pointers() bool { return t.PtrBytes != 0 }
201204

202-
// IfaceIndir reports whether t is stored indirectly in an interface value.
203-
func (t *Type) IfaceIndir() bool {
204-
return t.Kind_&KindDirectIface == 0
205-
}
206-
207-
// isDirectIface reports whether t is stored directly in an interface value.
205+
// IsDirectIface reports whether t is stored directly in an interface value.
208206
func (t *Type) IsDirectIface() bool {
209-
return t.Kind_&KindDirectIface != 0
207+
return t.TFlag&TFlagDirectIface != 0
210208
}
211209

212210
func (t *Type) GcSlice(begin, end uintptr) []byte {

src/internal/reflectlite/export_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func Zero(typ Type) Value {
7070
}
7171
t := typ.common()
7272
fl := flag(t.Kind())
73-
if t.IfaceIndir() {
73+
if !t.IsDirectIface() {
7474
return Value{t, unsafe_New(t), fl | flagIndir}
7575
}
7676
return Value{t, nil, fl}

src/internal/reflectlite/value.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type Value struct {
5252
// - flagIndir: val holds a pointer to the data
5353
// - flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
5454
// - flagMethod: v is a method value.
55-
// If ifaceIndir(typ), code can assume that flagIndir is set.
55+
// If !typ.IsDirectIface(), code can assume that flagIndir is set.
5656
//
5757
// The remaining 22+ bits give a method number for method values.
5858
// If flag.kind() != Func, code can assume that flagMethod is unset.
@@ -118,7 +118,7 @@ func packEface(v Value) any {
118118
e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
119119
// First, fill in the data portion of the interface.
120120
switch {
121-
case t.IfaceIndir():
121+
case !t.IsDirectIface():
122122
if v.flag&flagIndir == 0 {
123123
panic("bad indir")
124124
}
@@ -155,7 +155,7 @@ func unpackEface(i any) Value {
155155
return Value{}
156156
}
157157
f := flag(t.Kind())
158-
if t.IfaceIndir() {
158+
if !t.IsDirectIface() {
159159
f |= flagIndir
160160
}
161161
return Value{t, e.Data, f}

src/internal/runtime/maps/map.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ func mapKeyError2(t *abi.Type, p unsafe.Pointer) error {
859859
return unhashableTypeError{t}
860860
}
861861

862-
if t.Kind_&abi.KindDirectIface != 0 {
862+
if t.IsDirectIface() {
863863
return mapKeyError2(t, unsafe.Pointer(pdata))
864864
} else {
865865
return mapKeyError2(t, *pdata)

src/reflect/abi.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func (a *abiSeq) addRcvr(rcvr *abi.Type) (*abiStep, bool) {
166166
// The receiver is always one word.
167167
a.valueStart = append(a.valueStart, len(a.steps))
168168
var ok, ptr bool
169-
if rcvr.IfaceIndir() || rcvr.Pointers() {
169+
if !rcvr.IsDirectIface() || rcvr.Pointers() {
170170
ok = a.assignIntN(0, goarch.PtrSize, 1, 0b1)
171171
ptr = true
172172
} else {

src/reflect/badlinkname.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
//
2828
//go:linkname unusedIfaceIndir reflect.ifaceIndir
2929
func unusedIfaceIndir(t *abi.Type) bool {
30-
return t.Kind_&abi.KindDirectIface == 0
30+
return !t.IsDirectIface()
3131
}
3232

3333
//go:linkname valueInterface

src/reflect/export_noswiss_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
package reflect
88

99
import (
10-
"internal/abi"
1110
"unsafe"
1211
)
1312

@@ -17,7 +16,7 @@ func MapBucketOf(x, y Type) Type {
1716

1817
func CachedBucketOf(m Type) Type {
1918
t := m.(*rtype)
20-
if Kind(t.t.Kind_&abi.KindMask) != Map {
19+
if Kind(t.t.Kind()) != Map {
2120
panic("not map")
2221
}
2322
tt := (*mapType)(unsafe.Pointer(t))

0 commit comments

Comments
 (0)