-
Notifications
You must be signed in to change notification settings - Fork 60
/
iface.1.8.go
68 lines (58 loc) · 1.5 KB
/
iface.1.8.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
//go:build go1.8 && !go1.10
// +build go1.8,!go1.10
package goloader
import (
"unsafe"
)
// 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.dumptypestructs.
type itab struct {
inter *interfacetype
_type *_type
link *itab
bad int32
inhash int32 // has this itab been added to hash?
fun [1]uintptr // variable sized
}
// See: src/runtime/iface.go
const hashSize = 1009
//go:linkname hash runtime.hash
var hash [hashSize]*itab
//go:linkname ifaceLock runtime.ifaceLock
var ifaceLock mutex
//go:linkname additab runtime.additab
func additab(m *itab, locked, canfail bool)
func additabs(module *moduledata) {
lock(&ifaceLock)
for _, itab := range module.itablinks {
if itab.inhash == 0 {
additab(itab, true, false)
}
}
unlock(&ifaceLock)
}
func removeitabs(module *moduledata) bool {
lock(&ifaceLock)
defer unlock(&ifaceLock)
//the itab alloc by runtime.persistentalloc, can't free
for index, h := range hash {
last := h
for m := h; m != nil; m = m.link {
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) {
if m == h {
hash[index] = m.link
} else {
last.link = m.link
}
}
last = m
}
}
return true
}