-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
before unload module, unregister itab from itabList, otherwise, there…
… will be panic when the itabList grow
- Loading branch information
Showing
10 changed files
with
146 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// +build go1.10 | ||
// +build !go1.15 | ||
|
||
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.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 | ||
} | ||
|
||
//go:linkname itabTable runtime.itabTable | ||
var itabTable *itabTableType // pointer to current table | ||
|
||
//go:linkname itabLock runtime.itabLock | ||
var itabLock mutex | ||
|
||
//go:linkname itabHashFunc runtime.itabHashFunc | ||
func itabHashFunc(inter *interfacetype, typ *_type) uintptr | ||
|
||
func eraseiface(inter *interfacetype, typ *_type) bool { | ||
lock(&itabLock) | ||
defer unlock(&itabLock) | ||
mask := itabTable.size - 1 | ||
h := itabHashFunc(inter, typ) & mask | ||
for i := uintptr(1); ; i++ { | ||
p := (**itab)(add(unsafe.Pointer(&itabTable.entries), h*PtrSize)) | ||
// Use atomic read here so if we see m != nil, we also see | ||
// the initializations of the fields of m. | ||
// m := *p | ||
m := (*itab)(Loadp(unsafe.Pointer(p))) | ||
if m == nil { | ||
return false | ||
} | ||
if m.inter == inter && m._type == typ { | ||
atomicstorep(unsafe.Pointer(p), unsafe.Pointer(nil)) | ||
itabTable.count = itabTable.count - 1 | ||
return true | ||
} | ||
h += i | ||
h &= mask | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// +build go1.8 | ||
// +build !go1.10,!go1.11,!go1.12,!go1.13,!go1.14,!go1.15 | ||
|
||
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 itabhash runtime.itabhash | ||
func itabhash(inter *interfacetype, typ *_type) uint32 | ||
|
||
func eraseiface(inter *interfacetype, typ *_type) bool { | ||
lock(&ifaceLock) | ||
defer unlock(&ifaceLock) | ||
h := itabhash(inter, typ) | ||
var m, last *itab = nil, nil | ||
for m = (*itab)(Loadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link { | ||
if m.inter == inter && m._type == typ { | ||
if last == nil { | ||
atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(nil)) | ||
} else { | ||
last.link = m.link | ||
} | ||
return true | ||
} | ||
last = m | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package goloader | ||
|
||
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters