tinygo/src/runtime/gc_stack_raw.go
Ayke van Laethem 655075e5e0 runtime: implement precise GC
This implements the block-based GC as a partially precise GC. This means
that for most heap allocations it is known which words contain a pointer
and which don't. This should in theory make the GC faster (because it
can skip non-pointer object) and have fewer false positives in a GC
cycle. It does however use a bit more RAM to store the layout of each
object.

Right now this GC seems to be slower than the conservative GC, but
should be less likely to run out of memory as a result of false
positives.
2023-01-17 19:32:18 +01:00

39 строки
1,1 КиБ
Go

//go:build (gc.conservative || gc.precise) && !tinygo.wasm
package runtime
import "internal/task"
// markStack marks all root pointers found on the stack.
//
// This implementation is conservative and relies on the stack top (provided by
// the linker) and getting the current stack pointer from a register. Also, it
// assumes a descending stack. Thus, it is not very portable.
func markStack() {
// Scan the current stack, and all current registers.
scanCurrentStack()
if !task.OnSystemStack() {
// Mark system stack.
markRoots(getSystemStackPointer(), stackTop)
}
}
//go:export tinygo_scanCurrentStack
func scanCurrentStack()
//go:export tinygo_scanstack
func scanstack(sp uintptr) {
// Mark current stack.
// This function is called by scanCurrentStack, after pushing all registers onto the stack.
// Callee-saved registers have been pushed onto stack by tinygo_localscan, so this will scan them too.
if task.OnSystemStack() {
// This is the system stack.
// Scan all words on the stack.
markRoots(sp, stackTop)
} else {
// This is a goroutine stack.
// It is an allocation, so scan it as if it were a value in a global.
markRoot(0, sp)
}
}