tinygo/testdata/gc.go
Ayke van Laethem 15c7d93ea9 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.
2020-01-27 19:01:55 +01:00

66 строки
1,6 КиБ
Go

package main
var xorshift32State uint32 = 1
func xorshift32(x uint32) uint32 {
// Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs"
x ^= x << 13
x ^= x >> 17
x ^= x << 5
return x
}
func randuint32() uint32 {
xorshift32State = xorshift32(xorshift32State)
return xorshift32State
}
func main() {
testNonPointerHeap()
}
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.
index := randuint32() % 4
// Check whether the contents of the previous allocation was correct.
rand := randSeeds[index]
for _, b := range scalarSlices[index] {
rand = xorshift32(rand)
if b != byte(rand) {
panic("memory was overwritten!")
}
}
// Allocate a randomly-sized slice, randomly sliced to be smaller.
sliceLen := randuint32() % maxSliceSize
slice := make([]byte, sliceLen)
cutLen := randuint32() % maxSliceSize
if cutLen < sliceLen {
slice = slice[cutLen:]
}
scalarSlices[index] = slice
// Fill the slice with a pattern that looks random but is easily
// calculated and verified.
rand = randuint32() + 1
randSeeds[index] = rand
for i := 0; i < len(slice); i++ {
rand = xorshift32(rand)
slice[i] = byte(rand)
}
}
println("ok")
}