Commit 9799a5a4 authored by Russ Cox's avatar Russ Cox

runtime: allow up to 128 GB of allocated memory

Incorporates code from CL 6828055.

Fixes #2142.

R=golang-dev, iant, devon.odell
CC=golang-dev
https://golang.org/cl/6826088
parent fc5e64cb
...@@ -323,32 +323,30 @@ runtime·mallocinit(void) ...@@ -323,32 +323,30 @@ runtime·mallocinit(void)
// enough to hold 4 bits per allocated word. // enough to hold 4 bits per allocated word.
if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) { if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
// On a 64-bit machine, allocate from a single contiguous reservation. // On a 64-bit machine, allocate from a single contiguous reservation.
// 16 GB should be big enough for now. // 128 GB (MaxMem) should be big enough for now.
// //
// The code will work with the reservation at any address, but ask // The code will work with the reservation at any address, but ask
// SysReserve to use 0x000000f800000000 if possible. // SysReserve to use 0x000000c000000000 if possible.
// Allocating a 16 GB region takes away 36 bits, and the amd64 // Allocating a 128 GB region takes away 37 bits, and the amd64
// doesn't let us choose the top 17 bits, so that leaves the 11 bits // doesn't let us choose the top 17 bits, so that leaves the 11 bits
// in the middle of 0x00f8 for us to choose. Choosing 0x00f8 means // in the middle of 0x00c0 for us to choose. Choosing 0x00c0 means
// that the valid memory addresses will begin 0x00f8, 0x00f9, 0x00fa, 0x00fb. // that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x0x00df.
// None of the bytes f8 f9 fa fb can appear in valid UTF-8, and // In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
// they are otherwise as far from ff (likely a common byte) as possible. // UTF-8 sequences, and they are otherwise as far away from
// Choosing 0x00 for the leading 6 bits was more arbitrary, but it // ff (likely a common byte) as possible. An earlier attempt to use 0x11f8
// is not a common ASCII code point either. Using 0x11f8 instead
// caused out of memory errors on OS X during thread allocations. // caused out of memory errors on OS X during thread allocations.
// These choices are both for debuggability and to reduce the // These choices are both for debuggability and to reduce the
// odds of the conservative garbage collector not collecting memory // odds of the conservative garbage collector not collecting memory
// because some non-pointer block of memory had a bit pattern // because some non-pointer block of memory had a bit pattern
// that matched a memory address. // that matched a memory address.
// //
// Actually we reserve 17 GB (because the bitmap ends up being 1 GB) // Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
// but it hardly matters: fc is not valid UTF-8 either, and we have to // but it hardly matters: e0 00 is not valid UTF-8 either.
// allocate 15 GB before we get that far.
// //
// If this fails we fall back to the 32 bit memory mechanism // If this fails we fall back to the 32 bit memory mechanism
arena_size = 16LL<<30; arena_size = MaxMem;
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*)(0x00c0ULL<<32), bitmap_size + arena_size);
} }
if (p == nil) { if (p == nil) {
// On a 32-bit machine, we can't typically get away // On a 32-bit machine, we can't typically get away
......
...@@ -114,12 +114,12 @@ enum ...@@ -114,12 +114,12 @@ enum
HeapAllocChunk = 1<<20, // Chunk size for heap growth HeapAllocChunk = 1<<20, // Chunk size for heap growth
// Number of bits in page to span calculations (4k pages). // Number of bits in page to span calculations (4k pages).
// On 64-bit, we limit the arena to 16G, so 22 bits suffices. // On 64-bit, we limit the arena to 128GB, or 37 bits.
// On 32-bit, we don't bother limiting anything: 20 bits for 4G. // On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
#ifdef _64BIT #ifdef _64BIT
MHeapMap_Bits = 22, MHeapMap_Bits = 37 - PageShift,
#else #else
MHeapMap_Bits = 20, MHeapMap_Bits = 32 - PageShift,
#endif #endif
// Max number of threads to run garbage collection. // Max number of threads to run garbage collection.
...@@ -133,7 +133,7 @@ enum ...@@ -133,7 +133,7 @@ enum
// This must be a #define instead of an enum because it // This must be a #define instead of an enum because it
// is so large. // is so large.
#ifdef _64BIT #ifdef _64BIT
#define MaxMem (16ULL<<30) /* 16 GB */ #define MaxMem (1ULL<<(MHeapMap_Bits+PageShift)) /* 128 GB */
#else #else
#define MaxMem ((uintptr)-1) #define MaxMem ((uintptr)-1)
#endif #endif
......
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