mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-09-11 15:09:32 +00:00
runtime: eagerly mark Boehm global roots
This commit is contained in:
@@ -165,6 +165,9 @@ func libgc_size(ptr uintptr) uintptr
|
|||||||
//export GC_push_all
|
//export GC_push_all
|
||||||
func libgc_push_all(bottom, top uintptr)
|
func libgc_push_all(bottom, top uintptr)
|
||||||
|
|
||||||
|
//export GC_push_all_eager
|
||||||
|
func libgc_push_all_eager(bottom, top uintptr)
|
||||||
|
|
||||||
//export GC_push_all_stack
|
//export GC_push_all_stack
|
||||||
func libgc_push_all_stack(bottom, top uintptr)
|
func libgc_push_all_stack(bottom, top uintptr)
|
||||||
|
|
||||||
|
|||||||
@@ -5,31 +5,12 @@ package runtime
|
|||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func markGlobals() {
|
func markGlobals() {
|
||||||
rangeCount := gcGlobalRootCount()
|
for i := uintptr(0); i < gcGlobalRootCount(); i++ {
|
||||||
if rangeCount == 0 {
|
addr := gcGlobalRoot(uintptr(i))
|
||||||
return
|
// GC_push_all queues one range per call and overflows Boehm's mark
|
||||||
|
// stack for programs with thousands of roots. Scan each range now.
|
||||||
|
libgc_push_all_eager(uintptr(addr), uintptr(addr)+gcGlobalRootSize(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// These functions are generated by the compiler from the pointer layouts of
|
||||||
@@ -37,4 +18,3 @@ func markGlobals() {
|
|||||||
func gcGlobalRootCount() uintptr
|
func gcGlobalRootCount() uintptr
|
||||||
func gcGlobalRoot(index uintptr) unsafe.Pointer
|
func gcGlobalRoot(index uintptr) unsafe.Pointer
|
||||||
func gcGlobalRootSize(index uintptr) uintptr
|
func gcGlobalRootSize(index uintptr) uintptr
|
||||||
func gcGlobalRootValues() unsafe.Pointer
|
|
||||||
|
|||||||
Vendored
-2
@@ -19,8 +19,6 @@ declare ptr @runtime.gcGlobalRoot(i32)
|
|||||||
|
|
||||||
declare i32 @runtime.gcGlobalRootSize(i32)
|
declare i32 @runtime.gcGlobalRootSize(i32)
|
||||||
|
|
||||||
declare ptr @runtime.gcGlobalRootValues()
|
|
||||||
|
|
||||||
; Generic function that returns a pointer (that must be tracked).
|
; Generic function that returns a pointer (that must be tracked).
|
||||||
define ptr @getPointer() {
|
define ptr @getPointer() {
|
||||||
ret ptr @someGlobal
|
ret ptr @someGlobal
|
||||||
|
|||||||
-6
@@ -9,7 +9,6 @@ target triple = "wasm32-unknown-unknown-wasm"
|
|||||||
@ptrArrayGlobal = global [8 x ptr] zeroinitializer
|
@ptrArrayGlobal = global [8 x ptr] zeroinitializer
|
||||||
@constantPtrGlobal = constant ptr @someGlobal
|
@constantPtrGlobal = constant ptr @someGlobal
|
||||||
@runtime.gcGlobalRoots = internal constant [4 x { ptr, i32 }] [{ ptr, i32 } { ptr @ptrGlobal, i32 4 }, { ptr, i32 } { ptr @structGlobal, i32 4 }, { ptr, i32 } { ptr getelementptr (i8, ptr @structGlobal, i32 8), i32 8 }, { ptr, i32 } { ptr @ptrArrayGlobal, i32 32 }]
|
@runtime.gcGlobalRoots = internal constant [4 x { ptr, i32 }] [{ ptr, i32 } { ptr @ptrGlobal, i32 4 }, { ptr, i32 } { ptr @structGlobal, i32 4 }, { ptr, i32 } { ptr getelementptr (i8, ptr @structGlobal, i32 8), i32 8 }, { ptr, i32 } { ptr @ptrArrayGlobal, i32 32 }]
|
||||||
@runtime.gcGlobalRootValueArray = internal global [12 x i32] zeroinitializer
|
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly)
|
declare void @runtime.trackPointer(ptr nocapture readonly)
|
||||||
|
|
||||||
@@ -36,11 +35,6 @@ entry:
|
|||||||
ret i32 %3
|
ret i32 %3
|
||||||
}
|
}
|
||||||
|
|
||||||
define ptr @runtime.gcGlobalRootValues() {
|
|
||||||
entry:
|
|
||||||
ret ptr @runtime.gcGlobalRootValueArray
|
|
||||||
}
|
|
||||||
|
|
||||||
define ptr @getPointer() {
|
define ptr @getPointer() {
|
||||||
ret ptr @someGlobal
|
ret ptr @someGlobal
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user