Fix profile filtered loading
The computation for the profile line size of wrong. We need to multiply
the number of classes by the sizeof(uint16_t).
Test: m test-art-host-gtest
Bug: 78596914
Change-Id: I2e84cb0afd70c3c600c72c74997cc3097838a5e0
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 7c21916..d27465d 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -1351,7 +1351,7 @@
if (!filter_fn(profile_line_headers[k].dex_location, profile_line_headers[k].checksum)) {
// We have to skip the line. Advanced the current pointer of the buffer.
size_t profile_line_size =
- profile_line_headers[k].class_set_size +
+ profile_line_headers[k].class_set_size * sizeof(uint16_t) +
profile_line_headers[k].method_region_size_bytes +
DexFileData::ComputeBitmapStorage(profile_line_headers[k].num_method_ids);
uncompressed_data.Advance(profile_line_size);
diff --git a/runtime/jit/profile_compilation_info_test.cc b/runtime/jit/profile_compilation_info_test.cc
index 4e3774e..0ebadc0 100644
--- a/runtime/jit/profile_compilation_info_test.cc
+++ b/runtime/jit/profile_compilation_info_test.cc
@@ -1160,7 +1160,7 @@
ProfileCompilationInfo loaded_info;
ASSERT_TRUE(profile.GetFile()->ResetOffset());
- // Filter out dex locations. Keep only dex_location1 and dex_location2.
+ // Filter out dex locations. Keep only dex_location1 and dex_location3.
ProfileCompilationInfo::ProfileLoadFilterFn filter_fn =
[](const std::string& dex_location, uint32_t checksum) -> bool {
return (dex_location == "dex_location1" && checksum == 1)
@@ -1303,4 +1303,40 @@
}
}
+// Regression test: we were failing to do a filtering loading when the filtered dex file
+// contained profiled classes.
+TEST_F(ProfileCompilationInfoTest, FilteredLoadingWithClasses) {
+ ScratchFile profile;
+
+ // Save a profile with 2 dex files containing just classes.
+ ProfileCompilationInfo saved_info;
+ uint16_t item_count = 1000;
+ for (uint16_t i = 0; i < item_count; i++) {
+ ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, dex::TypeIndex(i), &saved_info));
+ ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &saved_info));
+ }
+
+ ASSERT_TRUE(saved_info.Save(GetFd(profile)));
+ ASSERT_EQ(0, profile.GetFile()->Flush());
+
+
+ // Filter out dex locations: kepp only dex_location2.
+ ProfileCompilationInfo loaded_info;
+ ASSERT_TRUE(profile.GetFile()->ResetOffset());
+ ProfileCompilationInfo::ProfileLoadFilterFn filter_fn =
+ [](const std::string& dex_location, uint32_t checksum) -> bool {
+ return (dex_location == "dex_location2" && checksum == 2);
+ };
+ ASSERT_TRUE(loaded_info.Load(GetFd(profile), true, filter_fn));
+
+ // Compute the expectation.
+ ProfileCompilationInfo expected_info;
+ for (uint16_t i = 0; i < item_count; i++) {
+ ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &expected_info));
+ }
+
+ // Validate the expectation.
+ ASSERT_TRUE(loaded_info.Equals(expected_info));
+}
+
} // namespace art