github.com/moontrade/nogc@v0.1.7/mem_std.go (about) 1 //go:build !tinygo && !wasm && !wasi && !tinygo.wasm 2 // +build !tinygo,!wasm,!wasi,!tinygo.wasm 3 4 package nogc 5 6 import ( 7 "reflect" 8 "unsafe" 9 ) 10 11 func Compare(a, b unsafe.Pointer, n uintptr) int { 12 return Cmp(*(*string)(unsafe.Pointer(&reflect.StringHeader{Data: uintptr(a), Len: int(n)})), 13 *(*string)(unsafe.Pointer(&reflect.StringHeader{Data: uintptr(b), Len: int(n)}))) 14 } 15 16 //go:linkname Cmp runtime.cmpstring 17 func Cmp(a, b string) int 18 19 func Copy(dst, src unsafe.Pointer, n uintptr) { 20 Move(dst, src, n) 21 //memcpySlow(dst, src, n) 22 } 23 24 func memcpySlow(dst, src unsafe.Pointer, n uintptr) { 25 //dstB := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ 26 // Data: uintptr(dst), 27 // Len: int(n), 28 // Cap: int(n), 29 //})) 30 //srcB := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ 31 // Data: uintptr(src), 32 // Len: int(n), 33 // Cap: int(n), 34 //})) 35 //copy(dstB, srcB) 36 } 37 38 // Move copies n bytes from "from" to "to". 39 // 40 // Move ensures that any pointer in "from" is written to "to" with 41 // an indivisible write, so that racy reads cannot observe a 42 // half-written pointer. This is necessary to prevent the garbage 43 // collector from observing invalid pointers, and differs from Memmove 44 // in unmanaged languages. However, Memmove is only required to do 45 // this if "from" and "to" may contain pointers, which can only be the 46 // case if "from", "to", and "n" are all be word-aligned. 47 // 48 // Implementations are in memmove_*.s. 49 // 50 //go:noescape 51 //go:linkname Move runtime.memmove 52 func Move(to, from unsafe.Pointer, n uintptr) 53 54 func zeroSlow(ptr unsafe.Pointer, size uintptr) { 55 b := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ 56 Data: uintptr(ptr), 57 Len: int(size), 58 Cap: int(size), 59 })) 60 switch { 61 case size < 8: 62 for i := 0; i < len(b); i++ { 63 b[i] = 0 64 } 65 case size == 8: 66 *(*uint64)(unsafe.Pointer(&b[0])) = 0 67 default: 68 var i = 0 69 for ; i <= len(b)-8; i += 8 { 70 *(*uint64)(unsafe.Pointer(&b[i])) = 0 71 } 72 for ; i < len(b); i++ { 73 b[i] = 0 74 } 75 } 76 } 77 78 //func Zero(ptr unsafe.Pointer, n uintptr) { 79 // memclrNoHeapPointers(ptr, n) 80 // //zeroSlow(ptr, n) 81 //} 82 83 // Zero clears n bytes starting at ptr. 84 // 85 // Usually you should use typedmemclr. memclrNoHeapPointers should be 86 // used only when the caller knows that *ptr contains no heap pointers 87 // because either: 88 // 89 // *ptr is initialized memory and its type is pointer-free, or 90 // 91 // *ptr is uninitialized memory (e.g., memory that's being reused 92 // for a new allocation) and hence contains only "junk". 93 // 94 // memclrNoHeapPointers ensures that if ptr is pointer-aligned, and n 95 // is a multiple of the pointer size, then any pointer-aligned, 96 // pointer-sized portion is cleared atomically. Despite the function 97 // name, this is necessary because this function is the underlying 98 // implementation of typedmemclr and memclrHasPointers. See the doc of 99 // Memmove for more details. 100 // 101 // The (CPU-specific) implementations of this function are in memclr_*.s. 102 // 103 //go:noescape 104 //go:linkname Zero runtime.memclrNoHeapPointers 105 func Zero(ptr unsafe.Pointer, n uintptr) 106 107 //func Memequal(a, b unsafe.Pointer, n uintptr) bool { 108 // if a == nil { 109 // return b == nil 110 // } 111 // return *(*string)(unsafe.Pointer(&reflect.SliceHeader{ 112 // Data: uintptr(a), 113 // Len: int(n), 114 // })) == *(*string)(unsafe.Pointer(&reflect.SliceHeader{ 115 // Data: uintptr(b), 116 // Len: int(n), 117 // })) 118 //} 119 120 //go:linkname Equals runtime.memequal 121 func Equals(a, b unsafe.Pointer, size uintptr) bool 122 123 //go:linkname Fastrand runtime.fastrand 124 func Fastrand() uint32