summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc23
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) {