mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
runtime: make out-of-memory failures fatal
Match the Go runtime by terminating instead of unwinding when an allocator exhausts the heap. Recovering an OOM can leave allocator locks held and cannot safely continue when the panic path itself needs memory.
This commit is contained in:
@@ -416,7 +416,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||
size += bytesPerBlock - 1
|
||||
if size < rawSize {
|
||||
// The size overflowed.
|
||||
runtimePanicAt(returnAddress(0), "out of memory")
|
||||
runtimeFatal("out of memory")
|
||||
}
|
||||
neededBlocks := size / bytesPerBlock
|
||||
size = neededBlocks * bytesPerBlock
|
||||
@@ -465,7 +465,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||
// Unfortunately the heap could not be increased. This
|
||||
// happens on baremetal systems for example (where all
|
||||
// available RAM has already been dedicated to the heap).
|
||||
runtimePanicAt(returnAddress(0), "out of memory")
|
||||
runtimeFatal("out of memory")
|
||||
}
|
||||
|
||||
// Set the block states.
|
||||
|
||||
@@ -87,7 +87,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||
gcResumeWorld()
|
||||
gcLock.Unlock()
|
||||
if ptr == nil {
|
||||
runtimePanic("gc: out of memory")
|
||||
runtimeFatal("gc: out of memory")
|
||||
}
|
||||
|
||||
return ptr
|
||||
|
||||
@@ -53,7 +53,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||
continue
|
||||
}
|
||||
// Failed to make the heap bigger, so we must really be out of memory.
|
||||
runtimePanic("out of memory")
|
||||
runtimeFatal("out of memory")
|
||||
}
|
||||
gcLock.Unlock()
|
||||
|
||||
|
||||
@@ -91,6 +91,18 @@ func runtimePanic(msg string) {
|
||||
runtimePanicAt(returnAddress(0), msg)
|
||||
}
|
||||
|
||||
// runtimeFatal terminates for runtime failures that cannot safely be
|
||||
// recovered, such as exhausting the heap.
|
||||
func runtimeFatal(msg string) {
|
||||
if panicStrategy() == tinygo.PanicStrategyTrap {
|
||||
trap()
|
||||
}
|
||||
printstring("fatal error: ")
|
||||
printstring(msg)
|
||||
printnl()
|
||||
abort()
|
||||
}
|
||||
|
||||
func runtimePanicAt(addr unsafe.Pointer, msg string) {
|
||||
if panicStrategy() == tinygo.PanicStrategyTrap {
|
||||
trap()
|
||||
|
||||
Reference in New Issue
Block a user