diff options
author | Andreas Gampe <agampe@google.com> | 2014-03-21 11:44:43 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-03-21 11:47:17 -0700 |
commit | 7104cbf9c594563c6daae592b8f38f49a423d12e (patch) | |
tree | 71cd3aa726d7ad946f314e41e465b39cb6b8b8c0 /runtime/mem_map.cc | |
parent | faa93b3ab455492dad1a9d3fb630e3936d389c85 (diff) | |
download | art-7104cbf9c594563c6daae592b8f38f49a423d12e.tar.gz art-7104cbf9c594563c6daae592b8f38f49a423d12e.tar.bz2 art-7104cbf9c594563c6daae592b8f38f49a423d12e.zip |
Fix sign problem, implement low-mem mmap wraparound
A signed value comparison meant that on 64b systems comparisons
were false when pointers > 2GB were in use (as happens in long-running
tests). Fix this to be uint.
Implement a simple wrap-around in the MAP_32BIT emulation code.
Change-Id: I09870b4755f2dca676e42e701fbb6f6eb4bb95d0
Diffstat (limited to 'runtime/mem_map.cc')
-rw-r--r-- | runtime/mem_map.cc | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index 5647d939ae..0af25e740a 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -47,7 +47,10 @@ static std::ostream& operator<<( } #if defined(__LP64__) && !defined(__x86_64__) -uintptr_t MemMap::next_mem_pos_ = kPageSize * 2; // first page to check for low-mem extent +// Where to start with low memory allocation. +static constexpr uintptr_t LOW_MEM_START = kPageSize * 2; + +uintptr_t MemMap::next_mem_pos_ = LOW_MEM_START; // first page to check for low-mem extent #endif static bool CheckMapRequest(byte* expected_ptr, void* actual_ptr, size_t byte_count, @@ -133,7 +136,22 @@ MemMap* MemMap::MapAnonymous(const char* name, byte* expected, size_t byte_count if (low_4gb && expected == nullptr) { flags |= MAP_FIXED; + bool first_run = true; + for (uintptr_t ptr = next_mem_pos_; ptr < 4 * GB; ptr += kPageSize) { + if (4U * GB - ptr < page_aligned_byte_count) { + // Not enough memory until 4GB. + if (first_run) { + // Try another time from the bottom; + next_mem_pos_ = LOW_MEM_START; + first_run = false; + continue; + } else { + // Second try failed. + break; + } + } + uintptr_t tail_ptr; // Check pages are free. |