mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-09-11 23:19:30 +00:00
runtime: precisely scan Wasm globals
This commit is contained in:
@@ -48,7 +48,6 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
||||
func free(ptr unsafe.Pointer)
|
||||
|
||||
// markRoots is called with the start and end addresses to scan for references.
|
||||
// It is currently only called with the top and bottom of the stack.
|
||||
func markRoots(start, end uintptr)
|
||||
|
||||
// GC is called to explicitly run garbage collection.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//go:build (gc.conservative || gc.precise) && tinygo.wasm
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func markGlobals() {
|
||||
for i := uintptr(0); i < gcGlobalRootCount(); i++ {
|
||||
addr := gcGlobalRoot(i)
|
||||
size := gcGlobalRootSize(i)
|
||||
for offset := uintptr(0); offset < size; offset += unsafe.Sizeof(uintptr(0)) {
|
||||
slot := unsafe.Add(addr, offset)
|
||||
markRoot(uintptr(slot), *(*uintptr)(slot))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These functions are generated by the compiler from the pointer layouts of
|
||||
// mutable globals. Each range contains only pointer slots.
|
||||
func gcGlobalRootCount() uintptr
|
||||
func gcGlobalRoot(index uintptr) unsafe.Pointer
|
||||
func gcGlobalRootSize(index uintptr) uintptr
|
||||
@@ -0,0 +1,18 @@
|
||||
//go:build gc.custom && tinygo.wasm
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func markGlobals() {
|
||||
for i := uintptr(0); i < gcGlobalRootCount(); i++ {
|
||||
start := uintptr(gcGlobalRoot(i))
|
||||
markRoots(start, start+gcGlobalRootSize(i))
|
||||
}
|
||||
}
|
||||
|
||||
// These functions are generated by the compiler from the pointer layouts of
|
||||
// mutable globals. Each range contains only pointer slots.
|
||||
func gcGlobalRootCount() uintptr
|
||||
func gcGlobalRoot(index uintptr) unsafe.Pointer
|
||||
func gcGlobalRootSize(index uintptr) uintptr
|
||||
@@ -0,0 +1,40 @@
|
||||
//go:build gc.boehm && tinygo.wasm
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func markGlobals() {
|
||||
rangeCount := gcGlobalRootCount()
|
||||
if rangeCount == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var rootCount uintptr
|
||||
for i := uintptr(0); i < rangeCount; i++ {
|
||||
rootCount += gcGlobalRootSize(i) / unsafe.Sizeof(uintptr(0))
|
||||
}
|
||||
|
||||
// markRoots only accepts a range, so copy all global pointers into
|
||||
// contiguous scratch space for marking.
|
||||
roots := unsafe.Slice((*uintptr)(gcGlobalRootValues()), rootCount)
|
||||
var rootIndex uintptr
|
||||
for i := uintptr(0); i < rangeCount; i++ {
|
||||
addr := gcGlobalRoot(i)
|
||||
size := gcGlobalRootSize(i)
|
||||
for offset := uintptr(0); offset < size; offset += unsafe.Sizeof(uintptr(0)) {
|
||||
roots[rootIndex] = *(*uintptr)(unsafe.Add(addr, offset))
|
||||
rootIndex++
|
||||
}
|
||||
}
|
||||
|
||||
start := uintptr(unsafe.Pointer(&roots[0]))
|
||||
markRoots(start, start+rootCount*unsafe.Sizeof(roots[0]))
|
||||
}
|
||||
|
||||
// These functions are generated by the compiler from the pointer layouts of
|
||||
// mutable globals. Each range contains only pointer slots.
|
||||
func gcGlobalRootCount() uintptr
|
||||
func gcGlobalRoot(index uintptr) unsafe.Pointer
|
||||
func gcGlobalRootSize(index uintptr) uintptr
|
||||
func gcGlobalRootValues() unsafe.Pointer
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
func gcMarkReachable() {
|
||||
markStack()
|
||||
findGlobals(markRoots)
|
||||
markGlobals()
|
||||
}
|
||||
|
||||
//go:extern runtime.stackChainStart
|
||||
|
||||
Reference in New Issue
Block a user