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.
Этот коммит содержится в:
Ayke van Laethem 2020-01-25 23:50:57 +01:00 коммит произвёл Ron Evans
родитель 6e26728391
коммит 15c7d93ea9
6 изменённых файлов: 24 добавлений и 4 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

11
testdata/gc.go предоставленный
Просмотреть файл

@ -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:]
}