Source file src/internal/abi/type.go

     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  	"internal/goarch"
     9  	"unsafe"
    10  )
    11  
    12  // Type is the runtime representation of a Go type.
    13  //
    14  // Be careful about accessing this type at build time, as the version
    15  // of this type in the compiler/linker may not have the same layout
    16  // as the version in the target binary, due to pointer width
    17  // differences and any experiments. Use cmd/compile/internal/rttype
    18  // or the functions in compiletype.go to access this type instead.
    19  // (TODO: this admonition applies to every type in this package.
    20  // Put it in some shared location?)
    21  type Type struct {
    22  	Size_       uintptr
    23  	PtrBytes    uintptr // number of (prefix) bytes in the type that can contain pointers
    24  	Hash        uint32  // hash of type; avoids computation in hash tables
    25  	TFlag       TFlag   // extra type information flags
    26  	Align_      uint8   // alignment of variable with this type
    27  	FieldAlign_ uint8   // alignment of struct field with this type
    28  	Kind_       Kind    // what kind of type this is (string, int, ...)
    29  	// function for comparing objects of this type
    30  	// (ptr to object A, ptr to object B) -> ==?
    31  	Equal func(unsafe.Pointer, unsafe.Pointer) bool
    32  	// GCData stores the GC type data for the garbage collector.
    33  	// Normally, GCData points to a bitmask that describes the
    34  	// ptr/nonptr fields of the type. The bitmask will have at
    35  	// least PtrBytes/ptrSize bits.
    36  	// If the TFlagGCMaskOnDemand bit is set, GCData is instead a
    37  	// **byte and the pointer to the bitmask is one dereference away.
    38  	// The runtime will build the bitmask if needed.
    39  	// (See runtime/type.go:getGCMask.)
    40  	// Note: multiple types may have the same value of GCData,
    41  	// including when TFlagGCMaskOnDemand is set. The types will, of course,
    42  	// have the same pointer layout (but not necessarily the same size).
    43  	GCData    *byte
    44  	Str       NameOff // string form
    45  	PtrToThis TypeOff // type for pointer to this type, may be zero
    46  }
    47  
    48  // A Kind represents the specific kind of type that a Type represents.
    49  // The zero Kind is not a valid kind.
    50  type Kind uint8
    51  
    52  const (
    53  	Invalid Kind = iota
    54  	Bool
    55  	Int
    56  	Int8
    57  	Int16
    58  	Int32
    59  	Int64
    60  	Uint
    61  	Uint8
    62  	Uint16
    63  	Uint32
    64  	Uint64
    65  	Uintptr
    66  	Float32
    67  	Float64
    68  	Complex64
    69  	Complex128
    70  	Array
    71  	Chan
    72  	Func
    73  	Interface
    74  	Map
    75  	Pointer
    76  	Slice
    77  	String
    78  	Struct
    79  	UnsafePointer
    80  )
    81  
    82  // TFlag is used by a Type to signal what extra type information is
    83  // available in the memory directly following the Type value.
    84  type TFlag uint8
    85  
    86  const (
    87  	// TFlagUncommon means that there is a data with a type, UncommonType,
    88  	// just beyond the shared-per-type common data.  That is, the data
    89  	// for struct types will store their UncommonType at one offset, the
    90  	// data for interface types will store their UncommonType at a different
    91  	// offset.  UncommonType is always accessed via a pointer that is computed
    92  	// using trust-us-we-are-the-implementors pointer arithmetic.
    93  	//
    94  	// For example, if t.Kind() == Struct and t.tflag&TFlagUncommon != 0,
    95  	// then t has UncommonType data and it can be accessed as:
    96  	//
    97  	//	type structTypeUncommon struct {
    98  	//		structType
    99  	//		u UncommonType
   100  	//	}
   101  	//	u := &(*structTypeUncommon)(unsafe.Pointer(t)).u
   102  	TFlagUncommon TFlag = 1 << 0
   103  
   104  	// TFlagExtraStar means the name in the str field has an
   105  	// extraneous '*' prefix. This is because for most types T in
   106  	// a program, the type *T also exists and reusing the str data
   107  	// saves binary size.
   108  	TFlagExtraStar TFlag = 1 << 1
   109  
   110  	// TFlagNamed means the type has a name.
   111  	TFlagNamed TFlag = 1 << 2
   112  
   113  	// TFlagRegularMemory means that equal and hash functions can treat
   114  	// this type as a single region of t.size bytes.
   115  	TFlagRegularMemory TFlag = 1 << 3
   116  
   117  	// TFlagGCMaskOnDemand means that the GC pointer bitmask will be
   118  	// computed on demand at runtime instead of being precomputed at
   119  	// compile time. If this flag is set, the GCData field effectively
   120  	// has type **byte instead of *byte. The runtime will store a
   121  	// pointer to the GC pointer bitmask in *GCData.
   122  	TFlagGCMaskOnDemand TFlag = 1 << 4
   123  
   124  	// TFlagDirectIface means that a value of this type is stored directly
   125  	// in the data field of an interface, instead of indirectly.
   126  	// This flag is just a cached computation of Size_ == PtrBytes == goarch.PtrSize.
   127  	TFlagDirectIface TFlag = 1 << 5
   128  
   129  	// Leaving this breadcrumb behind for dlv. It should not be used, and no
   130  	// Kind should be big enough to set this bit.
   131  	KindDirectIface Kind = 1 << 5
   132  )
   133  
   134  // NameOff is the offset to a name from moduledata.types.  See resolveNameOff in runtime.
   135  type NameOff int32
   136  
   137  // TypeOff is the offset to a type from moduledata.types.  See resolveTypeOff in runtime.
   138  type TypeOff int32
   139  
   140  // TextOff is an offset from the top of a text section.  See (rtype).textOff in runtime.
   141  type TextOff int32
   142  
   143  // String returns the name of k.
   144  func (k Kind) String() string {
   145  	if int(k) < len(kindNames) {
   146  		return kindNames[k]
   147  	}
   148  	return kindNames[0]
   149  }
   150  
   151  var kindNames = []string{
   152  	Invalid:       "invalid",
   153  	Bool:          "bool",
   154  	Int:           "int",
   155  	Int8:          "int8",
   156  	Int16:         "int16",
   157  	Int32:         "int32",
   158  	Int64:         "int64",
   159  	Uint:          "uint",
   160  	Uint8:         "uint8",
   161  	Uint16:        "uint16",
   162  	Uint32:        "uint32",
   163  	Uint64:        "uint64",
   164  	Uintptr:       "uintptr",
   165  	Float32:       "float32",
   166  	Float64:       "float64",
   167  	Complex64:     "complex64",
   168  	Complex128:    "complex128",
   169  	Array:         "array",
   170  	Chan:          "chan",
   171  	Func:          "func",
   172  	Interface:     "interface",
   173  	Map:           "map",
   174  	Pointer:       "ptr",
   175  	Slice:         "slice",
   176  	String:        "string",
   177  	Struct:        "struct",
   178  	UnsafePointer: "unsafe.Pointer",
   179  }
   180  
   181  // TypeOf returns the abi.Type of some value.
   182  func TypeOf(a any) *Type {
   183  	eface := *(*EmptyInterface)(unsafe.Pointer(&a))
   184  	// Types are either static (for compiler-created types) or
   185  	// heap-allocated but always reachable (for reflection-created
   186  	// types, held in the central map). So there is no need to
   187  	// escape types. noescape here help avoid unnecessary escape
   188  	// of v.
   189  	return (*Type)(NoEscape(unsafe.Pointer(eface.Type)))
   190  }
   191  
   192  // TypeFor returns the abi.Type for a type parameter.
   193  func TypeFor[T any]() *Type {
   194  	return (*PtrType)(unsafe.Pointer(TypeOf((*T)(nil)))).Elem
   195  }
   196  
   197  func (t *Type) Kind() Kind { return t.Kind_ }
   198  
   199  func (t *Type) HasName() bool {
   200  	return t.TFlag&TFlagNamed != 0
   201  }
   202  
   203  // Pointers reports whether t contains pointers.
   204  func (t *Type) Pointers() bool { return t.PtrBytes != 0 }
   205  
   206  // IsDirectIface reports whether t is stored directly in an interface value.
   207  func (t *Type) IsDirectIface() bool {
   208  	return t.TFlag&TFlagDirectIface != 0
   209  }
   210  
   211  func (t *Type) GcSlice(begin, end uintptr) []byte {
   212  	if t.TFlag&TFlagGCMaskOnDemand != 0 {
   213  		panic("GcSlice can't handle on-demand gcdata types")
   214  	}
   215  	return unsafe.Slice(t.GCData, int(end))[begin:]
   216  }
   217  
   218  // Method on non-interface type
   219  type Method struct {
   220  	Name NameOff // name of method
   221  	Mtyp TypeOff // method type (without receiver)
   222  	Ifn  TextOff // fn used in interface call (one-word receiver)
   223  	Tfn  TextOff // fn used for normal method call
   224  }
   225  
   226  // UncommonType is present only for defined types or types with methods
   227  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   228  // Using a pointer to this struct reduces the overall size required
   229  // to describe a non-defined type with no methods.
   230  type UncommonType struct {
   231  	PkgPath NameOff // import path; empty for built-in types like int, string
   232  	Mcount  uint16  // number of methods
   233  	Xcount  uint16  // number of exported methods
   234  	Moff    uint32  // offset from this uncommontype to [mcount]Method
   235  	_       uint32  // unused
   236  }
   237  
   238  func (t *UncommonType) Methods() []Method {
   239  	if t.Mcount == 0 {
   240  		return nil
   241  	}
   242  	return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0"))[:t.Mcount:t.Mcount]
   243  }
   244  
   245  func (t *UncommonType) ExportedMethods() []Method {
   246  	if t.Xcount == 0 {
   247  		return nil
   248  	}
   249  	return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0"))[:t.Xcount:t.Xcount]
   250  }
   251  
   252  // addChecked returns p+x.
   253  //
   254  // The whySafe string is ignored, so that the function still inlines
   255  // as efficiently as p+x, but all call sites should use the string to
   256  // record why the addition is safe, which is to say why the addition
   257  // does not cause x to advance to the very end of p's allocation
   258  // and therefore point incorrectly at the next block in memory.
   259  func addChecked(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
   260  	return unsafe.Pointer(uintptr(p) + x)
   261  }
   262  
   263  // Imethod represents a method on an interface type
   264  type Imethod struct {
   265  	Name NameOff // name of method
   266  	Typ  TypeOff // .(*FuncType) underneath
   267  }
   268  
   269  // ArrayType represents a fixed array type.
   270  type ArrayType struct {
   271  	Type
   272  	Elem  *Type // array element type
   273  	Slice *Type // slice type
   274  	Len   uintptr
   275  }
   276  
   277  // Len returns the length of t if t is an array type, otherwise 0
   278  func (t *Type) Len() int {
   279  	if t.Kind() == Array {
   280  		return int((*ArrayType)(unsafe.Pointer(t)).Len)
   281  	}
   282  	return 0
   283  }
   284  
   285  func (t *Type) Common() *Type {
   286  	return t
   287  }
   288  
   289  type ChanDir int
   290  
   291  const (
   292  	RecvDir    ChanDir = 1 << iota         // <-chan
   293  	SendDir                                // chan<-
   294  	BothDir            = RecvDir | SendDir // chan
   295  	InvalidDir ChanDir = 0
   296  )
   297  
   298  // ChanType represents a channel type
   299  type ChanType struct {
   300  	Type
   301  	Elem *Type
   302  	Dir  ChanDir
   303  }
   304  
   305  type structTypeUncommon struct {
   306  	StructType
   307  	u UncommonType
   308  }
   309  
   310  // ChanDir returns the direction of t if t is a channel type, otherwise InvalidDir (0).
   311  func (t *Type) ChanDir() ChanDir {
   312  	if t.Kind() == Chan {
   313  		ch := (*ChanType)(unsafe.Pointer(t))
   314  		return ch.Dir
   315  	}
   316  	return InvalidDir
   317  }
   318  
   319  // Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil
   320  func (t *Type) Uncommon() *UncommonType {
   321  	if t.TFlag&TFlagUncommon == 0 {
   322  		return nil
   323  	}
   324  	switch t.Kind() {
   325  	case Struct:
   326  		return &(*structTypeUncommon)(unsafe.Pointer(t)).u
   327  	case Pointer:
   328  		type u struct {
   329  			PtrType
   330  			u UncommonType
   331  		}
   332  		return &(*u)(unsafe.Pointer(t)).u
   333  	case Func:
   334  		type u struct {
   335  			FuncType
   336  			u UncommonType
   337  		}
   338  		return &(*u)(unsafe.Pointer(t)).u
   339  	case Slice:
   340  		type u struct {
   341  			SliceType
   342  			u UncommonType
   343  		}
   344  		return &(*u)(unsafe.Pointer(t)).u
   345  	case Array:
   346  		type u struct {
   347  			ArrayType
   348  			u UncommonType
   349  		}
   350  		return &(*u)(unsafe.Pointer(t)).u
   351  	case Chan:
   352  		type u struct {
   353  			ChanType
   354  			u UncommonType
   355  		}
   356  		return &(*u)(unsafe.Pointer(t)).u
   357  	case Map:
   358  		type u struct {
   359  			MapType
   360  			u UncommonType
   361  		}
   362  		return &(*u)(unsafe.Pointer(t)).u
   363  	case Interface:
   364  		type u struct {
   365  			InterfaceType
   366  			u UncommonType
   367  		}
   368  		return &(*u)(unsafe.Pointer(t)).u
   369  	default:
   370  		type u struct {
   371  			Type
   372  			u UncommonType
   373  		}
   374  		return &(*u)(unsafe.Pointer(t)).u
   375  	}
   376  }
   377  
   378  // Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.
   379  func (t *Type) Elem() *Type {
   380  	switch t.Kind() {
   381  	case Array:
   382  		tt := (*ArrayType)(unsafe.Pointer(t))
   383  		return tt.Elem
   384  	case Chan:
   385  		tt := (*ChanType)(unsafe.Pointer(t))
   386  		return tt.Elem
   387  	case Map:
   388  		tt := (*MapType)(unsafe.Pointer(t))
   389  		return tt.Elem
   390  	case Pointer:
   391  		tt := (*PtrType)(unsafe.Pointer(t))
   392  		return tt.Elem
   393  	case Slice:
   394  		tt := (*SliceType)(unsafe.Pointer(t))
   395  		return tt.Elem
   396  	}
   397  	return nil
   398  }
   399  
   400  // StructType returns t cast to a *StructType, or nil if its tag does not match.
   401  func (t *Type) StructType() *StructType {
   402  	if t.Kind() != Struct {
   403  		return nil
   404  	}
   405  	return (*StructType)(unsafe.Pointer(t))
   406  }
   407  
   408  // MapType returns t cast to a *MapType, or nil if its tag does not match.
   409  func (t *Type) MapType() *MapType {
   410  	if t.Kind() != Map {
   411  		return nil
   412  	}
   413  	return (*MapType)(unsafe.Pointer(t))
   414  }
   415  
   416  // PointerType returns t cast to a *PtrType, or nil if its tag does not match.
   417  func (t *Type) PointerType() *PtrType {
   418  	if t.Kind() != Pointer {
   419  		return nil
   420  	}
   421  	return (*PtrType)(unsafe.Pointer(t))
   422  }
   423  
   424  // SliceType returns t cast to a *SliceType, or nil if its tag does not match.
   425  func (t *Type) SliceType() *SliceType {
   426  	if t.Kind() != Slice {
   427  		return nil
   428  	}
   429  	return (*SliceType)(unsafe.Pointer(t))
   430  }
   431  
   432  // ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.
   433  func (t *Type) ArrayType() *ArrayType {
   434  	if t.Kind() != Array {
   435  		return nil
   436  	}
   437  	return (*ArrayType)(unsafe.Pointer(t))
   438  }
   439  
   440  // ChanType returns t cast to a *ChanType, or nil if its tag does not match.
   441  func (t *Type) ChanType() *ChanType {
   442  	if t.Kind() != Chan {
   443  		return nil
   444  	}
   445  	return (*ChanType)(unsafe.Pointer(t))
   446  }
   447  
   448  // FuncType returns t cast to a *FuncType, or nil if its tag does not match.
   449  func (t *Type) FuncType() *FuncType {
   450  	if t.Kind() != Func {
   451  		return nil
   452  	}
   453  	return (*FuncType)(unsafe.Pointer(t))
   454  }
   455  
   456  // InterfaceType returns t cast to a *InterfaceType, or nil if its tag does not match.
   457  func (t *Type) InterfaceType() *InterfaceType {
   458  	if t.Kind() != Interface {
   459  		return nil
   460  	}
   461  	return (*InterfaceType)(unsafe.Pointer(t))
   462  }
   463  
   464  // Size returns the size of data with type t.
   465  func (t *Type) Size() uintptr { return t.Size_ }
   466  
   467  // Align returns the alignment of data with type t.
   468  func (t *Type) Align() int { return int(t.Align_) }
   469  
   470  func (t *Type) FieldAlign() int { return int(t.FieldAlign_) }
   471  
   472  type InterfaceType struct {
   473  	Type
   474  	PkgPath Name      // import path
   475  	Methods []Imethod // sorted by hash
   476  }
   477  
   478  func (t *Type) ExportedMethods() []Method {
   479  	ut := t.Uncommon()
   480  	if ut == nil {
   481  		return nil
   482  	}
   483  	return ut.ExportedMethods()
   484  }
   485  
   486  func (t *Type) NumMethod() int {
   487  	if t.Kind() == Interface {
   488  		tt := (*InterfaceType)(unsafe.Pointer(t))
   489  		return tt.NumMethod()
   490  	}
   491  	return len(t.ExportedMethods())
   492  }
   493  
   494  // NumMethod returns the number of interface methods in the type's method set.
   495  func (t *InterfaceType) NumMethod() int { return len(t.Methods) }
   496  
   497  func (t *Type) Key() *Type {
   498  	if t.Kind() == Map {
   499  		return (*MapType)(unsafe.Pointer(t)).Key
   500  	}
   501  	return nil
   502  }
   503  
   504  type SliceType struct {
   505  	Type
   506  	Elem *Type // slice element type
   507  }
   508  
   509  // FuncType represents a function type.
   510  //
   511  // A *Type for each in and out parameter is stored in an array that
   512  // directly follows the funcType (and possibly its uncommonType). So
   513  // a function type with one method, one input, and one output is:
   514  //
   515  //	struct {
   516  //		funcType
   517  //		uncommonType
   518  //		[2]*rtype    // [0] is in, [1] is out
   519  //	}
   520  type FuncType struct {
   521  	Type
   522  	InCount  uint16
   523  	OutCount uint16 // top bit is set if last input parameter is ...
   524  }
   525  
   526  func (t *FuncType) In(i int) *Type {
   527  	return t.InSlice()[i]
   528  }
   529  
   530  func (t *FuncType) NumIn() int {
   531  	return int(t.InCount)
   532  }
   533  
   534  func (t *FuncType) NumOut() int {
   535  	return int(t.OutCount & (1<<15 - 1))
   536  }
   537  
   538  func (t *FuncType) Out(i int) *Type {
   539  	return (t.OutSlice()[i])
   540  }
   541  
   542  func (t *FuncType) InSlice() []*Type {
   543  	uadd := unsafe.Sizeof(*t)
   544  	if t.TFlag&TFlagUncommon != 0 {
   545  		uadd += unsafe.Sizeof(UncommonType{})
   546  	}
   547  	if t.InCount == 0 {
   548  		return nil
   549  	}
   550  	return (*[1 << 16]*Type)(addChecked(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.InCount:t.InCount]
   551  }
   552  func (t *FuncType) OutSlice() []*Type {
   553  	outCount := uint16(t.NumOut())
   554  	if outCount == 0 {
   555  		return nil
   556  	}
   557  	uadd := unsafe.Sizeof(*t)
   558  	if t.TFlag&TFlagUncommon != 0 {
   559  		uadd += unsafe.Sizeof(UncommonType{})
   560  	}
   561  	return (*[1 << 17]*Type)(addChecked(unsafe.Pointer(t), uadd, "outCount > 0"))[t.InCount : t.InCount+outCount : t.InCount+outCount]
   562  }
   563  
   564  func (t *FuncType) IsVariadic() bool {
   565  	return t.OutCount&(1<<15) != 0
   566  }
   567  
   568  type PtrType struct {
   569  	Type
   570  	Elem *Type // pointer element (pointed at) type
   571  }
   572  
   573  type StructField struct {
   574  	Name   Name    // name is always non-empty
   575  	Typ    *Type   // type of field
   576  	Offset uintptr // byte offset of field
   577  }
   578  
   579  func (f *StructField) Embedded() bool {
   580  	return f.Name.IsEmbedded()
   581  }
   582  
   583  type StructType struct {
   584  	Type
   585  	PkgPath Name
   586  	Fields  []StructField
   587  }
   588  
   589  // Name is an encoded type Name with optional extra data.
   590  //
   591  // The first byte is a bit field containing:
   592  //
   593  //	1<<0 the name is exported
   594  //	1<<1 tag data follows the name
   595  //	1<<2 pkgPath nameOff follows the name and tag
   596  //	1<<3 the name is of an embedded (a.k.a. anonymous) field
   597  //
   598  // Following that, there is a varint-encoded length of the name,
   599  // followed by the name itself.
   600  //
   601  // If tag data is present, it also has a varint-encoded length
   602  // followed by the tag itself.
   603  //
   604  // If the import path follows, then 4 bytes at the end of
   605  // the data form a nameOff. The import path is only set for concrete
   606  // methods that are defined in a different package than their type.
   607  //
   608  // If a name starts with "*", then the exported bit represents
   609  // whether the pointed to type is exported.
   610  //
   611  // Note: this encoding must match here and in:
   612  //   cmd/compile/internal/reflectdata/reflect.go
   613  //   cmd/link/internal/ld/decodesym.go
   614  
   615  type Name struct {
   616  	Bytes *byte
   617  }
   618  
   619  // DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   620  // be safe for the reason in whySafe (which can appear in a backtrace, etc.)
   621  func (n Name) DataChecked(off int, whySafe string) *byte {
   622  	return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), whySafe))
   623  }
   624  
   625  // Data does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
   626  // be safe because the runtime made the call (other packages use DataChecked)
   627  func (n Name) Data(off int) *byte {
   628  	return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), "the runtime doesn't need to give you a reason"))
   629  }
   630  
   631  // IsExported returns "is n exported?"
   632  func (n Name) IsExported() bool {
   633  	return (*n.Bytes)&(1<<0) != 0
   634  }
   635  
   636  // HasTag returns true iff there is tag data following this name
   637  func (n Name) HasTag() bool {
   638  	return (*n.Bytes)&(1<<1) != 0
   639  }
   640  
   641  // IsEmbedded returns true iff n is embedded (an anonymous field).
   642  func (n Name) IsEmbedded() bool {
   643  	return (*n.Bytes)&(1<<3) != 0
   644  }
   645  
   646  // ReadVarint parses a varint as encoded by encoding/binary.
   647  // It returns the number of encoded bytes and the encoded value.
   648  func (n Name) ReadVarint(off int) (int, int) {
   649  	v := 0
   650  	for i := 0; ; i++ {
   651  		x := *n.DataChecked(off+i, "read varint")
   652  		v += int(x&0x7f) << (7 * i)
   653  		if x&0x80 == 0 {
   654  			return i + 1, v
   655  		}
   656  	}
   657  }
   658  
   659  // IsBlank indicates whether n is "_".
   660  func (n Name) IsBlank() bool {
   661  	if n.Bytes == nil {
   662  		return false
   663  	}
   664  	_, l := n.ReadVarint(1)
   665  	return l == 1 && *n.Data(2) == '_'
   666  }
   667  
   668  // writeVarint writes n to buf in varint form. Returns the
   669  // number of bytes written. n must be nonnegative.
   670  // Writes at most 10 bytes.
   671  func writeVarint(buf []byte, n int) int {
   672  	for i := 0; ; i++ {
   673  		b := byte(n & 0x7f)
   674  		n >>= 7
   675  		if n == 0 {
   676  			buf[i] = b
   677  			return i + 1
   678  		}
   679  		buf[i] = b | 0x80
   680  	}
   681  }
   682  
   683  // Name returns the name of n, or empty if it does not actually have a name.
   684  func (n Name) Name() string {
   685  	if n.Bytes == nil {
   686  		return ""
   687  	}
   688  	i, l := n.ReadVarint(1)
   689  	return unsafe.String(n.DataChecked(1+i, "non-empty string"), l)
   690  }
   691  
   692  // Tag returns the tag string for n, or empty if there is none.
   693  func (n Name) Tag() string {
   694  	if !n.HasTag() {
   695  		return ""
   696  	}
   697  	i, l := n.ReadVarint(1)
   698  	i2, l2 := n.ReadVarint(1 + i + l)
   699  	return unsafe.String(n.DataChecked(1+i+l+i2, "non-empty string"), l2)
   700  }
   701  
   702  func NewName(n, tag string, exported, embedded bool) Name {
   703  	if len(n) >= 1<<29 {
   704  		panic("abi.NewName: name too long: " + n[:1024] + "...")
   705  	}
   706  	if len(tag) >= 1<<29 {
   707  		panic("abi.NewName: tag too long: " + tag[:1024] + "...")
   708  	}
   709  	var nameLen [10]byte
   710  	var tagLen [10]byte
   711  	nameLenLen := writeVarint(nameLen[:], len(n))
   712  	tagLenLen := writeVarint(tagLen[:], len(tag))
   713  
   714  	var bits byte
   715  	l := 1 + nameLenLen + len(n)
   716  	if exported {
   717  		bits |= 1 << 0
   718  	}
   719  	if len(tag) > 0 {
   720  		l += tagLenLen + len(tag)
   721  		bits |= 1 << 1
   722  	}
   723  	if embedded {
   724  		bits |= 1 << 3
   725  	}
   726  
   727  	b := make([]byte, l)
   728  	b[0] = bits
   729  	copy(b[1:], nameLen[:nameLenLen])
   730  	copy(b[1+nameLenLen:], n)
   731  	if len(tag) > 0 {
   732  		tb := b[1+nameLenLen+len(n):]
   733  		copy(tb, tagLen[:tagLenLen])
   734  		copy(tb[tagLenLen:], tag)
   735  	}
   736  
   737  	return Name{Bytes: &b[0]}
   738  }
   739  
   740  // DescriptorSize returns the contiguous size taken in memory by the
   741  // type descriptor. This is the size of the Type struct,
   742  // plus other fields used by some type kinds, plus the UncommonType
   743  // struct if present, plus other optional information.
   744  // This is just the size of the bytes that appear contiguously in memory.
   745  // It does not include the size of things like type strings
   746  // and field names that appear elsewhere.
   747  //
   748  // This code must match the data structures build by
   749  // cmd/compile/internal/reflectdata/reflect.go:writeType.
   750  func (t *Type) DescriptorSize() int {
   751  	var baseSize, addSize int
   752  	switch t.Kind_ {
   753  	case Array:
   754  		baseSize, addSize = t.ArrayType().descriptorSizes()
   755  	case Chan:
   756  		baseSize, addSize = t.ChanType().descriptorSizes()
   757  	case Func:
   758  		baseSize, addSize = t.FuncType().descriptorSizes()
   759  	case Interface:
   760  		baseSize, addSize = t.InterfaceType().descriptorSizes()
   761  	case Map:
   762  		baseSize, addSize = t.MapType().descriptorSizes()
   763  	case Pointer:
   764  		baseSize, addSize = t.PointerType().descriptorSizes()
   765  	case Slice:
   766  		baseSize, addSize = t.SliceType().descriptorSizes()
   767  	case Struct:
   768  		baseSize, addSize = t.StructType().descriptorSizes()
   769  	case Bool,
   770  		Int, Int8, Int16, Int32, Int64,
   771  		Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
   772  		Float32, Float64, Complex64, Complex128,
   773  		String, UnsafePointer:
   774  
   775  		baseSize = int(unsafe.Sizeof(*t))
   776  		addSize = 0
   777  
   778  	default:
   779  		panic("DescriptorSize: invalid type descriptor")
   780  	}
   781  
   782  	// For clarity, we add the sizes together in the order
   783  	// they appear in memory.
   784  
   785  	ret := baseSize
   786  
   787  	mcount := 0
   788  	ut := t.Uncommon()
   789  	if ut != nil {
   790  		ret += int(unsafe.Sizeof(*ut))
   791  		mcount = int(ut.Mcount)
   792  	}
   793  
   794  	ret += addSize
   795  
   796  	ret += mcount * int(unsafe.Sizeof(Method{}))
   797  
   798  	return ret
   799  }
   800  
   801  func (at *ArrayType) descriptorSizes() (base, add int) {
   802  	return int(unsafe.Sizeof(*at)), 0
   803  }
   804  
   805  func (ct *ChanType) descriptorSizes() (base, add int) {
   806  	return int(unsafe.Sizeof(*ct)), 0
   807  }
   808  
   809  func (ft *FuncType) descriptorSizes() (base, add int) {
   810  	base = int(unsafe.Sizeof(*ft))
   811  	add = (ft.NumIn() + ft.NumOut()) * goarch.PtrSize
   812  	return base, add
   813  }
   814  
   815  func (it *InterfaceType) descriptorSizes() (base, add int) {
   816  	base = int(unsafe.Sizeof(*it))
   817  	add = len(it.Methods) * int(unsafe.Sizeof(Imethod{}))
   818  	return base, add
   819  }
   820  
   821  func (mt *MapType) descriptorSizes() (base, add int) {
   822  	return int(unsafe.Sizeof(*mt)), 0
   823  }
   824  
   825  func (pt *PtrType) descriptorSizes() (base, add int) {
   826  	return int(unsafe.Sizeof(*pt)), 0
   827  }
   828  
   829  func (st *SliceType) descriptorSizes() (base, add int) {
   830  	return int(unsafe.Sizeof(*st)), 0
   831  }
   832  
   833  func (st *StructType) descriptorSizes() (base, add int) {
   834  	base = int(unsafe.Sizeof(*st))
   835  	add = len(st.Fields) * int(unsafe.Sizeof(StructField{}))
   836  	return base, add
   837  }
   838  
   839  const (
   840  	TraceArgsLimit    = 10 // print no more than 10 args/components
   841  	TraceArgsMaxDepth = 5  // no more than 5 layers of nesting
   842  
   843  	// maxLen is a (conservative) upper bound of the byte stream length. For
   844  	// each arg/component, it has no more than 2 bytes of data (size, offset),
   845  	// and no more than one {, }, ... at each level (it cannot have both the
   846  	// data and ... unless it is the last one, just be conservative). Plus 1
   847  	// for _endSeq.
   848  	TraceArgsMaxLen = (TraceArgsMaxDepth*3+2)*TraceArgsLimit + 1
   849  )
   850  
   851  // Populate the data.
   852  // The data is a stream of bytes, which contains the offsets and sizes of the
   853  // non-aggregate arguments or non-aggregate fields/elements of aggregate-typed
   854  // arguments, along with special "operators". Specifically,
   855  //   - for each non-aggregate arg/field/element, its offset from FP (1 byte) and
   856  //     size (1 byte)
   857  //   - special operators:
   858  //   - 0xff - end of sequence
   859  //   - 0xfe - print { (at the start of an aggregate-typed argument)
   860  //   - 0xfd - print } (at the end of an aggregate-typed argument)
   861  //   - 0xfc - print ... (more args/fields/elements)
   862  //   - 0xfb - print _ (offset too large)
   863  const (
   864  	TraceArgsEndSeq         = 0xff
   865  	TraceArgsStartAgg       = 0xfe
   866  	TraceArgsEndAgg         = 0xfd
   867  	TraceArgsDotdotdot      = 0xfc
   868  	TraceArgsOffsetTooLarge = 0xfb
   869  	TraceArgsSpecial        = 0xf0 // above this are operators, below this are ordinary offsets
   870  )
   871  
   872  // MaxPtrmaskBytes is the maximum length of a GC ptrmask bitmap,
   873  // which holds 1-bit entries describing where pointers are in a given type.
   874  // Above this length, the runtime computes the GC ptrmask bitmap as needed.
   875  // The information is used by the runtime to initialize the heap bitmap.
   876  //
   877  // There is a bit of overhead to computing the GC ptrmask bitmap
   878  // the first time. On the other hand building GC ptrmask bitmaps
   879  // for all types at compile time takes space in the binary for
   880  // large types that have a lot of pointers, such as large array types.
   881  // Using 16 means that types that keep their pointers in the first
   882  // 512 (on 32-bit) or 1024 (on 64-bit) bytes are computed at compile time,
   883  // and types with more pointers are computed at run time.
   884  // This tradeoff sounds reasonable, and 16 was the cutoff back when
   885  // we used GC programs, but this has not been benchmarked.
   886  const MaxPtrmaskBytes = 16
   887  

View as plain text