diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index af03f8018d..fbdd6bb021 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -371,6 +371,22 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) { byte *p; + if(n > h->arena_end - h->arena_used) { + // We are in 32-bit mode, maybe we didn't use all possible address space yet. + // Reserve some more space. + byte *new_end; + uintptr needed; + + needed = (uintptr)h->arena_used + n - (uintptr)h->arena_end; + // Round wanted arena size to a multiple of 256MB. + needed = (needed + (256<<20) - 1) & ~((256<<20)-1); + new_end = h->arena_end + needed; + if(new_end <= h->arena_start + MaxArena32) { + p = runtime·SysReserve(h->arena_end, new_end - h->arena_end); + if(p == h->arena_end) + h->arena_end = new_end; + } + } if(n <= h->arena_end - h->arena_used) { // Keep taking from our reservation. p = h->arena_used; @@ -392,7 +408,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) return nil; if(p < h->arena_start || p+n - h->arena_start >= MaxArena32) { - runtime·printf("runtime: memory allocated by OS not in usable range\n"); + runtime·printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n", + p, h->arena_start, h->arena_start+MaxArena32); runtime·SysFree(p, n); return nil; }