github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/internal/abi/type.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package abi 6 7 import ( 8 "github.com/shogo82148/std/unsafe" 9 ) 10 11 // Type is the runtime representation of a Go type. 12 // 13 // Be careful about accessing this type at build time, as the version 14 // of this type in the compiler/linker may not have the same layout 15 // as the version in the target binary, due to pointer width 16 // differences and any experiments. Use cmd/compile/internal/rttype 17 // or the functions in compiletype.go to access this type instead. 18 // (TODO: this admonition applies to every type in this package. 19 // Put it in some shared location?) 20 type Type struct { 21 Size_ uintptr 22 PtrBytes uintptr 23 Hash uint32 24 TFlag TFlag 25 Align_ uint8 26 FieldAlign_ uint8 27 Kind_ uint8 28 // function for comparing objects of this type 29 // (ptr to object A, ptr to object B) -> ==? 30 Equal func(unsafe.Pointer, unsafe.Pointer) bool 31 // GCData stores the GC type data for the garbage collector. 32 // If the KindGCProg bit is set in kind, GCData is a GC program. 33 // Otherwise it is a ptrmask bitmap. See mbitmap.go for details. 34 GCData *byte 35 Str NameOff 36 PtrToThis TypeOff 37 } 38 39 // A Kind represents the specific kind of type that a Type represents. 40 // The zero Kind is not a valid kind. 41 type Kind uint 42 43 const ( 44 Invalid Kind = iota 45 Bool 46 Int 47 Int8 48 Int16 49 Int32 50 Int64 51 Uint 52 Uint8 53 Uint16 54 Uint32 55 Uint64 56 Uintptr 57 Float32 58 Float64 59 Complex64 60 Complex128 61 Array 62 Chan 63 Func 64 Interface 65 Map 66 Pointer 67 Slice 68 String 69 Struct 70 UnsafePointer 71 ) 72 73 const ( 74 // TODO (khr, drchase) why aren't these in TFlag? Investigate, fix if possible. 75 KindDirectIface = 1 << 5 76 KindGCProg = 1 << 6 77 KindMask = (1 << 5) - 1 78 ) 79 80 // TFlag is used by a Type to signal what extra type information is 81 // available in the memory directly following the Type value. 82 type TFlag uint8 83 84 const ( 85 // TFlagUncommon means that there is a data with a type, UncommonType, 86 // just beyond the shared-per-type common data. That is, the data 87 // for struct types will store their UncommonType at one offset, the 88 // data for interface types will store their UncommonType at a different 89 // offset. UncommonType is always accessed via a pointer that is computed 90 // using trust-us-we-are-the-implementors pointer arithmetic. 91 // 92 // For example, if t.Kind() == Struct and t.tflag&TFlagUncommon != 0, 93 // then t has UncommonType data and it can be accessed as: 94 // 95 // type structTypeUncommon struct { 96 // structType 97 // u UncommonType 98 // } 99 // u := &(*structTypeUncommon)(unsafe.Pointer(t)).u 100 TFlagUncommon TFlag = 1 << 0 101 102 // TFlagExtraStar means the name in the str field has an 103 // extraneous '*' prefix. This is because for most types T in 104 // a program, the type *T also exists and reusing the str data 105 // saves binary size. 106 TFlagExtraStar TFlag = 1 << 1 107 108 // TFlagNamed means the type has a name. 109 TFlagNamed TFlag = 1 << 2 110 111 // TFlagRegularMemory means that equal and hash functions can treat 112 // this type as a single region of t.size bytes. 113 TFlagRegularMemory TFlag = 1 << 3 114 115 // TFlagUnrolledBitmap marks special types that are unrolled-bitmap 116 // versions of types with GC programs. 117 // These types need to be deallocated when the underlying object 118 // is freed. 119 TFlagUnrolledBitmap TFlag = 1 << 4 120 ) 121 122 // NameOff is the offset to a name from moduledata.types. See resolveNameOff in runtime. 123 type NameOff int32 124 125 // TypeOff is the offset to a type from moduledata.types. See resolveTypeOff in runtime. 126 type TypeOff int32 127 128 // TextOff is an offset from the top of a text section. See (rtype).textOff in runtime. 129 type TextOff int32 130 131 // String returns the name of k. 132 func (k Kind) String() string 133 134 func (t *Type) Kind() Kind 135 136 func (t *Type) HasName() bool 137 138 // Pointers reports whether t contains pointers. 139 func (t *Type) Pointers() bool 140 141 // IfaceIndir reports whether t is stored indirectly in an interface value. 142 func (t *Type) IfaceIndir() bool 143 144 // isDirectIface reports whether t is stored directly in an interface value. 145 func (t *Type) IsDirectIface() bool 146 147 func (t *Type) GcSlice(begin, end uintptr) []byte 148 149 // Method on non-interface type 150 type Method struct { 151 Name NameOff 152 Mtyp TypeOff 153 Ifn TextOff 154 Tfn TextOff 155 } 156 157 // UncommonType is present only for defined types or types with methods 158 // (if T is a defined type, the uncommonTypes for T and *T have methods). 159 // Using a pointer to this struct reduces the overall size required 160 // to describe a non-defined type with no methods. 161 type UncommonType struct { 162 PkgPath NameOff 163 Mcount uint16 164 Xcount uint16 165 Moff uint32 166 _ uint32 167 } 168 169 func (t *UncommonType) Methods() []Method 170 171 func (t *UncommonType) ExportedMethods() []Method 172 173 // Imethod represents a method on an interface type 174 type Imethod struct { 175 Name NameOff 176 Typ TypeOff 177 } 178 179 // ArrayType represents a fixed array type. 180 type ArrayType struct { 181 Type 182 Elem *Type 183 Slice *Type 184 Len uintptr 185 } 186 187 // Len returns the length of t if t is an array type, otherwise 0 188 func (t *Type) Len() int 189 190 func (t *Type) Common() *Type 191 192 type ChanDir int 193 194 const ( 195 RecvDir ChanDir = 1 << iota 196 SendDir 197 BothDir = RecvDir | SendDir 198 InvalidDir ChanDir = 0 199 ) 200 201 // ChanType represents a channel type 202 type ChanType struct { 203 Type 204 Elem *Type 205 Dir ChanDir 206 } 207 208 // ChanDir returns the direction of t if t is a channel type, otherwise InvalidDir (0). 209 func (t *Type) ChanDir() ChanDir 210 211 // Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil 212 func (t *Type) Uncommon() *UncommonType 213 214 // Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil. 215 func (t *Type) Elem() *Type 216 217 // StructType returns t cast to a *StructType, or nil if its tag does not match. 218 func (t *Type) StructType() *StructType 219 220 // MapType returns t cast to a *MapType, or nil if its tag does not match. 221 func (t *Type) MapType() *MapType 222 223 // ArrayType returns t cast to a *ArrayType, or nil if its tag does not match. 224 func (t *Type) ArrayType() *ArrayType 225 226 // FuncType returns t cast to a *FuncType, or nil if its tag does not match. 227 func (t *Type) FuncType() *FuncType 228 229 // InterfaceType returns t cast to a *InterfaceType, or nil if its tag does not match. 230 func (t *Type) InterfaceType() *InterfaceType 231 232 // Size returns the size of data with type t. 233 func (t *Type) Size() uintptr 234 235 // Align returns the alignment of data with type t. 236 func (t *Type) Align() int 237 238 func (t *Type) FieldAlign() int 239 240 type InterfaceType struct { 241 Type 242 PkgPath Name 243 Methods []Imethod 244 } 245 246 func (t *Type) ExportedMethods() []Method 247 248 func (t *Type) NumMethod() int 249 250 // NumMethod returns the number of interface methods in the type's method set. 251 func (t *InterfaceType) NumMethod() int 252 253 type MapType struct { 254 Type 255 Key *Type 256 Elem *Type 257 Bucket *Type 258 // function for hashing keys (ptr to key, seed) -> hash 259 Hasher func(unsafe.Pointer, uintptr) uintptr 260 KeySize uint8 261 ValueSize uint8 262 BucketSize uint16 263 Flags uint32 264 } 265 266 // Note: flag values must match those used in the TMAP case 267 // in ../cmd/compile/internal/reflectdata/reflect.go:writeType. 268 func (mt *MapType) IndirectKey() bool 269 270 func (mt *MapType) IndirectElem() bool 271 272 func (mt *MapType) ReflexiveKey() bool 273 274 func (mt *MapType) NeedKeyUpdate() bool 275 276 func (mt *MapType) HashMightPanic() bool 277 278 func (t *Type) Key() *Type 279 280 type SliceType struct { 281 Type 282 Elem *Type 283 } 284 285 // funcType represents a function type. 286 // 287 // A *Type for each in and out parameter is stored in an array that 288 // directly follows the funcType (and possibly its uncommonType). So 289 // a function type with one method, one input, and one output is: 290 // 291 // struct { 292 // funcType 293 // uncommonType 294 // [2]*rtype // [0] is in, [1] is out 295 // } 296 type FuncType struct { 297 Type 298 InCount uint16 299 OutCount uint16 300 } 301 302 func (t *FuncType) In(i int) *Type 303 304 func (t *FuncType) NumIn() int 305 306 func (t *FuncType) NumOut() int 307 308 func (t *FuncType) Out(i int) *Type 309 310 func (t *FuncType) InSlice() []*Type 311 312 func (t *FuncType) OutSlice() []*Type 313 314 func (t *FuncType) IsVariadic() bool 315 316 type PtrType struct { 317 Type 318 Elem *Type 319 } 320 321 type StructField struct { 322 Name Name 323 Typ *Type 324 Offset uintptr 325 } 326 327 func (f *StructField) Embedded() bool 328 329 type StructType struct { 330 Type 331 PkgPath Name 332 Fields []StructField 333 } 334 335 type Name struct { 336 Bytes *byte 337 } 338 339 // DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to 340 // be safe for the reason in whySafe (which can appear in a backtrace, etc.) 341 func (n Name) DataChecked(off int, whySafe string) *byte 342 343 // Data does pointer arithmetic on n's Bytes, and that arithmetic is asserted to 344 // be safe because the runtime made the call (other packages use DataChecked) 345 func (n Name) Data(off int) *byte 346 347 // IsExported returns "is n exported?" 348 func (n Name) IsExported() bool 349 350 // HasTag returns true iff there is tag data following this name 351 func (n Name) HasTag() bool 352 353 // IsEmbedded returns true iff n is embedded (an anonymous field). 354 func (n Name) IsEmbedded() bool 355 356 // ReadVarint parses a varint as encoded by encoding/binary. 357 // It returns the number of encoded bytes and the encoded value. 358 func (n Name) ReadVarint(off int) (int, int) 359 360 // IsBlank indicates whether n is "_". 361 func (n Name) IsBlank() bool 362 363 // Name returns the tag string for n, or empty if there is none. 364 func (n Name) Name() string 365 366 // Tag returns the tag string for n, or empty if there is none. 367 func (n Name) Tag() string 368 369 func NewName(n, tag string, exported, embedded bool) Name 370 371 const ( 372 TraceArgsLimit = 10 373 TraceArgsMaxDepth = 5 374 375 // maxLen is a (conservative) upper bound of the byte stream length. For 376 // each arg/component, it has no more than 2 bytes of data (size, offset), 377 // and no more than one {, }, ... at each level (it cannot have both the 378 // data and ... unless it is the last one, just be conservative). Plus 1 379 // for _endSeq. 380 TraceArgsMaxLen = (TraceArgsMaxDepth*3+2)*TraceArgsLimit + 1 381 ) 382 383 // Populate the data. 384 // The data is a stream of bytes, which contains the offsets and sizes of the 385 // non-aggregate arguments or non-aggregate fields/elements of aggregate-typed 386 // arguments, along with special "operators". Specifically, 387 // - for each non-aggregate arg/field/element, its offset from FP (1 byte) and 388 // size (1 byte) 389 // - special operators: 390 // - 0xff - end of sequence 391 // - 0xfe - print { (at the start of an aggregate-typed argument) 392 // - 0xfd - print } (at the end of an aggregate-typed argument) 393 // - 0xfc - print ... (more args/fields/elements) 394 // - 0xfb - print _ (offset too large) 395 const ( 396 TraceArgsEndSeq = 0xff 397 TraceArgsStartAgg = 0xfe 398 TraceArgsEndAgg = 0xfd 399 TraceArgsDotdotdot = 0xfc 400 TraceArgsOffsetTooLarge = 0xfb 401 TraceArgsSpecial = 0xf0 402 ) 403 404 // MaxPtrmaskBytes is the maximum length of a GC ptrmask bitmap, 405 // which holds 1-bit entries describing where pointers are in a given type. 406 // Above this length, the GC information is recorded as a GC program, 407 // which can express repetition compactly. In either form, the 408 // information is used by the runtime to initialize the heap bitmap, 409 // and for large types (like 128 or more words), they are roughly the 410 // same speed. GC programs are never much larger and often more 411 // compact. (If large arrays are involved, they can be arbitrarily 412 // more compact.) 413 // 414 // The cutoff must be large enough that any allocation large enough to 415 // use a GC program is large enough that it does not share heap bitmap 416 // bytes with any other objects, allowing the GC program execution to 417 // assume an aligned start and not use atomic operations. In the current 418 // runtime, this means all malloc size classes larger than the cutoff must 419 // be multiples of four words. On 32-bit systems that's 16 bytes, and 420 // all size classes >= 16 bytes are 16-byte aligned, so no real constraint. 421 // On 64-bit systems, that's 32 bytes, and 32-byte alignment is guaranteed 422 // for size classes >= 256 bytes. On a 64-bit system, 256 bytes allocated 423 // is 32 pointers, the bits for which fit in 4 bytes. So MaxPtrmaskBytes 424 // must be >= 4. 425 // 426 // We used to use 16 because the GC programs do have some constant overhead 427 // to get started, and processing 128 pointers seems to be enough to 428 // amortize that overhead well. 429 // 430 // To make sure that the runtime's chansend can call typeBitsBulkBarrier, 431 // we raised the limit to 2048, so that even 32-bit systems are guaranteed to 432 // use bitmaps for objects up to 64 kB in size. 433 const MaxPtrmaskBytes = 2048