mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 02:57:46 +00:00
d1e96fd0a8
Make the GC globals scan phase conservative instead of precise on WebAssembly. This reduces code size at the risk of introducing some false positives. This is a stopgap measure to mitigate an issue with the precise scanning of globals that doesn't track all pointers. It works for regular globals but globals created in the interp package don't always have a type and therefore may be missed by the AddGlobalsBitmap pass. The same issue is present on Linux and macOS, but is not as noticeable there.
36 lines
985 B
Go
36 lines
985 B
Go
// +build gc.conservative gc.extalloc
|
|
// +build !baremetal,!wasm
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
//go:extern runtime.trackedGlobalsStart
|
|
var trackedGlobalsStart uintptr
|
|
|
|
//go:extern runtime.trackedGlobalsLength
|
|
var trackedGlobalsLength uintptr
|
|
|
|
//go:extern runtime.trackedGlobalsBitmap
|
|
var trackedGlobalsBitmap [0]uint8
|
|
|
|
// markGlobals marks all globals, which are reachable by definition.
|
|
//
|
|
// This implementation relies on a compiler pass that stores all globals in a
|
|
// single global (adjusting all uses of them accordingly) and creates a bit
|
|
// vector with the locations of each pointer. This implementation then walks the
|
|
// bit vector and for each pointer it indicates, it marks the root.
|
|
//
|
|
//go:nobounds
|
|
func markGlobals() {
|
|
for i := uintptr(0); i < trackedGlobalsLength; i++ {
|
|
if trackedGlobalsBitmap[i/8]&(1<<(i%8)) != 0 {
|
|
addr := trackedGlobalsStart + i*unsafe.Alignof(uintptr(0))
|
|
root := *(*uintptr)(unsafe.Pointer(addr))
|
|
markRoot(addr, root)
|
|
}
|
|
}
|
|
}
|