github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/iface.1.8.go (about)

     1  //go:build go1.8 && !go1.10
     2  // +build go1.8,!go1.10
     3  
     4  package goloader
     5  
     6  import (
     7  	"unsafe"
     8  )
     9  
    10  // layout of Itab known to compilers
    11  // allocated in non-garbage-collected memory
    12  // Needs to be in sync with
    13  // ../cmd/compile/internal/gc/reflect.go:/^func.dumptypestructs.
    14  type itab struct {
    15  	inter  *interfacetype
    16  	_type  *_type
    17  	link   *itab
    18  	bad    int32
    19  	inhash int32      // has this itab been added to hash?
    20  	fun    [1]uintptr // variable sized
    21  }
    22  
    23  // See: src/runtime/iface.go
    24  const hashSize = 1009
    25  
    26  //go:linkname __hash runtime.hash
    27  var __hash uintptr
    28  
    29  var hash = (*[hashSize]*itab)(unsafe.Pointer(&__hash))
    30  
    31  //go:linkname __ifaceLock runtime.ifaceLock
    32  var __ifaceLock uintptr
    33  
    34  var ifaceLock = (*mutex)(unsafe.Pointer(&__ifaceLock))
    35  
    36  //go:linkname additab runtime.additab
    37  func additab(m *itab, locked, canfail bool)
    38  
    39  func additabs(module *moduledata) {
    40  	lock(ifaceLock)
    41  	for _, itab := range module.itablinks {
    42  		if itab.inhash == 0 {
    43  			additab(itab, true, false)
    44  		}
    45  	}
    46  	unlock(ifaceLock)
    47  }
    48  
    49  func removeitabs(module *moduledata) bool {
    50  	lock(ifaceLock)
    51  	defer unlock(ifaceLock)
    52  
    53  	//the itab alloc by runtime.persistentalloc, can't free
    54  	for index, h := range hash {
    55  		last := h
    56  		for m := h; m != nil; m = m.link {
    57  			uintptrm := uintptr(unsafe.Pointer(m))
    58  			inter := uintptr(unsafe.Pointer(m.inter))
    59  			_type := uintptr(unsafe.Pointer(m._type))
    60  			if (inter >= module.types && inter <= module.etypes) || (_type >= module.types && _type <= module.etypes) ||
    61  				(uintptrm >= module.types && uintptrm <= module.etypes) {
    62  				if m == h {
    63  					hash[index] = m.link
    64  				} else {
    65  					last.link = m.link
    66  				}
    67  			}
    68  			last = m
    69  		}
    70  	}
    71  	return true
    72  }