This repository has been archived by the owner on Jul 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathiface.go
84 lines (70 loc) · 2.43 KB
/
iface.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
//go:build go1.10
// +build go1.10
package godynamic
import "unsafe"
// Mutual exclusion locks. In the uncontended case,
// as fast as spin locks (just a few user-level instructions),
// but on the contention path they sleep in the kernel.
// A zeroed Mutex is unlocked (no need to initialize each lock).
type mutex struct {
// Futex-based impl treats it as uint32 key,
// while sema-based impl as M* waitm.
// Used to be a union, but unions break precise GC.
key uintptr
}
//go:linkname lock runtime.lock
func lock(l *mutex)
//go:linkname unlock runtime.unlock
func unlock(l *mutex)
//go:linkname atomicstorep runtime.atomicstorep
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer)
// layout of Itab known to compilers
// allocated in non-garbage-collected memory
// Needs to be in sync with
// ../cmd/compile/internal/gc/reflect.go:/^func.dumptabs.
type itab struct {
inter *interfacetype
_type *_type
hash uint32 // copy of _type.hash. Used for type switches.
_ [4]byte
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
const itabInitSize = 512
// Note: change the formula in the mallocgc call in itabAdd if you change these fields.
type itabTableType struct {
size uintptr // length of entries array. Always a power of 2.
count uintptr // current number of filled entries.
entries [itabInitSize]*itab // really [size] large
}
var itabLock *mutex = nil
var itabTable *itabTableType = nil
//go:linkname itabHashFunc runtime.itabHashFunc
func itabHashFunc(inter *interfacetype, typ *_type) uintptr
//go:linkname itabAdd runtime.itabAdd
func itabAdd(m *itab)
func additabs(module *moduledata) {
lock(itabLock)
for _, itab := range module.itablinks {
itabAdd(itab)
}
unlock(itabLock)
}
func removeitabs(module *moduledata) bool {
lock(itabLock)
defer unlock(itabLock)
for i := uintptr(0); i < itabTable.size; i++ {
p := (**itab)(add(unsafe.Pointer(&itabTable.entries), i*PtrSize))
m := (*itab)(loadp(unsafe.Pointer(p)))
if m != nil {
uintptrm := uintptr(unsafe.Pointer(m))
inter := uintptr(unsafe.Pointer(m.inter))
_type := uintptr(unsafe.Pointer(m._type))
if (inter >= module.types && inter <= module.etypes) || (_type >= module.types && _type <= module.etypes) ||
(uintptrm >= module.types && uintptrm <= module.etypes) {
atomicstorep(unsafe.Pointer(p), unsafe.Pointer(nil))
itabTable.count = itabTable.count - 1
}
}
}
return true
}