Skip to content

Commit 4643401

Browse files
aykevldeadprogram
authored andcommitted
runtime: refactor markGlobals to findGlobals
Instead of markGlobals calling markRoots unconditionally (which doesn't make sense for -gc=none and -gc=leaking), provide markRoots as a callback function. This is in preparation for -gc=boehm, where the previous design is even more awkward and a callback makes far more sense. I've tested the size impact using `make smoketest XTENSA=0`. There is none, except for two cases: * One with `-opt=0` so const-propagation for the callback didn't take place. * One other on AVR, I don't know why but as it's only 16 bytes in a very specific case I'm going to assume it's just a random change in compiler output that caused a size difference.
1 parent dc44988 commit 4643401

File tree

8 files changed

+20
-27
lines changed

8 files changed

+20
-27
lines changed

src/runtime/gc_blocks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ func runGC() (freeBytes uintptr) {
420420

421421
// Mark phase: mark all reachable objects, recursively.
422422
markStack()
423-
markGlobals()
423+
findGlobals(markRoots)
424424

425425
if baremetal && hasScheduler {
426426
// Channel operations in interrupts may move task pointers around while we are marking.

src/runtime/gc_globals.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
package runtime
44

5-
// This file implements markGlobals for all the files that don't have a more
6-
// specific implementation.
5+
// This file implements findGlobals for all systems where the start and end of
6+
// the globals section can be found through linker-defined symbols.
77

8-
// markGlobals marks all globals, which are reachable by definition.
8+
// findGlobals finds all globals (which are reachable by definition) and calls
9+
// the callback for them.
910
//
1011
// This implementation marks all globals conservatively and assumes it can use
1112
// linker-defined symbols for the start and end of the .data section.
12-
func markGlobals() {
13-
markRoots(globalsStart, globalsEnd)
13+
func findGlobals(found func(start, end uintptr)) {
14+
found(globalsStart, globalsEnd)
1415
}

src/runtime/gc_leaking.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,3 @@ func setHeapEnd(newHeapEnd uintptr) {
100100
// enough.
101101
heapEnd = newHeapEnd
102102
}
103-
104-
func markRoots(start, end uintptr) {
105-
// dummy, so that markGlobals will compile
106-
}

src/runtime/gc_none.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,3 @@ func initHeap() {
3737
func setHeapEnd(newHeapEnd uintptr) {
3838
// Nothing to do here, this function is never actually called.
3939
}
40-
41-
func markRoots(start, end uintptr) {
42-
// dummy, so that markGlobals will compile
43-
}

src/runtime/os_darwin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ type segmentLoadCommand struct {
5454
//go:extern _mh_execute_header
5555
var libc_mh_execute_header machHeader
5656

57-
// Mark global variables.
57+
// Find global variables in .data/.bss sections.
5858
// The MachO linker doesn't seem to provide symbols for the start and end of the
5959
// data section. There is get_etext, get_edata, and get_end, but these are
6060
// undocumented and don't work with ASLR (which is enabled by default).
6161
// Therefore, read the MachO header directly.
62-
func markGlobals() {
62+
func findGlobals(found func(start, end uintptr)) {
6363
// Here is a useful blog post to understand the MachO file format:
6464
// https://h3adsh0tzz.com/2020/01/macho-file-format/
6565

@@ -103,7 +103,7 @@ func markGlobals() {
103103
// This could be improved by only reading the memory areas
104104
// covered by sections. That would reduce the amount of memory
105105
// scanned a little bit (up to a single VM page).
106-
markRoots(offset+cmd.vmaddr, offset+cmd.vmaddr+cmd.vmsize)
106+
found(offset+cmd.vmaddr, offset+cmd.vmaddr+cmd.vmsize)
107107
}
108108
}
109109

src/runtime/os_linux.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ type elfProgramHeader32 struct {
7777
//go:extern __ehdr_start
7878
var ehdr_start elfHeader
7979

80-
// markGlobals marks all globals, which are reachable by definition.
80+
// findGlobals finds globals in the .data/.bss sections.
8181
// It parses the ELF program header to find writable segments.
82-
func markGlobals() {
82+
func findGlobals(found func(start, end uintptr)) {
8383
// Relevant constants from the ELF specification.
8484
// See: https://refspecs.linuxfoundation.org/elf/elf.pdf
8585
const (
@@ -99,14 +99,14 @@ func markGlobals() {
9999
if header._type == PT_LOAD && header.flags&PF_W != 0 {
100100
start := header.vaddr
101101
end := start + header.memsz
102-
markRoots(start, end)
102+
found(start, end)
103103
}
104104
} else {
105105
header := (*elfProgramHeader32)(headerPtr)
106106
if header._type == PT_LOAD && header.flags&PF_W != 0 {
107107
start := header.vaddr
108108
end := start + header.memsz
109-
markRoots(start, end)
109+
found(start, end)
110110
}
111111
}
112112
headerPtr = unsafe.Add(headerPtr, ehdr_start.phentsize)

src/runtime/os_windows.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ var module *exeHeader
5252
// around 160 bytes of amd64 instructions.
5353
// Most of this function is based on the documentation in
5454
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format.
55-
func markGlobals() {
55+
func findGlobals(found func(start, end uintptr)) {
5656
// Constants used in this function.
5757
const (
5858
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
@@ -85,7 +85,7 @@ func markGlobals() {
8585
// Found a writable section. Scan the entire section for roots.
8686
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
8787
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
88-
markRoots(start, end)
88+
found(start, end)
8989
}
9090
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
9191
}

src/runtime/runtime_nintendoswitch.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,17 +245,17 @@ var bssStartSymbol [0]byte
245245
//go:extern __bss_end
246246
var bssEndSymbol [0]byte
247247

248-
// Mark global variables.
248+
// Find global variables.
249249
// The linker script provides __*_start and __*_end symbols that can be used to
250250
// scan the given sections. They are already aligned so don't need to be
251251
// manually aligned here.
252-
func markGlobals() {
252+
func findGlobals(found func(start, end uintptr)) {
253253
dataStart := uintptr(unsafe.Pointer(&dataStartSymbol))
254254
dataEnd := uintptr(unsafe.Pointer(&dataEndSymbol))
255-
markRoots(dataStart, dataEnd)
255+
found(dataStart, dataEnd)
256256
bssStart := uintptr(unsafe.Pointer(&bssStartSymbol))
257257
bssEnd := uintptr(unsafe.Pointer(&bssEndSymbol))
258-
markRoots(bssStart, bssEnd)
258+
found(bssStart, bssEnd)
259259
}
260260

261261
// getContextPtr returns the hblauncher context

0 commit comments

Comments
 (0)