mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 12:03:41 +00:00
avr: use a garbage collector
This might sound crazy, but I think it's better to enable the GC by default to avoid surprises. It costs 1130 bytes of flash and 16 bytes of RAM (plus heap overhead) so it's not exactly free, but if needed it can easily be disabled with `-gc=leaking`. On the Uno (32kB flash, 2kB RAM) that's not massive, on the DigiSpark (8kB flash, 0.5kB RAM) that may be too much depending on the application.
This commit is contained in:
committed by
Ron Evans
parent
6e26728391
commit
15c7d93ea9
@@ -269,6 +269,8 @@ ifneq ($(AVR), 0)
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=digispark examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=digispark -gc=leaking examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
endif
|
||||
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
|
||||
@@ -318,7 +318,7 @@ func markRoots(start, end uintptr) {
|
||||
}
|
||||
}
|
||||
|
||||
for addr := start; addr != end; addr += unsafe.Sizeof(addr) {
|
||||
for addr := start; addr != end; addr += unsafe.Alignof(addr) {
|
||||
root := *(*uintptr)(unsafe.Pointer(addr))
|
||||
markRoot(addr, root)
|
||||
}
|
||||
|
||||
@@ -60,3 +60,12 @@ __vector_WDT:
|
||||
|
||||
pop r16
|
||||
reti
|
||||
|
||||
; This is necessary for the garbage collector.
|
||||
; It returns the stack pointer as an uintptr.
|
||||
.section .text.runtime.getCurrentStackPointer
|
||||
.global runtime.getCurrentStackPointer
|
||||
runtime.getCurrentStackPointer:
|
||||
in r24, 0x3d; SPL
|
||||
in r25, 0x3e; SPH
|
||||
ret
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
"compiler": "avr-gcc",
|
||||
"gc": "leaking",
|
||||
"gc": "conservative",
|
||||
"linker": "avr-gcc",
|
||||
"ldflags": [
|
||||
"-T", "targets/avr.ld",
|
||||
|
||||
@@ -46,3 +46,5 @@ SECTIONS
|
||||
/* For the memory allocator. */
|
||||
_heap_start = _ebss;
|
||||
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_globals_start = _sdata;
|
||||
_globals_end = _ebss;
|
||||
|
||||
Vendored
+9
-2
@@ -23,6 +23,13 @@ var scalarSlices [4][]byte
|
||||
var randSeeds [4]uint32
|
||||
|
||||
func testNonPointerHeap() {
|
||||
maxSliceSize := uint32(1024)
|
||||
if ^uintptr(0) <= 0xffff {
|
||||
// 16-bit and lower devices, such as AVR.
|
||||
// Heap size is a real issue there, while it is still useful to run
|
||||
// these tests. Therefore, lower the max slice size.
|
||||
maxSliceSize = 64
|
||||
}
|
||||
// Allocate roughly 0.5MB of memory.
|
||||
for i := 0; i < 1000; i++ {
|
||||
// Pick a random index that the optimizer can't predict.
|
||||
@@ -38,9 +45,9 @@ func testNonPointerHeap() {
|
||||
}
|
||||
|
||||
// Allocate a randomly-sized slice, randomly sliced to be smaller.
|
||||
sliceLen := randuint32() % 1024
|
||||
sliceLen := randuint32() % maxSliceSize
|
||||
slice := make([]byte, sliceLen)
|
||||
cutLen := randuint32() % 1024
|
||||
cutLen := randuint32() % maxSliceSize
|
||||
if cutLen < sliceLen {
|
||||
slice = slice[cutLen:]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user