Commit 3dcedb62 authored by Rémy Oudompheng's avatar Rémy Oudompheng Committed by Russ Cox

runtime: try extending arena size in 32-bit allocator.

If it didn't reach the limit, we can try extending the arena
before resorting to random memory mappings and praying for the
kernel to be kind.

Fixes #3173.

R=rsc, rsc
CC=golang-dev
https://golang.org/cl/5725045
parent b514f0b9
...@@ -371,6 +371,22 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) ...@@ -371,6 +371,22 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
{ {
byte *p; 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) { if(n <= h->arena_end - h->arena_used) {
// Keep taking from our reservation. // Keep taking from our reservation.
p = h->arena_used; p = h->arena_used;
...@@ -392,7 +408,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) ...@@ -392,7 +408,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
return nil; return nil;
if(p < h->arena_start || p+n - h->arena_start >= MaxArena32) { 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); runtime·SysFree(p, n);
return nil; return nil;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment