diff options
Diffstat (limited to 'runtime/mem_map.cc')
| -rw-r--r-- | runtime/mem_map.cc | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index bb07fcbf37..1ec59b3cc7 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -318,11 +318,18 @@ MemMap* MemMap::MapAnonymous(const char* name, debug_friendly_name += name; fd.Reset(ashmem_create_region(debug_friendly_name.c_str(), page_aligned_byte_count), /* check_usage */ false); + if (fd.Fd() == -1) { - *error_msg = StringPrintf("ashmem_create_region failed for '%s': %s", name, strerror(errno)); - return nullptr; + // We failed to create the ashmem region. Print a warning, but continue + // anyway by creating a true anonymous mmap with an fd of -1. It is + // better to use an unlabelled anonymous map than to fail to create a + // map at all. + PLOG(WARNING) << "ashmem_create_region failed for '" << name << "'"; + } else { + // We succeeded in creating the ashmem region. Use the created ashmem + // region as backing for the mmap. + flags &= ~MAP_ANONYMOUS; } - flags &= ~MAP_ANONYMOUS; } // We need to store and potentially set an error number for pretty printing of errors @@ -354,7 +361,6 @@ MemMap* MemMap::MapAnonymous(const char* name, } return nullptr; } - std::ostringstream check_map_request_error_msg; if (!CheckMapRequest(expected_ptr, actual, page_aligned_byte_count, error_msg)) { return nullptr; } @@ -441,7 +447,6 @@ MemMap* MemMap::MapFileAtAddress(uint8_t* expected_ptr, } return nullptr; } - std::ostringstream check_map_request_error_msg; if (!CheckMapRequest(expected_ptr, actual, page_aligned_byte_count, error_msg)) { return nullptr; } @@ -918,4 +923,23 @@ void MemMap::TryReadable() { } } +void ZeroAndReleasePages(void* address, size_t length) { + uint8_t* const mem_begin = reinterpret_cast<uint8_t*>(address); + uint8_t* const mem_end = mem_begin + length; + uint8_t* const page_begin = AlignUp(mem_begin, kPageSize); + uint8_t* const page_end = AlignDown(mem_end, kPageSize); + if (!kMadviseZeroes || page_begin >= page_end) { + // No possible area to madvise. + std::fill(mem_begin, mem_end, 0); + } else { + // Spans one or more pages. + DCHECK_LE(mem_begin, page_begin); + DCHECK_LE(page_begin, page_end); + DCHECK_LE(page_end, mem_end); + std::fill(mem_begin, page_begin, 0); + CHECK_NE(madvise(page_begin, page_end - page_begin, MADV_DONTNEED), -1) << "madvise failed"; + std::fill(page_end, mem_end, 0); + } +} + } // namespace art |