github.com/moontrade/nogc@v0.1.7/tinygc_tinygounix.go (about) 1 //go:build tinygo && gc.provided && !tinygo.wasm && (darwin || (linux && !baremetal && !wasi) || (freebsd && !baremetal)) && !nintendoswitch 2 3 package nogc 4 5 import ( 6 "unsafe" 7 ) 8 9 //////////////////////////////////////////////////////////////////////////////////// 10 // GC Instance 11 //////////////////////////////////////////////////////////////////////////////////// 12 13 //var collector *gc 14 15 //go:linkname gcInitHeap runtime.gcInitHeap 16 func gcInitHeap(heapStart, heapEnd uintptr) { 17 println("gcInitHeap!!!", uint(heapStart), uint(heapEnd)) 18 //if allocator == nil { 19 // initAllocator(heapStart, heapEnd) 20 //} 21 collector = newGC(64, doMarkGlobals, doMarkStack) 22 } 23 24 //////////////////////////////////////////////////////////////////////////////////// 25 // gcAlloc hook 26 //////////////////////////////////////////////////////////////////////////////////// 27 28 //go:linkname gcAlloc runtime.gcAlloc 29 func gcAlloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { 30 if gc_TRACE { 31 println("gcAlloc", uint(size)) 32 } 33 34 ptr := collector.New(size) 35 //println("alloc ptr", uint(ptr)) 36 return unsafe.Pointer(ptr) 37 } 38 39 //////////////////////////////////////////////////////////////////////////////////// 40 // gcFree hook 41 //////////////////////////////////////////////////////////////////////////////////// 42 43 //go:linkname gcFree runtime.gcFree 44 func gcFree(ptr unsafe.Pointer) { 45 if gc_TRACE { 46 println("gcFree", uint(uintptr(ptr))) 47 } 48 if !collector.Free(uintptr(ptr)) { 49 Free(Pointer(ptr)) 50 } 51 } 52 53 //////////////////////////////////////////////////////////////////////////////////// 54 // gcRun hook 55 //////////////////////////////////////////////////////////////////////////////////// 56 57 //go:linkname gcRun runtime.gcRun 58 func gcRun() { 59 //start := time.Now().UnixNano() 60 collector.Collect() 61 62 //println("full GC", time.Now().UnixNano()-start) 63 //collector.Print() 64 } 65 66 //go:linkname gcKeepAlive runtime.gcKeepAlive 67 func gcKeepAlive(x interface{}) { 68 //println("gcKeepAlive") 69 } 70 71 //go:linkname gcSetFinalizer runtime.gcSetFinalizer 72 func gcSetFinalizer(obj interface{}, finalizer interface{}) { 73 //println("gcSetFinalizer") 74 } 75 76 //////////////////////////////////////////////////////////////////////////////////// 77 // gcSetHeapEnd hook 78 //////////////////////////////////////////////////////////////////////////////////// 79 80 //go:linkname gcSetHeapEnd runtime.gcSetHeapEnd 81 func gcSetHeapEnd(newHeapEnd uintptr) { 82 //println("gcSetHeapEnd", uint(newHeapEnd)) 83 } 84 85 //////////////////////////////////////////////////////////////////////////////////// 86 // markGlobals hook 87 //////////////////////////////////////////////////////////////////////////////////// 88 89 func doMarkGlobals() { 90 markGlobals() 91 markScheduler() 92 } 93 94 //go:linkname markGlobals runtime.markGlobals 95 func markGlobals() 96 97 //go:linkname gcMarkGlobals runtime.gcMarkGlobals 98 func gcMarkGlobals(start, end uintptr) { 99 //println("gcMarkGlobals", uint(start), uint(end)) 100 //collector.markRoots(Pointer(start), Pointer(end)) 101 collector.markRoot(end) 102 } 103 104 //////////////////////////////////////////////////////////////////////////////////// 105 // markStack hook 106 //////////////////////////////////////////////////////////////////////////////////// 107 108 func doMarkStack() { 109 markStack() 110 } 111 112 //go:linkname markStack runtime.markStack 113 func markStack() 114 115 //////////////////////////////////////////////////////////////////////////////////// 116 // gcMarkRoots hook 117 //////////////////////////////////////////////////////////////////////////////////// 118 119 //go:linkname gcMarkRoots runtime.gcMarkRoots 120 func gcMarkRoots(start, end uintptr) { 121 //println("gcMarkRoots", uint(start), uint(end)) 122 if start == 0 { 123 collector.markRoot(end) 124 } else { 125 if end-start < 1000000 { 126 collector.markRoots(start, end) 127 } else { 128 collector.markRoot(end) 129 } 130 } 131 } 132 133 //////////////////////////////////////////////////////////////////////////////////// 134 // gcMarkRoot hook 135 //////////////////////////////////////////////////////////////////////////////////// 136 137 //go:linkname gcMarkRoot runtime.gcMarkRoot 138 func gcMarkRoot(addr, root uintptr) { 139 //println("gcMarkRoot", uint(addr), uint(root)) 140 collector.markRoot(root) 141 } 142 143 //////////////////////////////////////////////////////////////////////////////////// 144 // markScheduler hook 145 //////////////////////////////////////////////////////////////////////////////////// 146 147 //go:linkname markScheduler runtime.markScheduler 148 func markScheduler() 149 150 //////////////////////////////////////////////////////////////////////////////////// 151 // gcMarkTask hook 152 //////////////////////////////////////////////////////////////////////////////////// 153 154 //go:linkname gcMarkTask runtime.gcMarkTask 155 func gcMarkTask(runQueuePtr, taskPtr uintptr) { 156 println("gcMarkTask", uint(runQueuePtr), uint(taskPtr)) 157 collector.markRoot(taskPtr) 158 }