diff options
author | 2023-03-06 14:14:23 +0000 | |
---|---|---|
committer | 2023-03-08 10:22:09 +0000 | |
commit | 21ce03c070a14c3c5fd81bcd7e23fa06435f9ccb (patch) | |
tree | ca1f2dfd6887dc9224acfbe3ef90540e7f5ddd88 /runtime/class_linker.cc | |
parent | e6c839354e623ecb030d95e5333b5df84b7953dd (diff) |
Fix races related to dex caches in runtime app images.
- Make sure dex cache arrays are properly aligned.
- Handle dex cache arrays being concurrently cleared when loading an
image.
- Don't use memcpy but update entries one by one when generating the
image.
Test: test.py
Bug: 260557058
Change-Id: I5ef72a7363fe5e108f62d03caa399e5300cf7a55
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b00910fec8..8927c4337e 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1587,12 +1587,15 @@ static void VisitInternedStringReferences( if (obj_ptr->IsDexCache() && raw_member_offset >= sizeof(mirror::DexCache)) { // Special case for strings referenced from dex cache array. uint32_t offset = raw_member_offset - sizeof(mirror::DexCache); - ObjPtr<mirror::String> referred_string = - obj_ptr->AsDexCache()->GetStringsArray()->Get(offset); - DCHECK(referred_string != nullptr); - ObjPtr<mirror::String> visited = visitor(referred_string); - if (visited != referred_string) { - obj_ptr->AsDexCache()->GetStringsArray()->Set(offset, visited.Ptr()); + mirror::GcRootArray<mirror::String>* array = obj_ptr->AsDexCache()->GetStringsArray(); + // The array could be concurrently set to null. See `StartupCompletedTask`. + if (array != nullptr) { + ObjPtr<mirror::String> referred_string = array->Get(offset); + DCHECK(referred_string != nullptr); + ObjPtr<mirror::String> visited = visitor(referred_string); + if (visited != referred_string) { + obj_ptr->AsDexCache()->GetStringsArray()->Set(offset, visited.Ptr()); + } } } else { DCHECK_ALIGNED(raw_member_offset, 2); @@ -1705,6 +1708,14 @@ void AppImageLoadingHelper::Update( } }, space->Begin(), kRuntimePointerSize); } + + if (runtime->GetStartupCompleted()) { + // Free up dex cache arrays that we would only allocate at startup. + for (auto dex_cache : dex_caches.Iterate<mirror::DexCache>()) { + dex_cache->UnlinkStartupCaches(); + } + space->ReleaseMetadata(); + } } void AppImageLoadingHelper::HandleAppImageStrings(gc::space::ImageSpace* space) { |