Files
tinygo/src/runtime/gc_leaking.go
T
Rouven Broszeit 0f69d016a0 Added realloc implementation to GCs
When using the latest wasi-libc I experienced a
panic on an attempt to call realloc. My first attempt to
add it to arch_tinygowasm.go was obviously not good (PR #2194). So here
is another suggestion.
2021-12-10 17:51:08 +01:00

82 lines
1.9 KiB
Go

// +build gc.leaking
package runtime
// This GC implementation is the simplest useful memory allocator possible: it
// only allocates memory and never frees it. For some constrained systems, it
// may be the only memory allocator possible.
import (
"unsafe"
)
// Ever-incrementing pointer: no memory is freed.
var heapptr = heapStart
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
// TODO: this can be optimized by not casting between pointers and ints so
// much. And by using platform-native data types (e.g. *uint8 for 8-bit
// systems).
size = align(size)
addr := heapptr
heapptr += size
for heapptr >= heapEnd {
// Try to increase the heap and check again.
if growHeap() {
continue
}
// Failed to make the heap bigger, so we must really be out of memory.
runtimePanic("out of memory")
}
for i := uintptr(0); i < uintptr(size); i += 4 {
ptr := (*uint32)(unsafe.Pointer(addr + i))
*ptr = 0
}
return unsafe.Pointer(addr)
}
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
newAlloc := alloc(size, nil)
if ptr == nil {
return newAlloc
}
// according to POSIX everything beyond the previous pointer's
// size will have indeterminate values so we can just copy garbage
memcpy(newAlloc, ptr, size)
return newAlloc
}
func free(ptr unsafe.Pointer) {
// Memory is never freed.
}
func GC() {
// No-op.
}
func KeepAlive(x interface{}) {
// Unimplemented. Only required with SetFinalizer().
}
func SetFinalizer(obj interface{}, finalizer interface{}) {
// Unimplemented.
}
func initHeap() {
// preinit() may have moved heapStart; reset heapptr
ptr := heapStart
if GOARCH == "wasm" {
// llvm11 and llvm12 do not correctly align the heap on wasm
ptr = align(ptr)
}
heapptr = ptr
}
// setHeapEnd sets a new (larger) heapEnd pointer.
func setHeapEnd(newHeapEnd uintptr) {
// This "heap" is so simple that simply assigning a new value is good
// enough.
heapEnd = newHeapEnd
}