mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 20:13:40 +00:00
gc: drop support for 'precise' globals
Precise globals require a whole program optimization pass that is hard to support when building packages separately. This patch removes support for these globals by converting the last use (Linux) to use linker-defined symbols instead. For details, see: https://github.com/tinygo-org/tinygo/issues/2870
This commit is contained in:
committed by
Ron Evans
parent
5c488e3145
commit
2d61972475
@@ -4,6 +4,9 @@
|
||||
|
||||
package runtime
|
||||
|
||||
// This file implements markGlobals for all the files that don't have a more
|
||||
// specific implementation.
|
||||
|
||||
// markGlobals marks all globals, which are reachable by definition.
|
||||
//
|
||||
// This implementation marks all globals conservatively and assumes it can use
|
||||
@@ -1,35 +0,0 @@
|
||||
//go:build gc.conservative && !baremetal && !darwin && !nintendoswitch && !tinygo.wasm && !windows
|
||||
// +build gc.conservative,!baremetal,!darwin,!nintendoswitch,!tinygo.wasm,!windows
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-2
@@ -1,8 +1,13 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
//go:build linux && !baremetal && !nintendoswitch && !wasi
|
||||
// +build linux,!baremetal,!nintendoswitch,!wasi
|
||||
|
||||
package runtime
|
||||
|
||||
// This file is for systems that are _actually_ Linux (not systems that pretend
|
||||
// to be Linux, like baremetal systems).
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const GOOS = "linux"
|
||||
|
||||
const (
|
||||
@@ -18,3 +23,20 @@ const (
|
||||
clock_REALTIME = 0
|
||||
clock_MONOTONIC_RAW = 4
|
||||
)
|
||||
|
||||
//go:extern _edata
|
||||
var globalsStartSymbol [0]byte
|
||||
|
||||
//go:extern _end
|
||||
var globalsEndSymbol [0]byte
|
||||
|
||||
// markGlobals marks all globals, which are reachable by definition.
|
||||
//
|
||||
// This implementation marks all globals conservatively and assumes it can use
|
||||
// linker-defined symbols for the start and end of the .data section.
|
||||
func markGlobals() {
|
||||
start := uintptr(unsafe.Pointer(&globalsStartSymbol))
|
||||
end := uintptr(unsafe.Pointer(&globalsEndSymbol))
|
||||
start = (start + unsafe.Alignof(uintptr(0)) - 1) &^ (unsafe.Alignof(uintptr(0)) - 1) // align on word boundary
|
||||
markRoots(start, end)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//go:build linux && (baremetal || nintendoswitch || wasi)
|
||||
// +build linux
|
||||
// +build baremetal nintendoswitch wasi
|
||||
|
||||
// Other systems that aren't operating systems supported by the Go toolchain
|
||||
// need to pretend to be an existing operating system. Linux seems like a good
|
||||
// choice for this for its wide hardware support.
|
||||
|
||||
package runtime
|
||||
|
||||
const GOOS = "linux"
|
||||
Reference in New Issue
Block a user