compiler, runtime, reflect: generate hash functions only for map keys
[official-gcc.git] / libgo / go / runtime / type.go
blob94abbb8e9f89cf8d07b2afd8b64b3254248d0987
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.
7 package runtime
9 import (
10 "runtime/internal/atomic"
11 "runtime/internal/sys"
12 "unsafe"
15 // tflag is documented in reflect/type.go.
17 // tflag values must be kept in sync with copies in:
18 // go/types.cc
19 // reflect/type.go
20 // internal/reflectlite/type.go
21 type tflag uint8
23 const (
24 tflagRegularMemory tflag = 1 << 3 // equal and hash can treat values of this type as a single region of t.size bytes
27 type _type struct {
28 size uintptr
29 ptrdata uintptr
30 hash uint32
31 tflag tflag
32 align uint8
33 fieldAlign uint8
34 kind uint8
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.
41 gcdata *byte
42 _string *string
43 *uncommontype
44 ptrToThis *_type
47 func (t *_type) string() string {
48 return *t._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 {
57 if u.pkgPath == nil {
58 return ""
60 return *u.pkgPath
62 return ""
65 type method struct {
66 name *string
67 pkgPath *string
68 mtyp *_type
69 typ *_type
70 tfn unsafe.Pointer
73 type uncommontype struct {
74 name *string
75 pkgPath *string
76 methods []method
79 type imethod struct {
80 name *string
81 pkgPath *string
82 typ *_type
85 type interfacetype struct {
86 typ _type
87 methods []imethod
90 type maptype struct {
91 typ _type
92 key *_type
93 elem *_type
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
100 flags uint32
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 {
122 typ _type
123 elem *_type
124 slice *_type
125 len uintptr
128 type chantype struct {
129 typ _type
130 elem *_type
131 dir uintptr
134 type slicetype struct {
135 typ _type
136 elem *_type
139 type functype struct {
140 typ _type
141 dotdotdot bool
142 in []*_type
143 out []*_type
146 type ptrtype struct {
147 typ _type
148 elem *_type
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 {
168 typ _type
169 fields []structfield
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.
176 //go:notinheap
177 type typeDescriptorList struct {
178 count int
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 {
186 initialized uint32
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
195 // type descriptors.
196 // p points to a list of *typeDescriptorList, n is the length
197 // of the list.
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 {
210 lock(&typelistLock)
211 if atomic.Load(&typelist.initialized) == 0 {
212 n := 0
213 for _, list := range typelist.lists {
214 n += list.count
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]))