Handle allocation failure in AddPreResolvedStringsArray
Might fail on 32 bits if the address space is fragmented.
Regression test is infeasible to add.
Bug: 134652205
Test: test-art-host
(cherry picked from commit 4bdafc488c19f0bd1f8cc711b7db1ea9c68e5cd3)
Merged-In: I8a254a27275be4e0ff39fdb72715771f4f77cf36
Change-Id: I8a254a27275be4e0ff39fdb72715771f4f77cf36
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 78f5dc5..8893d67 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -680,9 +680,10 @@
for (const DexFile* dex_file : dex_files) {
dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file));
+ bool added_preresolved_string_array = false;
if (only_startup_strings) {
// When resolving startup strings, create the preresolved strings array.
- dex_cache->AddPreResolvedStringsArray();
+ added_preresolved_string_array = dex_cache->AddPreResolvedStringsArray();
}
TimingLogger::ScopedTiming t("Resolve const-string Strings", timings);
@@ -709,7 +710,7 @@
if (profile_compilation_info != nullptr && !is_startup_clinit) {
ProfileCompilationInfo::MethodHotness hotness =
profile_compilation_info->GetMethodHotness(method.GetReference());
- if (only_startup_strings ? !hotness.IsStartup() : !hotness.IsInProfile()) {
+ if (added_preresolved_string_array ? !hotness.IsStartup() : !hotness.IsInProfile()) {
continue;
}
}
@@ -727,7 +728,7 @@
: inst->VRegB_31c());
ObjPtr<mirror::String> string = class_linker->ResolveString(string_index, dex_cache);
CHECK(string != nullptr) << "Could not allocate a string when forcing determinism";
- if (only_startup_strings) {
+ if (added_preresolved_string_array) {
dex_cache->GetPreResolvedStrings()[string_index.index_] =
GcRoot<mirror::String>(string);
}
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index 7e79ebe..f97f521 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -172,19 +172,25 @@
dex_file->NumCallSiteIds());
}
-void DexCache::AddPreResolvedStringsArray() {
+bool DexCache::AddPreResolvedStringsArray() {
DCHECK_EQ(NumPreResolvedStrings(), 0u);
Thread* const self = Thread::Current();
LinearAlloc* linear_alloc = Runtime::Current()->GetLinearAlloc();
const size_t num_strings = GetDexFile()->NumStringIds();
- SetField32<false>(NumPreResolvedStringsOffset(), num_strings);
GcRoot<mirror::String>* strings =
linear_alloc->AllocArray<GcRoot<mirror::String>>(self, num_strings);
+ if (strings == nullptr) {
+ // Failed to allocate pre-resolved string array (probably due to address fragmentation), bail.
+ return false;
+ }
+ SetField32<false>(NumPreResolvedStringsOffset(), num_strings);
+
CHECK(strings != nullptr);
SetPreResolvedStrings(strings);
for (size_t i = 0; i < GetDexFile()->NumStringIds(); ++i) {
CHECK(GetPreResolvedStrings()[i].Read() == nullptr);
}
+ return true;
}
void DexCache::Init(const DexFile* dex_file,
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index e399a8c..b41443e 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -473,7 +473,8 @@
uint32_t MethodSlotIndex(uint32_t method_idx) REQUIRES_SHARED(Locks::mutator_lock_);
uint32_t MethodTypeSlotIndex(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
- void AddPreResolvedStringsArray() REQUIRES_SHARED(Locks::mutator_lock_);
+ // Returns true if we succeeded in adding the pre-resolved string array.
+ bool AddPreResolvedStringsArray() REQUIRES_SHARED(Locks::mutator_lock_);
private:
void Init(const DexFile* dex_file,