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

View as plain text