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

(cherry picked from commit f0cf86fd4085c725b667058b416e0f8a6a7dfcc2)

Change-Id: Id6064768e70ced44ce5bf1993a4446aae006b1d3
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 1bbce4f..a473f3f 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -1352,7 +1352,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