Increase threshold for profile compilation

Threshold to trigger compilation based on profiles has been increase
to avoid re-compilation too frequenctly.
Now compilation will take place if methods/classes in the new profile exceeds
by maximum of the following:
- 2% methods/classes in the existing profile.
- 100 methods or 50 classes.

Context for above numbers:
I analyzed profiles on my local device. Average number of methods and classes
in the profiles were 8000 and 2500 respectively.

Also added tests for the same.

Bug: 66732454
Test: test-art-host-gtest-profile_assistant_test
Change-Id: I8a9034c543a53a1c7b2a18a91d560786391b7c6e
diff --git a/profman/profile_assistant.cc b/profman/profile_assistant.cc
index c238f0d..ff02b5d 100644
--- a/profman/profile_assistant.cc
+++ b/profman/profile_assistant.cc
@@ -23,8 +23,11 @@
 
 // Minimum number of new methods/classes that profiles
 // must contain to enable recompilation.
-static constexpr const uint32_t kMinNewMethodsForCompilation = 10;
-static constexpr const uint32_t kMinNewClassesForCompilation = 10;
+static constexpr const uint32_t kMinNewMethodsForCompilation = 100;
+static constexpr const uint32_t kMinNewMethodsPercentChangeForCompilation = 2;
+static constexpr const uint32_t kMinNewClassesForCompilation = 50;
+static constexpr const uint32_t kMinNewClassesPercentChangeForCompilation = 2;
+
 
 ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfilesInternal(
         const std::vector<ScopedFlock>& profile_files,
@@ -55,9 +58,16 @@
     }
   }
 
+  uint32_t min_change_in_methods_for_compilation = std::max(
+      (kMinNewMethodsPercentChangeForCompilation * number_of_methods) / 100,
+      kMinNewMethodsForCompilation);
+  uint32_t min_change_in_classes_for_compilation = std::max(
+      (kMinNewClassesPercentChangeForCompilation * number_of_classes) / 100,
+      kMinNewClassesForCompilation);
   // Check if there is enough new information added by the current profiles.
-  if (((info.GetNumberOfMethods() - number_of_methods) < kMinNewMethodsForCompilation) &&
-      ((info.GetNumberOfResolvedClasses() - number_of_classes) < kMinNewClassesForCompilation)) {
+  if (((info.GetNumberOfMethods() - number_of_methods) < min_change_in_methods_for_compilation) &&
+      ((info.GetNumberOfResolvedClasses() - number_of_classes)
+          < min_change_in_classes_for_compilation)) {
     return kSkipCompilation;
   }
 
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 8cbf8c3..2f38535 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -335,6 +335,22 @@
     ASSERT_EQ(expected_clases.size(), found);
   }
 
+  int CheckCompilationPercentChange(int methods_in_cur_profile, int classes_in_cur_profile,
+                                    int methods_in_ref_profile, int classes_in_ref_profile) {
+    ScratchFile profile;
+    ScratchFile reference_profile;
+
+    std::vector<int> profile_fds({ GetFd(profile)});
+    int reference_profile_fd = GetFd(reference_profile);
+
+    ProfileCompilationInfo info1;
+    SetupProfile("p1", 1, methods_in_cur_profile, classes_in_cur_profile, profile,  &info1);
+    ProfileCompilationInfo info2;
+    SetupProfile("p1", 1, methods_in_ref_profile, classes_in_ref_profile, reference_profile,
+        &info2);
+    return ProcessProfiles(profile_fds, reference_profile_fd);
+  }
+
   std::unique_ptr<ArenaAllocator> arena_;
 
   // Cache of inline caches generated during tests.
@@ -460,7 +476,7 @@
       GetFd(profile2)});
   int reference_profile_fd = GetFd(reference_profile);
 
-  const uint16_t kNumberOfMethodsToSkipCompilation = 1;
+  const uint16_t kNumberOfMethodsToSkipCompilation = 24;  // Threshold is 100.
   ProfileCompilationInfo info1;
   SetupProfile("p1", 1, kNumberOfMethodsToSkipCompilation, 0, profile1, &info1);
   ProfileCompilationInfo info2;
@@ -489,6 +505,50 @@
   CheckProfileInfo(profile2, info2);
 }
 
+TEST_F(ProfileAssistantTest, DoNotAdviseCompilationMethodPercentage) {
+  const uint16_t kNumberOfMethodsInRefProfile = 6000;
+  const uint16_t kNumberOfMethodsInCurProfile = 6110;  // Threshold is 2%.
+  // We should not advise compilation.
+  ASSERT_EQ(ProfileAssistant::kSkipCompilation,
+            CheckCompilationPercentChange(kNumberOfMethodsInCurProfile,
+                                          0,
+                                          kNumberOfMethodsInRefProfile,
+                                          0));
+}
+
+TEST_F(ProfileAssistantTest, ShouldAdviseCompilationMethodPercentage) {
+  const uint16_t kNumberOfMethodsInRefProfile = 6000;
+  const uint16_t kNumberOfMethodsInCurProfile = 6120;  // Threshold is 2%.
+  // We should advise compilation.
+  ASSERT_EQ(ProfileAssistant::kCompile,
+            CheckCompilationPercentChange(kNumberOfMethodsInCurProfile,
+                                          0,
+                                          kNumberOfMethodsInRefProfile,
+                                          0));
+}
+
+TEST_F(ProfileAssistantTest, DoNotdviseCompilationClassPercentage) {
+  const uint16_t kNumberOfClassesInRefProfile = 6000;
+  const uint16_t kNumberOfClassesInCurProfile = 6110;  // Threshold is 2%.
+  // We should not advise compilation.
+  ASSERT_EQ(ProfileAssistant::kSkipCompilation,
+            CheckCompilationPercentChange(0,
+                                          kNumberOfClassesInCurProfile,
+                                          0,
+                                          kNumberOfClassesInRefProfile));
+}
+
+TEST_F(ProfileAssistantTest, ShouldAdviseCompilationClassPercentage) {
+  const uint16_t kNumberOfClassesInRefProfile = 6000;
+  const uint16_t kNumberOfClassesInCurProfile = 6120;  // Threshold is 2%.
+  // We should advise compilation.
+  ASSERT_EQ(ProfileAssistant::kCompile,
+            CheckCompilationPercentChange(0,
+                                          kNumberOfClassesInCurProfile,
+                                          0,
+                                          kNumberOfClassesInRefProfile));
+}
+
 TEST_F(ProfileAssistantTest, FailProcessingBecauseOfProfiles) {
   ScratchFile profile1;
   ScratchFile profile2;