-
Notifications
You must be signed in to change notification settings - Fork 1
/
alg.go
352 lines (264 loc) · 8.39 KB
/
alg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtimer
import "unsafe" // #nosec
const (
C0 = uintptr((8-PtrSize)/4*2860486313 + (PtrSize-4)/4*33054211828000289)
C1 = uintptr((8-PtrSize)/4*3267000013 + (PtrSize-4)/4*23344194077549503)
)
// type algorithms - known to compiler
const (
AlgNOEQ = iota
AlgMEM0
AlgMEM8
AlgMEM16
AlgMEM32
AlgMEM64
AlgMEM128
AlgSTRING
AlgINTER
AlgNILINTER
AlgFLOAT32
AlgFLOAT64
AlgCPLX64
AlgCPLX128
AlgMax
)
// TypeAlg is also copied/used in reflect/type.go.
// keep them in sync.
type TypeAlg struct {
// function for hashing objects of this type
// (ptr to object, seed) -> hash
Hash func(unsafe.Pointer, uintptr) uintptr
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
Equal func(unsafe.Pointer, unsafe.Pointer) bool
}
func Memhash0(p unsafe.Pointer, h uintptr) uintptr {
return memhash0(p, h)
}
//go:linkname memhash0 runtime.memhash0
func memhash0(p unsafe.Pointer, h uintptr) uintptr
func Memhash8(p unsafe.Pointer, h uintptr) uintptr {
return memhash8(p, h)
}
func Memhash16(p unsafe.Pointer, h uintptr) uintptr {
return memhash16(p, h)
}
func Memhash32(p unsafe.Pointer, h uintptr) uintptr {
return memhash32(p, h)
}
func Memhash64(p unsafe.Pointer, h uintptr) uintptr {
return memhash64(p, h)
}
//go:linkname memhash8 runtime.memhash8
func memhash8(p unsafe.Pointer, h uintptr) uintptr
//go:linkname memhash16 runtime.memhash16
func memhash16(p unsafe.Pointer, h uintptr) uintptr
//go:linkname memhash32 runtime.memhash32
func memhash32(p unsafe.Pointer, h uintptr) uintptr
//go:linkname memhash64 runtime.memhash64
func memhash64(p unsafe.Pointer, h uintptr) uintptr
func Memhash128(p unsafe.Pointer, h uintptr) uintptr {
return memhash128(p, h)
}
//go:linkname memhash128 runtime.memhash128
func memhash128(p unsafe.Pointer, h uintptr) uintptr
// MemhashVarlen is defined in runtime assembly because it needs access
// to the closure. It appears here to provide an argument
// signature for the assembly routine.
func MemhashVarlen(p unsafe.Pointer, h uintptr) uintptr {
return memhashVarlen(p, h)
}
//go:linkname memhashVarlen runtime.memhash_varlen
func memhashVarlen(p unsafe.Pointer, h uintptr) uintptr
var AlgArray = [AlgMax]TypeAlg{
AlgNOEQ: {nil, nil},
AlgMEM0: {Memhash0, Memequal0},
AlgMEM8: {Memhash8, Memequal8},
AlgMEM16: {Memhash16, Memequal16},
AlgMEM32: {Memhash32, Memequal32},
AlgMEM64: {Memhash64, Memequal64},
AlgMEM128: {Memhash128, Memequal128},
AlgSTRING: {Strhash, Strequal},
AlgINTER: {Interhash, Interequal},
AlgNILINTER: {Nilinterhash, Nilinterequal},
AlgFLOAT32: {F32hash, F32equal},
AlgFLOAT64: {F64hash, F64equal},
AlgCPLX64: {C64hash, C64equal},
AlgCPLX128: {C128hash, C128equal},
}
func Aeshash(p unsafe.Pointer, h, s uintptr) uintptr {
return aeshash(p, h, s)
}
//go:linkname aeshash runtime.aeshash
func aeshash(p unsafe.Pointer, h, s uintptr) uintptr
func Aeshash32(p unsafe.Pointer, h uintptr) uintptr {
return aeshash32(p, h)
}
//go:linkname aeshash32 runtime.aeshash32
func aeshash32(p unsafe.Pointer, h uintptr) uintptr
func Aeshash64(p unsafe.Pointer, h uintptr) uintptr {
return aeshash64(p, h)
}
//go:linkname aeshash64 runtime.aeshash64
func aeshash64(p unsafe.Pointer, h uintptr) uintptr
func Aeshashstr(p unsafe.Pointer, h uintptr) uintptr {
return aeshashstr(p, h)
}
//go:linkname aeshashstr runtime.aeshashstr
func aeshashstr(p unsafe.Pointer, h uintptr) uintptr
func Strhash(p unsafe.Pointer, h uintptr) uintptr {
return strhash(p, h)
}
//go:linkname strhash runtime.strhash
func strhash(a unsafe.Pointer, h uintptr) uintptr
func F32hash(p unsafe.Pointer, h uintptr) uintptr {
return f32hash(p, h)
}
//go:linkname f32hash runtime.f32hash
func f32hash(p unsafe.Pointer, h uintptr) uintptr
func F64hash(p unsafe.Pointer, h uintptr) uintptr {
return f64hash(p, h)
}
//go:linkname f64hash runtime.f64hash
func f64hash(p unsafe.Pointer, h uintptr) uintptr
func C64hash(p unsafe.Pointer, h uintptr) uintptr {
return c64hash(p, h)
}
//go:linkname c64hash runtime.c64hash
func c64hash(p unsafe.Pointer, h uintptr) uintptr
func C128hash(p unsafe.Pointer, h uintptr) uintptr {
return c128hash(p, h)
}
//go:linkname c128hash runtime.c128hash
func c128hash(p unsafe.Pointer, h uintptr) uintptr
func Interhash(p unsafe.Pointer, h uintptr) uintptr {
return interhash(p, h)
}
//go:linkname interhash runtime.interhash
func interhash(p unsafe.Pointer, h uintptr) uintptr
func Nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
return nilinterhash(p, h)
}
//go:linkname nilinterhash runtime.nilinterhash
func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
func Memequal(a, b unsafe.Pointer, size uintptr) bool {
return memequal(a, b, size)
}
//go:linkname memequal runtime.memequal
func memequal(a, b unsafe.Pointer, size uintptr) bool
func Memequal0(p, q unsafe.Pointer) bool {
return memequal0(p, q)
}
//go:linkname memequal0 runtime.memequal0
func memequal0(p, q unsafe.Pointer) bool
func Memequal8(p, q unsafe.Pointer) bool {
return memequal8(p, q)
}
//go:linkname memequal8 runtime.memequal8
func memequal8(p, q unsafe.Pointer) bool
func Memequal16(p, q unsafe.Pointer) bool {
return memequal16(p, q)
}
//go:linkname memequal18 runtime.memequal18
func memequal16(p, q unsafe.Pointer) bool
func Memequal32(p, q unsafe.Pointer) bool {
return memequal32(p, q)
}
//go:linkname memequal32 runtime.memequal32
func memequal32(p, q unsafe.Pointer) bool
func Memequal64(p, q unsafe.Pointer) bool {
return memequal64(p, q)
}
//go:linkname memequal64 runtime.memequal64
func memequal64(p, q unsafe.Pointer) bool
func Memequal128(p, q unsafe.Pointer) bool {
return memequal128(p, q)
}
//go:linkname memequal128 runtime.memequal128
func memequal128(p, q unsafe.Pointer) bool
func F32equal(p, q unsafe.Pointer) bool {
return f32equal(p, q)
}
//go:linkname f32equal runtime.f32equal
func f32equal(p, q unsafe.Pointer) bool
func F64equal(p, q unsafe.Pointer) bool {
return f64equal(p, q)
}
//go:linkname f64equal runtime.f64equal
func f64equal(p, q unsafe.Pointer) bool
func C64equal(p, q unsafe.Pointer) bool {
return c64equal(p, q)
}
//go:linkname c64equal runtime.c64equal
func c64equal(p, q unsafe.Pointer) bool
func C128equal(p, q unsafe.Pointer) bool {
return c128equal(p, q)
}
//go:linkname c128equal runtime.c128equal
func c128equal(p, q unsafe.Pointer) bool
func Strequal(p, q unsafe.Pointer) bool {
return strequal(p, q)
}
//go:linkname strequal runtime.strequal
func strequal(p, q unsafe.Pointer) bool
func Interequal(p, q unsafe.Pointer) bool {
return interequal(p, q)
}
//go:linkname interequal runtime.interequal
func interequal(p, q unsafe.Pointer) bool
func Nilinterequal(p, q unsafe.Pointer) bool {
return nilinterequal(p, q)
}
//go:linkname nilinterequal runtime.nilinterequal
func nilinterequal(p, q unsafe.Pointer) bool
func Efaceeq(t *Type, x, y unsafe.Pointer) bool {
return efaceeq(t, x, y)
}
//go:linkname efaceeq runtime.efaceeq
func efaceeq(t *Type, x, y unsafe.Pointer) bool
func Ifaceeq(t *Itab, x, y unsafe.Pointer) bool {
return ifaceeq(t, x, y)
}
//go:linkname ifaceeq runtime.ifaceeq
func ifaceeq(tab *Itab, x, y unsafe.Pointer) bool
func StringHash(s string, seed uintptr) uintptr {
return stringHash(s, seed)
}
// Testing adapters for hash quality tests (see hash_test.go)
//go:linkname stringHash runtime.stringHash
func stringHash(s string, seed uintptr) uintptr
func BytesHash(b []byte, seed uintptr) uintptr {
return bytesHash(b, seed)
}
//go:linkname bytesHash runtime.bytesHash
func bytesHash(b []byte, seed uintptr) uintptr
func Int32Hash(i uint32, seed uintptr) uintptr {
return int32Hash(i, seed)
}
//go:linkname int32Hash runtime.int32Hash
func int32Hash(i uint32, seed uintptr) uintptr
func Int64Hash(i uint64, seed uintptr) uintptr {
return int64Hash(i, seed)
}
//go:linkname int64Hash runtime.int64Hash
func int64Hash(i uint64, seed uintptr) uintptr
func EfaceHash(i interface{}, seed uintptr) uintptr {
return efaceHash(i, seed)
}
//go:linkname efaceHash runtime.efaceHash
func efaceHash(i interface{}, seed uintptr) uintptr
func IfaceHash(i interface {
F()
}, seed uintptr) uintptr {
return ifaceHash(i, seed)
}
//go:linkname ifaceHash runtime.ifaceHash
func ifaceHash(i interface {
F()
}, seed uintptr) uintptr
const HashRandomBytes = PtrSize / 4 * 64
//go:linkname CPUIDECX runtime.cpuid_ecx
var CPUIDECX uint32