Commit d37a8b73 authored by Paul Borman's avatar Paul Borman Committed by Russ Cox

runtime: drop to 32 bit malloc if 64 bit will not work

On 64 bit UML it is not possible to reserve memory at 0xF8<<32.
Detect when linux cannot use these high virtual memory addresses
and drop back to the 32 bit memory allocator.

R=rsc, cw
CC=golang-dev
https://golang.org/cl/5634050
parent 1127b229
...@@ -289,12 +289,13 @@ runtime·mallocinit(void) ...@@ -289,12 +289,13 @@ runtime·mallocinit(void)
// Actually we reserve 17 GB (because the bitmap ends up being 1 GB) // Actually we reserve 17 GB (because the bitmap ends up being 1 GB)
// but it hardly matters: fc is not valid UTF-8 either, and we have to // but it hardly matters: fc is not valid UTF-8 either, and we have to
// allocate 15 GB before we get that far. // allocate 15 GB before we get that far.
//
// If this fails we fall back to the 32 bit memory mechanism
arena_size = 16LL<<30; arena_size = 16LL<<30;
bitmap_size = arena_size / (sizeof(void*)*8/4); bitmap_size = arena_size / (sizeof(void*)*8/4);
p = runtime·SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size); p = runtime·SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size);
if(p == nil) }
runtime·throw("runtime: cannot reserve arena virtual address space"); if (p == nil) {
} else {
// On a 32-bit machine, we can't typically get away // On a 32-bit machine, we can't typically get away
// with a giant virtual address space reservation. // with a giant virtual address space reservation.
// Instead we map the memory information bitmap // Instead we map the memory information bitmap
...@@ -359,8 +360,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) ...@@ -359,8 +360,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
return p; return p;
} }
// On 64-bit, our reservation is all we have. // If using 64-bit, our reservation is all we have.
if(sizeof(void*) == 8) if(sizeof(void*) == 8 && (uintptr)h->bitmap >= 0xffffffffU)
return nil; return nil;
// On 32-bit, once the reservation is gone we can // On 32-bit, once the reservation is gone we can
......
...@@ -73,9 +73,18 @@ runtime·SysReserve(void *v, uintptr n) ...@@ -73,9 +73,18 @@ runtime·SysReserve(void *v, uintptr n)
// On 64-bit, people with ulimit -v set complain if we reserve too // On 64-bit, people with ulimit -v set complain if we reserve too
// much address space. Instead, assume that the reservation is okay // much address space. Instead, assume that the reservation is okay
// and check the assumption in SysMap. // if we can reserve at least 64K and check the assumption in SysMap.
if(sizeof(void*) == 8) // Only user-mode Linux (UML) rejects these requests.
if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
p = runtime·mmap(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
if (p != v) {
return nil;
}
runtime·munmap(p, 64<<10);
return v; return v;
}
p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
if((uintptr)p < 4096 || -(uintptr)p < 4096) { if((uintptr)p < 4096 || -(uintptr)p < 4096) {
...@@ -92,7 +101,7 @@ runtime·SysMap(void *v, uintptr n) ...@@ -92,7 +101,7 @@ runtime·SysMap(void *v, uintptr n)
mstats.sys += n; mstats.sys += n;
// On 64-bit, we don't actually have v reserved, so tread carefully. // On 64-bit, we don't actually have v reserved, so tread carefully.
if(sizeof(void*) == 8) { if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
if(p != v && addrspace_free(v, n)) { if(p != v && addrspace_free(v, n)) {
// On some systems, mmap ignores v without // On some systems, mmap ignores v without
......
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