Optimize FilterApkAssets by caching config
ResTable_config of every ResTable_type is read from device every time
AssetManager::RebuildFilterList is invoked. For large APKs (like
framework-res.apk), this causes a large number of page faults
when accessing the config from disk. The configs are also used in the
slow path of AssetManager::FindEntryInternal, which makes it even
slower. Instead cache the config on the TypeSpec of its ApkAsset.
Bug: 177247024
Test: libandroidfw_tests
Change-Id: I66d507c4eeb2399f7558f3d9dfc53c157129ada0
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index 6357411..9aa3634 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -65,10 +65,10 @@
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
- auto type = type_spec->types[0];
- ASSERT_TRUE(LoadedPackage::GetEntry(type, entry_index).has_value());
+ auto type = type_spec->type_entries[0];
+ ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}
TEST(LoadedArscTest, LoadSparseEntryApp) {
@@ -89,10 +89,10 @@
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
- auto type = type_spec->types[0];
- ASSERT_TRUE(LoadedPackage::GetEntry(type, entry_index).has_value());
+ auto type = type_spec->type_entries[0];
+ ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}
TEST(LoadedArscTest, LoadSharedLibrary) {
@@ -176,13 +176,13 @@
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
auto type_name16 = package->GetTypeStringPool()->stringAt(type_spec->type_spec->id - 1);
ASSERT_TRUE(type_name16.has_value());
EXPECT_THAT(util::Utf16ToUtf8(*type_name16), StrEq("string"));
- ASSERT_TRUE(LoadedPackage::GetEntry(type_spec->types[0], entry_index).has_value());
+ ASSERT_TRUE(LoadedPackage::GetEntry(type_spec->type_entries[0].type, entry_index).has_value());
}
// AAPT(2) generates resource tables with chunks in a certain order. The rule is that
@@ -217,11 +217,11 @@
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(0);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
type_spec = package->GetTypeSpecByTypeIndex(1);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
}
TEST(LoadedArscTest, LoadOverlayable) {
@@ -363,10 +363,10 @@
const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
ASSERT_THAT(type_spec, NotNull());
- ASSERT_THAT(type_spec->type_count, Ge(1u));
+ ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));
- auto type = type_spec->types[0];
- ASSERT_TRUE(LoadedPackage::GetEntry(type, entry_index).has_value());
+ auto type = type_spec->type_entries[0];
+ ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}
// structs with size fields (like Res_value, ResTable_entry) should be