]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: drop to 32 bit malloc if 64 bit will not work
authorPaul Borman <borman@google.com>
Wed, 8 Feb 2012 19:39:16 +0000 (14:39 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 8 Feb 2012 19:39:16 +0000 (14:39 -0500)
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

src/pkg/runtime/malloc.goc
src/pkg/runtime/mem_linux.c

index f1509cd9d91df496db9388d13cf236b5c4bd2910..4e6bbe1b0fe624229fc2eb4dc483ae5c06ddebb0 100644 (file)
@@ -289,12 +289,13 @@ runtime·mallocinit(void)
                // 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
                // allocate 15 GB before we get that far.
+               //
+               // If this fails we fall back to the 32 bit memory mechanism
                arena_size = 16LL<<30;
                bitmap_size = arena_size / (sizeof(void*)*8/4);
                p = runtime·SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size);
-               if(p == nil)
-                       runtime·throw("runtime: cannot reserve arena virtual address space");
-       } else {
+       }
+       if (p == nil) {
                // On a 32-bit machine, we can't typically get away
                // with a giant virtual address space reservation.
                // Instead we map the memory information bitmap
@@ -359,8 +360,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
                return p;
        }
        
-       // On 64-bit, our reservation is all we have.
-       if(sizeof(void*) == 8)
+       // If using 64-bit, our reservation is all we have.
+       if(sizeof(void*) == 8 && (uintptr)h->bitmap >= 0xffffffffU)
                return nil;
 
        // On 32-bit, once the reservation is gone we can
index fdf02c2cac8a0a8f8a3e72987577e0bc88f3a737..47287939ad9e0d4d17dcd1290cad3a4421189fc0 100644 (file)
@@ -73,9 +73,18 @@ runtime·SysReserve(void *v, uintptr n)
 
        // On 64-bit, people with ulimit -v set complain if we reserve too
        // much address space.  Instead, assume that the reservation is okay
-       // and check the assumption in SysMap.
-       if(sizeof(void*) == 8)
+       // if we can reserve at least 64K and check the assumption in SysMap.
+       // 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;
+       }
        
        p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
        if((uintptr)p < 4096 || -(uintptr)p < 4096) {
@@ -92,7 +101,7 @@ runtime·SysMap(void *v, uintptr n)
        mstats.sys += n;
 
        // 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);
                if(p != v && addrspace_free(v, n)) {
                        // On some systems, mmap ignores v without