feat: replace println with gcPanic
This commit is contained in:
@@ -10,8 +10,7 @@ import (
|
|||||||
//go:linkname getsp llgo.stackSave
|
//go:linkname getsp llgo.stackSave
|
||||||
func getsp() unsafe.Pointer
|
func getsp() unsafe.Pointer
|
||||||
|
|
||||||
// when executing initGC(), we must ensure there's no any allocations.
|
// link here for testing
|
||||||
// use linking here to avoid import clite
|
|
||||||
//
|
//
|
||||||
//go:linkname memset C.memset
|
//go:linkname memset C.memset
|
||||||
func memset(unsafe.Pointer, int, uintptr) unsafe.Pointer
|
func memset(unsafe.Pointer, int, uintptr) unsafe.Pointer
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ package tinygogc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
c "github.com/goplus/llgo/runtime/internal/clite"
|
||||||
)
|
)
|
||||||
|
|
||||||
const gcDebug = false
|
const gcDebug = false
|
||||||
@@ -102,11 +104,16 @@ func lazyInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gcPanic(s *c.Char) {
|
||||||
|
c.Printf(c.Str("%s"), s)
|
||||||
|
c.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
// blockFromAddr returns a block given an address somewhere in the heap (which
|
// blockFromAddr returns a block given an address somewhere in the heap (which
|
||||||
// might not be heap-aligned).
|
// might not be heap-aligned).
|
||||||
func blockFromAddr(addr uintptr) uintptr {
|
func blockFromAddr(addr uintptr) uintptr {
|
||||||
if addr < heapStart || addr >= uintptr(metadataStart) {
|
if addr < heapStart || addr >= uintptr(metadataStart) {
|
||||||
println("gc: trying to get block from invalid address")
|
gcPanic(c.Str("gc: trying to get block from invalid address"))
|
||||||
}
|
}
|
||||||
return (addr - heapStart) / bytesPerBlock
|
return (addr - heapStart) / bytesPerBlock
|
||||||
}
|
}
|
||||||
@@ -120,7 +127,7 @@ func gcPointerOf(blockAddr uintptr) unsafe.Pointer {
|
|||||||
func gcAddressOf(blockAddr uintptr) uintptr {
|
func gcAddressOf(blockAddr uintptr) uintptr {
|
||||||
addr := heapStart + blockAddr*bytesPerBlock
|
addr := heapStart + blockAddr*bytesPerBlock
|
||||||
if addr > uintptr(metadataStart) {
|
if addr > uintptr(metadataStart) {
|
||||||
println("gc: block pointing inside metadata")
|
gcPanic(c.Str("gc: block pointing inside metadata"))
|
||||||
}
|
}
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
@@ -151,7 +158,7 @@ func gcFindHead(blockAddr uintptr) uintptr {
|
|||||||
blockAddr--
|
blockAddr--
|
||||||
}
|
}
|
||||||
if gcStateOf(blockAddr) != blockStateHead && gcStateOf(blockAddr) != blockStateMark {
|
if gcStateOf(blockAddr) != blockStateHead && gcStateOf(blockAddr) != blockStateMark {
|
||||||
println("gc: found tail without head")
|
gcPanic(c.Str("gc: found tail without head"))
|
||||||
}
|
}
|
||||||
return blockAddr
|
return blockAddr
|
||||||
}
|
}
|
||||||
@@ -190,7 +197,7 @@ func gcSetState(blockAddr uintptr, newState uint8) {
|
|||||||
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
||||||
*stateBytePtr |= uint8(newState << ((blockAddr % blocksPerStateByte) * stateBits))
|
*stateBytePtr |= uint8(newState << ((blockAddr % blocksPerStateByte) * stateBits))
|
||||||
if gcStateOf(blockAddr) != newState {
|
if gcStateOf(blockAddr) != newState {
|
||||||
println("gc: setState() was not successful")
|
gcPanic(c.Str("gc: setState() was not successful"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +206,7 @@ func gcMarkFree(blockAddr uintptr) {
|
|||||||
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
||||||
*stateBytePtr &^= uint8(blockStateMask << ((blockAddr % blocksPerStateByte) * stateBits))
|
*stateBytePtr &^= uint8(blockStateMask << ((blockAddr % blocksPerStateByte) * stateBits))
|
||||||
if gcStateOf(blockAddr) != blockStateFree {
|
if gcStateOf(blockAddr) != blockStateFree {
|
||||||
println("gc: markFree() was not successful")
|
gcPanic(c.Str("gc: markFree() was not successful"))
|
||||||
}
|
}
|
||||||
*(*[wordsPerBlock]uintptr)(unsafe.Pointer(gcAddressOf(blockAddr))) = [wordsPerBlock]uintptr{}
|
*(*[wordsPerBlock]uintptr)(unsafe.Pointer(gcAddressOf(blockAddr))) = [wordsPerBlock]uintptr{}
|
||||||
}
|
}
|
||||||
@@ -208,13 +215,13 @@ func gcMarkFree(blockAddr uintptr) {
|
|||||||
// before calling this function.
|
// before calling this function.
|
||||||
func gcUnmark(blockAddr uintptr) {
|
func gcUnmark(blockAddr uintptr) {
|
||||||
if gcStateOf(blockAddr) != blockStateMark {
|
if gcStateOf(blockAddr) != blockStateMark {
|
||||||
println("gc: unmark() on a block that is not marked")
|
gcPanic(c.Str("gc: unmark() on a block that is not marked"))
|
||||||
}
|
}
|
||||||
clearMask := blockStateMask ^ blockStateHead // the bits to clear from the state
|
clearMask := blockStateMask ^ blockStateHead // the bits to clear from the state
|
||||||
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, blockAddr/blocksPerStateByte))
|
||||||
*stateBytePtr &^= uint8(clearMask << ((blockAddr % blocksPerStateByte) * stateBits))
|
*stateBytePtr &^= uint8(clearMask << ((blockAddr % blocksPerStateByte) * stateBits))
|
||||||
if gcStateOf(blockAddr) != blockStateHead {
|
if gcStateOf(blockAddr) != blockStateHead {
|
||||||
println("gc: unmark() was not successful")
|
gcPanic(c.Str("gc: unmark() was not successful"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +283,7 @@ func Alloc(size uintptr) unsafe.Pointer {
|
|||||||
// Unfortunately the heap could not be increased. This
|
// Unfortunately the heap could not be increased. This
|
||||||
// happens on baremetal systems for example (where all
|
// happens on baremetal systems for example (where all
|
||||||
// available RAM has already been dedicated to the heap).
|
// available RAM has already been dedicated to the heap).
|
||||||
println("out of memory")
|
gcPanic(c.Str("out of memory"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +398,7 @@ func gc() (freeBytes uintptr) {
|
|||||||
// must be aligned.
|
// must be aligned.
|
||||||
func markRoots(start, end uintptr) {
|
func markRoots(start, end uintptr) {
|
||||||
if start >= end {
|
if start >= end {
|
||||||
println("gc: unexpected range to mark")
|
gcPanic(c.Str("gc: unexpected range to mark"))
|
||||||
}
|
}
|
||||||
// Reduce the end bound to avoid reading too far on platforms where pointer alignment is smaller than pointer size.
|
// Reduce the end bound to avoid reading too far on platforms where pointer alignment is smaller than pointer size.
|
||||||
// If the size of the range is 0, then end will be slightly below start after this.
|
// If the size of the range is 0, then end will be slightly below start after this.
|
||||||
|
|||||||
Reference in New Issue
Block a user