summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2024-11-19 12:21:38 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2024-11-20 10:57:23 +0000
commit723708ddb645439631dc8ccffa5eecd97aaaad57 (patch)
tree833c9b3ee18e04e0ddb52ab8f7edf4de9548bf00
parentdbe738240d1e5f390112c57e25854aef781ebbed (diff)
Revert "Always use an array in the DexCache for ArtField and ArtMethod."
This reverts commit 1f9c184392020cb5c4bdf453f4c8847ca389614b. Reason for revert: Memory regressions. Change-Id: I85357603c31aa7dbde92aea5958167ea8f0fd481
-rw-r--r--runtime/class_linker.cc16
-rw-r--r--runtime/mirror/dex_cache.cc32
-rw-r--r--runtime/mirror/dex_cache.h8
-rw-r--r--runtime/oat/image.cc4
4 files changed, 5 insertions, 55 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6d247a6d7a..eb9e9062cb 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -10994,24 +10994,8 @@ void ClassLinker::InsertDexFileInToClassLoader(ObjPtr<mirror::Object> dex_file,
}
}
-class ReclaimMemoryDexCacheVisitor : public DexCacheVisitor {
- public:
- ReclaimMemoryDexCacheVisitor() {}
-
- void Visit(ObjPtr<mirror::DexCache> dex_cache)
- REQUIRES_SHARED(Locks::dex_lock_, Locks::mutator_lock_) override {
- dex_cache->ReclaimMemory();
- }
-};
-
void ClassLinker::CleanupClassLoaders() {
Thread* const self = Thread::Current();
- // We clear dex cache arrays for every GC.
- {
- ReaderMutexLock mu(self, *Locks::dex_lock_);
- ReclaimMemoryDexCacheVisitor visitor;
- VisitDexCaches(&visitor);
- }
std::list<ClassLoaderData> to_delete;
// Do the delete outside the lock to avoid lock violation in jit code cache.
{
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index abbd23442b..b981f08d97 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -224,6 +224,7 @@ void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved)
SetResolvedTypesEntry(type_idx.index_, resolved.Ptr());
// TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
WriteBarrier::ForEveryFieldWrite(this);
+
if (this == resolved->GetDexCache()) {
// If we're updating the dex cache of the class, optimistically update the cache for methods and
// fields if the caches are full arrays.
@@ -254,36 +255,5 @@ void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved)
}
}
-static void ReclaimMemoryInternal(uint64_t address, size_t size) {
- if (address == 0u || size <= MemMap::GetPageSize()) {
- return;
- }
- uint8_t* const mem_begin = reinterpret_cast<uint8_t*>(address);
- uint8_t* const mem_end = reinterpret_cast<uint8_t*>(address + size);
- uint8_t* const page_begin = AlignUp(mem_begin, MemMap::GetPageSize());
- uint8_t* const page_end = AlignDown(mem_end, MemMap::GetPageSize());
- DCHECK_GE(page_end, page_begin);
- if (page_end == page_begin) {
- return;
- }
- bool res = madvise(page_begin, page_end - page_begin, MADV_DONTNEED);
- if (res == -1) {
- PLOG(WARNING) << "madvise failed";
- }
-}
-
-void DexCache::ReclaimMemory() {
- ReclaimMemoryInternal(resolved_fields_array_,
- NumResolvedFieldsArray() * sizeof(ArtField*));
- ReclaimMemoryInternal(resolved_method_types_array_,
- NumResolvedMethodTypesArray() * sizeof(GcRoot<mirror::MethodType>));
- ReclaimMemoryInternal(resolved_methods_array_,
- NumResolvedMethodsArray() * sizeof(ArtMethod*));
- ReclaimMemoryInternal(resolved_types_array_,
- NumResolvedTypesArray() * sizeof(GcRoot<mirror::Class>));
- ReclaimMemoryInternal(strings_array_,
- NumStringsArray() * sizeof(GcRoot<mirror::String>));
-}
-
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 69e610d9dc..c1d8cd8335 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -274,14 +274,12 @@ class MANAGED DexCache final : public Object {
"String dex cache size is not a power of 2.");
// Size of field dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
- // Set to the maximum number of field IDs to always use a direct array.
- static constexpr size_t kDexCacheFieldCacheSize = 65536;
+ static constexpr size_t kDexCacheFieldCacheSize = 1024;
static_assert(IsPowerOfTwo(kDexCacheFieldCacheSize),
"Field dex cache size is not a power of 2.");
// Size of method dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
- // Set to the maximum number of method IDs to always use a direct array.
- static constexpr size_t kDexCacheMethodCacheSize = 65536;
+ static constexpr size_t kDexCacheMethodCacheSize = 1024;
static_assert(IsPowerOfTwo(kDexCacheMethodCacheSize),
"Method dex cache size is not a power of 2.");
@@ -394,8 +392,6 @@ class MANAGED DexCache final : public Object {
return number_of_elements <= dex_cache_size;
}
- // Returns to the OS memory used for dex cache arrays.
- void ReclaimMemory() REQUIRES_SHARED(Locks::mutator_lock_);
// NOLINTBEGIN(bugprone-macro-parentheses)
#define DEFINE_ARRAY(name, array_kind, getter_setter, type, ids, alloc_kind) \
diff --git a/runtime/oat/image.cc b/runtime/oat/image.cc
index 77eb7df6e6..b62a4e0621 100644
--- a/runtime/oat/image.cc
+++ b/runtime/oat/image.cc
@@ -34,8 +34,8 @@
namespace art HIDDEN {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-// Last change: Add kAccDefault as an intrinsic bit.
-const uint8_t ImageHeader::kImageVersion[] = { '1', '1', '7', '\0' };
+// Revert dex cache change.
+const uint8_t ImageHeader::kImageVersion[] = { '1', '1', '8', '\0' };
ImageHeader::ImageHeader(uint32_t image_reservation_size,
uint32_t component_count,