diff options
| -rw-r--r-- | libartbase/base/fuchsia_compat.h | 36 | ||||
| -rw-r--r-- | libartbase/base/mem_map.cc | 102 | ||||
| -rw-r--r-- | libartbase/base/mem_map.h | 7 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.cc | 10 |
4 files changed, 53 insertions, 102 deletions
diff --git a/libartbase/base/fuchsia_compat.h b/libartbase/base/fuchsia_compat.h deleted file mode 100644 index 018bac0528..0000000000 --- a/libartbase/base/fuchsia_compat.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_LIBARTBASE_BASE_FUCHSIA_COMPAT_H_ -#define ART_LIBARTBASE_BASE_FUCHSIA_COMPAT_H_ - -// stubs for features lacking in Fuchsia - -struct rlimit { - int rlim_cur; -}; - -#define RLIMIT_FSIZE (1) -#define RLIM_INFINITY (-1) -static int getrlimit(int resource, struct rlimit *rlim) { - LOG(FATAL) << "getrlimit not available for Fuchsia"; -} - -static int ashmem_create_region(const char *name, size_t size) { - LOG(FATAL) << "ashmem_create_region not available for Fuchsia"; -} - -#endif // ART_LIBARTBASE_BASE_FUCHSIA_COMPAT_H_ diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc index d9760bd574..a82da2d8c8 100644 --- a/libartbase/base/mem_map.cc +++ b/libartbase/base/mem_map.cc @@ -23,6 +23,10 @@ #include <sys/resource.h> #endif +#if defined(__linux__) +#include <sys/prctl.h> +#endif + #include <map> #include <memory> #include <sstream> @@ -30,12 +34,6 @@ #include "android-base/stringprintf.h" #include "android-base/unique_fd.h" -#if !defined(__Fuchsia__) -#include "cutils/ashmem.h" -#else -#include "fuchsia_compat.h" -#endif - #include "allocator.h" #include "bit_utils.h" #include "globals.h" @@ -61,6 +59,9 @@ using Maps = AllocationTrackingMultiMap<void*, MemMap*, kAllocatorTagMaps>; // All the non-empty MemMaps. Use a multimap as we do a reserve-and-divide (eg ElfMap::Load()). static Maps* gMaps GUARDED_BY(MemMap::GetMemMapsLock()) = nullptr; +// A map containing unique strings used for indentifying anonymous mappings +static std::map<std::string, int> debugStrMap GUARDED_BY(MemMap::GetMemMapsLock()); + // Retrieve iterator to a `gMaps` entry that is known to exist. Maps::iterator GetGMapsEntry(const MemMap& map) REQUIRES(MemMap::GetMemMapsLock()) { DCHECK(map.IsValid()); @@ -246,6 +247,33 @@ void* MemMap::TryMemMapLow4GB(void* ptr, } #endif +void MemMap::SetDebugName(void* map_ptr, const char* name, size_t size) { + // Debug naming is only used for Android target builds. For Linux targets, + // we'll still call prctl but it wont do anything till we upstream the prctl. + if (kIsTargetFuchsia || !kIsTargetBuild) { + return; + } + + // lock as std::map is not thread-safe + std::lock_guard<std::mutex> mu(*mem_maps_lock_); + + std::string debug_friendly_name("dalvik-"); + debug_friendly_name += name; + auto it = debugStrMap.find(debug_friendly_name); + + if (it == debugStrMap.end()) { + it = debugStrMap.insert(std::make_pair(std::move(debug_friendly_name), 1)).first; + } + + DCHECK(it != debugStrMap.end()); +#if defined(PR_SET_VMA) && defined(__linux__) + prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, size, it->first.c_str()); +#else + // Prevent variable unused compiler errors. + UNUSED(map_ptr, size); +#endif +} + MemMap MemMap::MapAnonymous(const char* name, uint8_t* addr, size_t byte_count, @@ -253,11 +281,10 @@ MemMap MemMap::MapAnonymous(const char* name, bool low_4gb, bool reuse, std::string* error_msg, - bool use_ashmem) { + bool use_debug_name) { #ifndef __LP64__ UNUSED(low_4gb); #endif - use_ashmem = use_ashmem && !kIsTargetLinux && !kIsTargetFuchsia; if (byte_count == 0) { *error_msg = "Empty MemMap requested."; return Invalid(); @@ -274,41 +301,8 @@ MemMap MemMap::MapAnonymous(const char* name, flags |= MAP_FIXED; } - if (use_ashmem) { - if (!kIsTargetBuild) { - // When not on Android (either host or assuming a linux target) ashmem is faked using - // files in /tmp. Ensure that such files won't fail due to ulimit restrictions. If they - // will then use a regular mmap. - struct rlimit rlimit_fsize; - CHECK_EQ(getrlimit(RLIMIT_FSIZE, &rlimit_fsize), 0); - use_ashmem = (rlimit_fsize.rlim_cur == RLIM_INFINITY) || - (page_aligned_byte_count < rlimit_fsize.rlim_cur); - } - } - unique_fd fd; - - if (use_ashmem) { - // android_os_Debug.cpp read_mapinfo assumes all ashmem regions associated with the VM are - // prefixed "dalvik-". - std::string debug_friendly_name("dalvik-"); - debug_friendly_name += name; - fd.reset(ashmem_create_region(debug_friendly_name.c_str(), page_aligned_byte_count)); - - if (fd.get() == -1) { - // 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; - } - } - // We need to store and potentially set an error number for pretty printing of errors int saved_errno = 0; @@ -341,6 +335,11 @@ MemMap MemMap::MapAnonymous(const char* name, if (!CheckMapRequest(addr, actual, page_aligned_byte_count, error_msg)) { return Invalid(); } + + if (use_debug_name) { + SetDebugName(actual, name, page_aligned_byte_count); + } + return MemMap(name, reinterpret_cast<uint8_t*>(actual), byte_count, @@ -639,8 +638,7 @@ MemMap MemMap::RemapAtEnd(uint8_t* new_end, const char* tail_name, int tail_prot, std::string* error_msg, - bool use_ashmem) { - use_ashmem = use_ashmem && !kIsTargetLinux && !kIsTargetFuchsia; + bool use_debug_name) { DCHECK_GE(new_end, Begin()); DCHECK_LE(new_end, End()); DCHECK_LE(begin_ + size_, reinterpret_cast<uint8_t*>(base_begin_) + base_size_); @@ -666,19 +664,6 @@ MemMap MemMap::RemapAtEnd(uint8_t* new_end, unique_fd fd; int flags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS; - if (use_ashmem) { - // android_os_Debug.cpp read_mapinfo assumes all ashmem regions associated with the VM are - // prefixed "dalvik-". - std::string debug_friendly_name("dalvik-"); - debug_friendly_name += tail_name; - fd.reset(ashmem_create_region(debug_friendly_name.c_str(), tail_base_size)); - flags = MAP_PRIVATE | MAP_FIXED; - if (fd.get() == -1) { - *error_msg = StringPrintf("ashmem_create_region failed for '%s': %s", - tail_name, strerror(errno)); - return Invalid(); - } - } MEMORY_TOOL_MAKE_UNDEFINED(tail_base_begin, tail_base_size); // Note: Do not explicitly unmap the tail region, mmap() with MAP_FIXED automatically @@ -703,6 +688,11 @@ MemMap MemMap::RemapAtEnd(uint8_t* new_end, auto it = GetGMapsEntry(*this); gMaps->erase(it); } + + if (use_debug_name) { + SetDebugName(actual, tail_name, tail_base_size); + } + size_ = new_size; base_size_ = new_base_size; // Return the new mapping. diff --git a/libartbase/base/mem_map.h b/libartbase/base/mem_map.h index cd7d502796..f5fead0ed2 100644 --- a/libartbase/base/mem_map.h +++ b/libartbase/base/mem_map.h @@ -114,6 +114,9 @@ class MemMap { // of the source mmap is returned to the caller. bool ReplaceWith(/*in-out*/MemMap* source, /*out*/std::string* error); + // Set a debug friendly name for a map. It will be prefixed with "dalvik-". + static void SetDebugName(void* map_ptr, const char* name, size_t size); + // Request an anonymous region of length 'byte_count' and a requested base address. // Use null as the requested base address if you don't care. // "reuse" allows re-mapping an address range from an existing mapping. @@ -130,7 +133,7 @@ class MemMap { bool low_4gb, bool reuse, std::string* error_msg, - bool use_ashmem = true); + bool use_debug_name = true); static MemMap MapAnonymous(const char* name, uint8_t* addr, size_t byte_count, @@ -239,7 +242,7 @@ class MemMap { const char* tail_name, int tail_prot, std::string* error_msg, - bool use_ashmem = true); + bool use_debug_name = true); static bool CheckNoGaps(MemMap& begin_map, MemMap& end_map) REQUIRES(!MemMap::mem_maps_lock_); diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 33adc18673..b743b40330 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -168,11 +168,6 @@ JitCodeCache* JitCodeCache::Create(size_t initial_capacity, ScopedTrace trace(__PRETTY_FUNCTION__); CHECK_GE(max_capacity, initial_capacity); - // Generating debug information is for using the Linux perf tool on - // host which does not work with ashmem. - // Also, targets linux and fuchsia do not support ashmem. - bool use_ashmem = !generate_debug_info && !kIsTargetLinux && !kIsTargetFuchsia; - // With 'perf', we want a 1-1 mapping between an address and a method. // We aren't able to keep method pointers live during the instrumentation method entry trampoline // so we will just disable jit-gc if we are doing that. @@ -212,8 +207,7 @@ JitCodeCache* JitCodeCache::Create(size_t initial_capacity, kProtData, /* low_4gb */ true, /* reuse */ false, - &error_str, - use_ashmem); + &error_str); if (!data_map.IsValid()) { std::ostringstream oss; oss << "Failed to create read write cache: " << error_str << " size=" << max_capacity; @@ -233,7 +227,7 @@ JitCodeCache* JitCodeCache::Create(size_t initial_capacity, uint8_t* divider = data_map.Begin() + data_size; MemMap code_map = data_map.RemapAtEnd( - divider, "jit-code-cache", memmap_flags_prot_code | PROT_WRITE, &error_str, use_ashmem); + divider, "jit-code-cache", memmap_flags_prot_code | PROT_WRITE, &error_str); if (!code_map.IsValid()) { std::ostringstream oss; oss << "Failed to create read write execute cache: " << error_str << " size=" << max_capacity; |