github.com/moontrade/nogc@v0.1.7/tinygc_tinygowasm.go (about)

     1  //go:build gc.provided && tinygo.wasm
     2  
     3  package nogc
     4  
     5  import (
     6  	"unsafe"
     7  )
     8  
     9  func getCollector() *gc {
    10  	if collector != nil {
    11  		return collector
    12  	}
    13  	p := AllocZeroed(unsafe.Sizeof(gc{}))
    14  	collector = (*gc)(p.Unsafe())
    15  	initGC(collector, 64)
    16  	return collector
    17  }
    18  
    19  ////////////////////////////////////////////////////////////////////////////////////
    20  // GC Instance
    21  ////////////////////////////////////////////////////////////////////////////////////
    22  
    23  //go:linkname gcInitHeap runtime.gcInitHeap
    24  func gcInitHeap(heapStart, heapEnd uintptr) {
    25  	if allocator == nil {
    26  		if gc_TRACE {
    27  			println("gcInitHeap initAllocator", uint(heapStart), uint(heapEnd))
    28  		}
    29  		initAllocator(heapStart, heapEnd)
    30  	} else {
    31  		println("allocator is already initialized")
    32  	}
    33  	if gc_TRACE {
    34  		println("gcInitHeap", uint(heapStart), uint(heapEnd))
    35  	}
    36  	//p := AllocZeroed(unsafe.Sizeof(gc{}))
    37  	//collector = (*gc)(p.Unsafe())
    38  	getCollector()
    39  	//initGC(&collector, 64)
    40  	//collector = newGC(64, doMarkGlobals, doMarkStack)
    41  }
    42  
    43  ////////////////////////////////////////////////////////////////////////////////////
    44  // gcAlloc hook
    45  ////////////////////////////////////////////////////////////////////////////////////
    46  
    47  //go:linkname gcAlloc runtime.gcAlloc
    48  func gcAlloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
    49  	if gc_TRACE {
    50  		println("gcAlloc", uint(size), uint(uintptr(layout)))
    51  	}
    52  	println("gcAlloc", uint(size), uint(uintptr(layout)))
    53  
    54  	//ptr := AllocZeroed(size)
    55  	ptr := collector.New(size)
    56  	return unsafe.Pointer(ptr)
    57  }
    58  
    59  //go:linkname gcRealloc runtime.gcRealloc
    60  func gcRealloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
    61  	if gc_TRACE {
    62  		println("gcRealloc", uint(uintptr(ptr)), "size", uint(size))
    63  	}
    64  	p := collector.Realloc(uintptr(ptr), size)
    65  	return unsafe.Pointer(p)
    66  }
    67  
    68  ////////////////////////////////////////////////////////////////////////////////////
    69  // gcFree hook
    70  ////////////////////////////////////////////////////////////////////////////////////
    71  
    72  //go:linkname gcFree runtime.gcFree
    73  func gcFree(ptr unsafe.Pointer) {
    74  	if gc_TRACE {
    75  		println("gcFree", uint(uintptr(ptr)))
    76  	}
    77  	if !collector.Free(uintptr(ptr)) {
    78  		Free(Pointer(ptr))
    79  	}
    80  }
    81  
    82  //go:linkname gcRegisterGlobal runtime.gcRegisterGlobal
    83  func gcRegisterGlobal(ptr uintptr, tag int) {
    84  	if gc_TRACE {
    85  		println("gcRegisterGlobal", uint(ptr), "tag", tag)
    86  	}
    87  	switch tag {
    88  	case 1:
    89  		getCollector().runqueue = ptr
    90  	case 2:
    91  		getCollector().sleepQueue = ptr
    92  	case 3:
    93  		//println("gcRegisterGlobal", uint(ptr), "tag", tag)
    94  		getCollector().currentTask = ptr
    95  	case 4:
    96  		getCollector().heapStart = ptr
    97  	case 5:
    98  		getCollector().heapEnd = ptr
    99  	case 6:
   100  		getCollector().globalsStart = ptr
   101  	case 7:
   102  		getCollector().globalsEnd = ptr
   103  	case 8:
   104  		getCollector().envArgs = ptr
   105  	case 9:
   106  		getCollector().envArgsPointer = ptr
   107  	}
   108  }
   109  
   110  ////////////////////////////////////////////////////////////////////////////////////
   111  // gcRun hook
   112  ////////////////////////////////////////////////////////////////////////////////////
   113  
   114  //go:linkname gcRun runtime.gcRun
   115  func gcRun() {
   116  	if gc_TRACE {
   117  		println("gcRun")
   118  	}
   119  	//start := time.Now().UnixNano()
   120  
   121  	collector.Collect()
   122  
   123  	//println("full GC", time.Now().UnixNano()-start)
   124  	//collector.Print()
   125  }
   126  
   127  //go:linkname gcKeepAlive runtime.gcKeepAlive
   128  func gcKeepAlive(x interface{}) {
   129  	if gc_TRACE {
   130  		println("gcKeepAlive")
   131  	}
   132  }
   133  
   134  //go:linkname gcSetFinalizer runtime.gcSetFinalizer
   135  func gcSetFinalizer(obj interface{}, finalizer interface{}) {
   136  	if gc_TRACE {
   137  		println("gcSetFinalizer")
   138  	}
   139  }
   140  
   141  ////////////////////////////////////////////////////////////////////////////////////
   142  // gcSetHeapEnd hook
   143  ////////////////////////////////////////////////////////////////////////////////////
   144  
   145  //go:linkname gcSetHeapEnd runtime.gcSetHeapEnd
   146  func gcSetHeapEnd(newHeapEnd uintptr) {
   147  	if gc_TRACE {
   148  		println("gcSetHeapEnd", uint(newHeapEnd))
   149  	}
   150  }
   151  
   152  ////////////////////////////////////////////////////////////////////////////////////
   153  // markGlobals hook
   154  ////////////////////////////////////////////////////////////////////////////////////
   155  
   156  func doMarkGlobals() {
   157  	if gc_TRACE {
   158  		println("doMarkGlobals")
   159  	}
   160  	markScheduler()
   161  	markGlobals()
   162  }
   163  
   164  //go:linkname markGlobals runtime.markGlobals
   165  func markGlobals()
   166  
   167  //go:linkname gcMarkGlobals runtime.gcMarkGlobals
   168  func gcMarkGlobals(start, end uintptr) {
   169  	if gc_TRACE {
   170  		println("gcMarkGlobals", uint(start), uint(end))
   171  	}
   172  	//println("gcMarkGlobals", uint(start), uint(end))
   173  	collector.markRoots(start, end)
   174  }
   175  
   176  ////////////////////////////////////////////////////////////////////////////////////
   177  // markStack hook
   178  ////////////////////////////////////////////////////////////////////////////////////
   179  
   180  func doMarkStack() {
   181  	if gc_TRACE {
   182  		println("doMarkStack")
   183  	}
   184  	markStack()
   185  }
   186  
   187  //go:linkname gcMarkStackObject runtime.gcMarkStackObject
   188  func gcMarkStackObject(start, end uintptr) {
   189  	if gc_TRACE {
   190  		println("gcMarkStackObject", uint(start), uint(end))
   191  	}
   192  
   193  	//println("gcMarkStackObject", uint(start), uint(end))
   194  	//for ptr := start; ptr < end; ptr += unsafe.Alignof(ptr) {
   195  	//	p := *(*uintptr)(unsafe.Pointer(ptr)) - gc_ObjectOverhead
   196  	//	println("stack slot", uint(ptr), "value", uint(p))
   197  	//}
   198  	collector.markRoots(start, end)
   199  }
   200  
   201  //go:linkname markStack runtime.markStack
   202  func markStack()
   203  
   204  ////////////////////////////////////////////////////////////////////////////////////
   205  // gcMarkRoots hook
   206  ////////////////////////////////////////////////////////////////////////////////////
   207  
   208  //go:linkname gcMarkRoots runtime.gcMarkRoots
   209  func gcMarkRoots(start, end uintptr) {
   210  	if gc_TRACE {
   211  		println("gcMarkRoots", uint(start), uint(end))
   212  	}
   213  	collector.markRoots(start, end)
   214  }
   215  
   216  ////////////////////////////////////////////////////////////////////////////////////
   217  // gcMarkRoot hook
   218  ////////////////////////////////////////////////////////////////////////////////////
   219  
   220  //go:linkname gcMarkRoot runtime.gcMarkRoot
   221  func gcMarkRoot(addr, root uintptr) {
   222  	if gc_TRACE {
   223  		println("gcMarkRoot", uint(addr), uint(root))
   224  	}
   225  	if root == 0 {
   226  		return
   227  	}
   228  	collector.markRoot(root)
   229  }
   230  
   231  ////////////////////////////////////////////////////////////////////////////////////
   232  // markScheduler hook
   233  ////////////////////////////////////////////////////////////////////////////////////
   234  
   235  //go:linkname markScheduler runtime.markScheduler
   236  func markScheduler()
   237  
   238  ////////////////////////////////////////////////////////////////////////////////////
   239  // gcMarkTask hook
   240  ////////////////////////////////////////////////////////////////////////////////////
   241  
   242  //go:linkname gcMarkTask runtime.gcMarkTask
   243  func gcMarkTask(runQueuePtr, taskPtr uintptr) {
   244  	if gc_TRACE {
   245  		println("gcMarkTask", uint(allocator.HeapStart), uint(runQueuePtr), uint(taskPtr))
   246  	}
   247  	println("gcMarkTask", uint(allocator.HeapStart), uint(runQueuePtr), uint(taskPtr))
   248  	if taskPtr == 0 {
   249  		return
   250  	}
   251  	collector.markRoot(taskPtr)
   252  }