summaryrefslogtreecommitdiff
path: root/libartbase/base/mem_map.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libartbase/base/mem_map.cc')
-rw-r--r--libartbase/base/mem_map.cc21
1 files changed, 14 insertions, 7 deletions
diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc
index 0ab47f2384..08d452b5ff 100644
--- a/libartbase/base/mem_map.cc
+++ b/libartbase/base/mem_map.cc
@@ -344,13 +344,20 @@ MemMap MemMap::MapAnonymous(const char* name,
// We need to store and potentially set an error number for pretty printing of errors
int saved_errno = 0;
- void* actual = MapInternal(addr,
- page_aligned_byte_count,
- prot,
- flags,
- fd.get(),
- 0,
- low_4gb);
+ void* actual = nullptr;
+
+ // New Ubuntu linux kerners seem to ignore the address hint, so make it a firm request.
+ // Whereas old kernels allocated at 'addr' if provided, newer kernels seem to ignore it.
+ // However, MAP_FIXED_NOREPLACE tells the kernel it must allocate at the address or fail.
+ // Do this only on host since android kernels still obey the hint without flag (for now).
+ if (!kIsTargetBuild && (flags & MAP_FIXED) == 0 && addr != nullptr) {
+ actual = MapInternal(
+ addr, page_aligned_byte_count, prot, flags | MAP_FIXED_NOREPLACE, fd.get(), 0, low_4gb);
+ // If the fixed-address allocation failed, fallback to the default path (random address).
+ }
+ if (actual == nullptr || actual == MAP_FAILED) {
+ actual = MapInternal(addr, page_aligned_byte_count, prot, flags, fd.get(), 0, low_4gb);
+ }
saved_errno = errno;
if (actual == MAP_FAILED) {