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  }