diff --git a/builder/sizes_test.go b/builder/sizes_test.go index 16760218c..c1d44f443 100644 --- a/builder/sizes_test.go +++ b/builder/sizes_test.go @@ -42,9 +42,9 @@ func TestBinarySize(t *testing.T) { // This is a small number of very diverse targets that we want to test. tests := []sizeTest{ // microcontrollers - {"hifive1b", "examples/echo", 3884, 280, 0, 2268}, - {"microbit", "examples/serial", 2844, 360, 8, 2272}, - {"wioterminal", "examples/pininterrupt", 7349, 1491, 116, 6912}, + {"hifive1b", "examples/echo", 3896, 280, 0, 2268}, + {"microbit", "examples/serial", 2860, 360, 8, 2272}, + {"wioterminal", "examples/pininterrupt", 7361, 1491, 116, 6912}, // TODO: also check wasm. Right now this is difficult, because // wasm binaries are run through wasm-opt and therefore the diff --git a/src/runtime/gc_blocks.go b/src/runtime/gc_blocks.go index 85f499490..408656b25 100644 --- a/src/runtime/gc_blocks.go +++ b/src/runtime/gc_blocks.go @@ -311,22 +311,31 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { return unsafe.Pointer(&zeroSizedAlloc) } - if preciseHeap { - size += align(unsafe.Sizeof(layout)) - } - if interrupt.In() { runtimePanicAt(returnAddress(0), "heap alloc in interrupt") } + // Round the size up to a multiple of blocks. + rawSize := size + size += bytesPerBlock - 1 + if preciseHeap { + // Add space for the layout. + size += align(unsafe.Sizeof(layout)) + } + if size < rawSize { + // The size overflowed. + runtimePanicAt(returnAddress(0), "out of memory") + } + neededBlocks := size / bytesPerBlock + size = neededBlocks * bytesPerBlock + // Make sure there are no concurrent allocations. The heap is not currently // designed for concurrent alloc/GC. gcLock.Lock() - gcTotalAlloc += uint64(size) + // Update the total allocation counters. + gcTotalAlloc += uint64(rawSize) gcMallocs++ - - neededBlocks := (size + (bytesPerBlock - 1)) / bytesPerBlock gcTotalBlocks += uint64(neededBlocks) // Continue looping until a run of free blocks has been found that fits the