github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/testdata/gc.go (about) 1 package main 2 3 import "runtime" 4 5 var xorshift32State uint32 = 1 6 7 func xorshift32(x uint32) uint32 { 8 // Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" 9 x ^= x << 13 10 x ^= x >> 17 11 x ^= x << 5 12 return x 13 } 14 15 func randuint32() uint32 { 16 xorshift32State = xorshift32(xorshift32State) 17 return xorshift32State 18 } 19 20 func main() { 21 testNonPointerHeap() 22 testKeepAlive() 23 } 24 25 var scalarSlices [4][]byte 26 var randSeeds [4]uint32 27 28 func testNonPointerHeap() { 29 maxSliceSize := uint32(1024) 30 if ^uintptr(0) <= 0xffff { 31 // 16-bit and lower devices, such as AVR. 32 // Heap size is a real issue there, while it is still useful to run 33 // these tests. Therefore, lower the max slice size. 34 maxSliceSize = 64 35 } 36 // Allocate roughly 0.5MB of memory. 37 for i := 0; i < 1000; i++ { 38 // Pick a random index that the optimizer can't predict. 39 index := randuint32() % 4 40 41 // Check whether the contents of the previous allocation was correct. 42 rand := randSeeds[index] 43 for _, b := range scalarSlices[index] { 44 rand = xorshift32(rand) 45 if b != byte(rand) { 46 panic("memory was overwritten!") 47 } 48 } 49 50 // Allocate a randomly-sized slice, randomly sliced to be smaller. 51 sliceLen := randuint32() % maxSliceSize 52 slice := make([]byte, sliceLen) 53 cutLen := randuint32() % maxSliceSize 54 if cutLen < sliceLen { 55 slice = slice[cutLen:] 56 } 57 scalarSlices[index] = slice 58 59 // Fill the slice with a pattern that looks random but is easily 60 // calculated and verified. 61 rand = randuint32() + 1 62 randSeeds[index] = rand 63 for i := 0; i < len(slice); i++ { 64 rand = xorshift32(rand) 65 slice[i] = byte(rand) 66 } 67 } 68 println("ok") 69 } 70 71 func testKeepAlive() { 72 // There isn't much we can test, but at least we can test that 73 // runtime.KeepAlive compiles correctly. 74 var x int 75 runtime.KeepAlive(&x) 76 }