diff options
author | Qiming Shi <qiming.shi@intel.com> | 2014-04-24 15:38:41 +0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-05-14 19:38:09 -0700 |
commit | 84d49ccd79088eb9a9f423c0a96e3905468cfe7d (patch) | |
tree | 30502e3c3f73000b2e49124cbd2da86d429036d8 /runtime/mem_map.cc | |
parent | 23d2b95b1d1c92898336a4ebf5c0281f79fb7581 (diff) | |
download | art-84d49ccd79088eb9a9f423c0a96e3905468cfe7d.tar.gz art-84d49ccd79088eb9a9f423c0a96e3905468cfe7d.tar.bz2 art-84d49ccd79088eb9a9f423c0a96e3905468cfe7d.zip |
ART: Resolve MAP_32BIT limitation in x86_64
Add checks that ensure when low4gb is set and an expected pointer
is given the requested memory fits into 4GB.
On x86_64, only use MAP_32BIT when there is no expected pointer.
This avoids a limitation in mmap (only 2GB visible).
Add tests to check behavior.
Original Author: Qiming Shi <qiming.shi@intel.com>
Change-Id: Ia2e3e0a46764ef70126b0c264f1fae681622d3cb
Diffstat (limited to 'runtime/mem_map.cc')
-rw-r--r-- | runtime/mem_map.cc | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index 1594338df3..98b0bbf125 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -128,6 +128,20 @@ MemMap* MemMap::MapAnonymous(const char* name, byte* expected, size_t byte_count // We need to store and potentially set an error number for pretty printing of errors int saved_errno = 0; +#ifdef __LP64__ + // When requesting low_4g memory and having an expectation, the requested range should fit into + // 4GB. + if (low_4gb && ( + // Start out of bounds. + (reinterpret_cast<uintptr_t>(expected) >> 32) != 0 || + // End out of bounds. For simplicity, this will fail for the last page of memory. + (reinterpret_cast<uintptr_t>(expected + page_aligned_byte_count) >> 32) != 0)) { + *error_msg = StringPrintf("The requested address space (%p, %p) cannot fit in low_4gb", + expected, expected + page_aligned_byte_count); + return nullptr; + } +#endif + // TODO: // A page allocator would be a useful abstraction here, as // 1) It is doubtful that MAP_32BIT on x86_64 is doing the right job for us @@ -192,7 +206,7 @@ MemMap* MemMap::MapAnonymous(const char* name, byte* expected, size_t byte_count #else #ifdef __x86_64__ - if (low_4gb) { + if (low_4gb && expected == nullptr) { flags |= MAP_32BIT; } #endif |