1 // Copyright 2009 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.
5 // Runtime type representation.
10 "runtime/internal/atomic"
11 "runtime/internal/sys"
15 // tflag is documented in reflect/type.go.
17 // tflag values must be kept in sync with copies in:
20 // internal/reflectlite/type.go
24 tflagRegularMemory tflag
= 1 << 3 // equal and hash can treat values of this type as a single region of t.size bytes
35 // function for comparing objects of this type
36 // (ptr to object A, ptr to object B) -> ==?
37 equal
func(unsafe
.Pointer
, unsafe
.Pointer
) bool
38 // gcdata stores the GC type data for the garbage collector.
39 // If the KindGCProg bit is set in kind, gcdata is a GC program.
40 // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
47 func (t
*_type
) string() string {
51 // pkgpath returns the path of the package where t was defined, if
52 // available. This is not the same as the reflect package's PkgPath
53 // method, in that it returns the package path for struct and interface
54 // types, not just named types.
55 func (t
*_type
) pkgpath() string {
56 if u
:= t
.uncommontype
; u
!= nil {
73 type uncommontype
struct {
85 type interfacetype
struct {
94 bucket
*_type
// internal type representing a hash bucket
95 // function for hashing keys (ptr to key, seed) -> hash
96 hasher
func(unsafe
.Pointer
, uintptr) uintptr
97 keysize
uint8 // size of key slot
98 elemsize
uint8 // size of elem slot
99 bucketsize
uint16 // size of bucket
103 // Note: flag values must match those used in the TMAP case
104 // in ../cmd/compile/internal/gc/reflect.go:dtypesym.
105 func (mt
*maptype
) indirectkey() bool { // store ptr to key instead of key itself
106 return mt
.flags
&1 != 0
108 func (mt
*maptype
) indirectelem() bool { // store ptr to elem instead of elem itself
109 return mt
.flags
&2 != 0
111 func (mt
*maptype
) reflexivekey() bool { // true if k==k for all keys
112 return mt
.flags
&4 != 0
114 func (mt
*maptype
) needkeyupdate() bool { // true if we need to update key on an overwrite
115 return mt
.flags
&8 != 0
117 func (mt
*maptype
) hashMightPanic() bool { // true if hash function might panic
118 return mt
.flags
&16 != 0
121 type arraytype
struct {
128 type chantype
struct {
134 type slicetype
struct {
139 type functype
struct {
146 type ptrtype
struct {
151 type structfield
struct {
152 name
*string // nil for embedded fields
153 pkgPath
*string // nil for exported Names; otherwise import path
154 typ
*_type
// type of field
155 tag
*string // nil if no tag
156 offsetAnon
uintptr // byte offset of field<<1 | isAnonymous
159 func (f
*structfield
) offset() uintptr {
160 return f
.offsetAnon
>> 1
163 func (f
*structfield
) anon() bool {
164 return f
.offsetAnon
&1 != 0
167 type structtype
struct {
172 // typeDescriptorList holds a list of type descriptors generated
173 // by the compiler. This is used for the compiler to register
174 // type descriptors to the runtime.
175 // The layout is known to the compiler.
177 type typeDescriptorList
struct {
179 types
[1]uintptr // variable length
182 // typelist holds all type descriptors generated by the comiler.
183 // This is for the reflect package to deduplicate type descriptors
184 // when it creates a type that is also a compiler-generated type.
185 var typelist
struct {
187 lists
[]*typeDescriptorList
// one element per package
188 types
map[string]uintptr // map from a type's string to *_type, lazily populated
189 // TODO: use a sorted array instead?
191 var typelistLock mutex
193 // The compiler generates a call of this function in the main
194 // package's init function, to register compiler-generated
196 // p points to a list of *typeDescriptorList, n is the length
198 //go:linkname registerTypeDescriptors
199 func registerTypeDescriptors(n
int, p unsafe
.Pointer
) {
200 *(*slice
)(unsafe
.Pointer(&typelist
.lists
)) = slice
{p
, n
, n
}
203 // The reflect package uses this function to look up a compiler-
204 // generated type descriptor.
205 //go:linkname reflect_lookupType reflect.lookupType
206 func reflect_lookupType(s
string) *_type
{
207 // Lazy initialization. We don't need to do this if we never create
208 // types through reflection.
209 if atomic
.Load(&typelist
.initialized
) == 0 {
211 if atomic
.Load(&typelist
.initialized
) == 0 {
213 for _
, list
:= range typelist
.lists
{
216 typelist
.types
= make(map[string]uintptr, n
)
217 for _
, list
:= range typelist
.lists
{
218 for i
:= 0; i
< list
.count
; i
++ {
219 typ
:= *(**_type
)(add(unsafe
.Pointer(&list
.types
), uintptr(i
)*sys
.PtrSize
))
220 typelist
.types
[typ
.string()] = uintptr(unsafe
.Pointer(typ
))
223 atomic
.Store(&typelist
.initialized
, 1)
225 unlock(&typelistLock
)
228 return (*_type
)(unsafe
.Pointer(typelist
.types
[s
]))