diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-02-21 03:24:03 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-02-21 03:24:03 +0000 |
commit | 91d6f071fbbd5bc53d43902bb2259788b121ebfa (patch) | |
tree | 0e13770b6a813bbeb58ab023ca5029957226f017 /libgo/runtime/malloc.goc | |
parent | cc73e54dc6f39bd07b18e8e01ce7577741f8d087 (diff) | |
download | gcc-91d6f071fbbd5bc53d43902bb2259788b121ebfa.zip gcc-91d6f071fbbd5bc53d43902bb2259788b121ebfa.tar.gz gcc-91d6f071fbbd5bc53d43902bb2259788b121ebfa.tar.bz2 |
runtime: Use a better heap location on arm64 systems.
Before this, the heap location used on a 64-bit system was not
available to user-space on arm64, so the "32-bit" strategy ended up
being used. So use somewhere that is available, and for bonus points
is far away from where the kernel allocates address space by default.
From-SVN: r207977
Diffstat (limited to 'libgo/runtime/malloc.goc')
-rw-r--r-- | libgo/runtime/malloc.goc | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index a06dd11..7120457 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -27,6 +27,31 @@ package runtime #define KindPtr GO_PTR #define KindNoPointers GO_NO_POINTERS +// GCCGO SPECIFIC CHANGE +// +// There is a long comment in runtime_mallocinit about where to put the heap +// on a 64-bit system. It makes assumptions that are not valid on linux/arm64 +// -- it assumes user space can choose the lower 47 bits of a pointer, but on +// linux/arm64 we can only choose the lower 39 bits. This means the heap is +// roughly a quarter of the available address space and we cannot choose a bit +// pattern that all pointers will have -- luckily the GC is mostly precise +// these days so this doesn't matter all that much. The kernel (as of 3.13) +// will allocate address space starting either down from 0x7fffffffff or up +// from 0x2000000000, so we put the heap roughly in the middle of these two +// addresses to minimize the chance that a non-heap allocation will get in the +// way of the heap. +// +// This all means that there isn't much point in trying 256 different +// locations for the heap on such systems. +#ifdef __aarch64__ +#define HeapBase(i) ((void*)(uintptr)(0x40ULL<<32)) +#define HeapBaseOptions 1 +#else +#define HeapBase(i) ((void*)(uintptr)(i<<40|0x00c0ULL<<32)) +#define HeapBaseOptions 0x80 +#endif +// END GCCGO SPECIFIC CHANGE + // Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K. MHeap runtime_mheap; @@ -423,9 +448,8 @@ runtime_mallocinit(void) bitmap_size = arena_size / (sizeof(void*)*8/4); spans_size = arena_size / PageSize * sizeof(runtime_mheap.spans[0]); spans_size = ROUND(spans_size, PageSize); - for(i = 0; i <= 0x7f; i++) { - p = (void*)(uintptr)(i<<40 | 0x00c0ULL<<32); - p = runtime_SysReserve(p, bitmap_size + spans_size + arena_size); + for(i = 0; i < HeapBaseOptions; i++) { + p = runtime_SysReserve(HeapBase(i), bitmap_size + spans_size + arena_size); if(p != nil) break; } |