summaryrefslogtreecommitdiffstats
path: root/profman
diff options
context:
space:
mode:
authorCalin Juravle <calin@google.com>2016-03-29 20:33:33 +0100
committerCalin Juravle <calin@google.com>2016-04-25 13:21:49 +0100
commitc824b51331bdd72c1c45ca4e45a0b025d30a09c9 (patch)
tree5077addabcb908ac33a978a2a107d2f4d2253605 /profman
parent900d7d44633675621e665536742a7a2b40dcc7f0 (diff)
downloadandroid_art-c824b51331bdd72c1c45ca4e45a0b025d30a09c9.tar.gz
android_art-c824b51331bdd72c1c45ca4e45a0b025d30a09c9.tar.bz2
android_art-c824b51331bdd72c1c45ca4e45a0b025d30a09c9.zip
Take into account the change in classes when analysing profiles
Bug: 27894914 (cherry picked from commit e02348caea14a203a2ed7a6c859e1515c6c6778f) Change-Id: I02834424803a9368374f32507e0b637fbfa5d7a6
Diffstat (limited to 'profman')
-rw-r--r--profman/profile_assistant.cc41
-rw-r--r--profman/profile_assistant_test.cc56
2 files changed, 64 insertions, 33 deletions
diff --git a/profman/profile_assistant.cc b/profman/profile_assistant.cc
index ac1865785e..a25460e427 100644
--- a/profman/profile_assistant.cc
+++ b/profman/profile_assistant.cc
@@ -21,44 +21,41 @@
namespace art {
-// Minimum number of new methods that profiles must contain to enable recompilation.
+// 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;
ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfilesInternal(
const std::vector<ScopedFlock>& profile_files,
const ScopedFlock& reference_profile_file) {
DCHECK(!profile_files.empty());
- std::vector<ProfileCompilationInfo> new_info(profile_files.size());
- bool should_compile = false;
- // Read the main profile files.
- for (size_t i = 0; i < new_info.size(); i++) {
- if (!new_info[i].Load(profile_files[i].GetFile()->Fd())) {
- LOG(WARNING) << "Could not load profile file at index " << i;
- return kErrorBadProfiles;
- }
- // Do we have enough new profiled methods that will make the compilation worthwhile?
- should_compile |= (new_info[i].GetNumberOfMethods() > kMinNewMethodsForCompilation);
- }
-
- if (!should_compile) {
- return kSkipCompilation;
- }
-
- // Merge information.
ProfileCompilationInfo info;
+ // Load the reference profile.
if (!info.Load(reference_profile_file.GetFile()->Fd())) {
LOG(WARNING) << "Could not load reference profile file";
return kErrorBadProfiles;
}
- for (size_t i = 0; i < new_info.size(); i++) {
- // Merge all data into a single object.
- if (!info.MergeWith(new_info[i])) {
- LOG(WARNING) << "Could not merge profile data at index " << i;
+ // Store the current state of the reference profile before merging with the current profiles.
+ uint32_t number_of_methods = info.GetNumberOfMethods();
+ uint32_t number_of_classes = info.GetNumberOfResolvedClasses();
+
+ // Merge all current profiles.
+ for (size_t i = 0; i < profile_files.size(); i++) {
+ if (!info.Load(profile_files[i].GetFile()->Fd())) {
+ LOG(WARNING) << "Could not load profile file at index " << i;
return kErrorBadProfiles;
}
}
+
+ // 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)) {
+ return kSkipCompilation;
+ }
+
// We were successful in merging all profile information. Update the reference profile.
if (!reference_profile_file.GetFile()->ClearContent()) {
PLOG(WARNING) << "Could not clear reference profile file";
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 157ffc4c71..462c39735e 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -29,6 +29,7 @@ class ProfileAssistantTest : public CommonRuntimeTest {
void SetupProfile(const std::string& id,
uint32_t checksum,
uint16_t number_of_methods,
+ uint16_t number_of_classes,
const ScratchFile& profile,
ProfileCompilationInfo* info,
uint16_t start_method_index = 0) {
@@ -40,6 +41,10 @@ class ProfileAssistantTest : public CommonRuntimeTest {
ASSERT_TRUE(info->AddMethodIndex(dex_location1, dex_location_checksum1, i));
ASSERT_TRUE(info->AddMethodIndex(dex_location2, dex_location_checksum2, i));
}
+ for (uint16_t i = 0; i < number_of_classes; i++) {
+ ASSERT_TRUE(info->AddClassIndex(dex_location1, dex_location_checksum1, i));
+ }
+
ASSERT_TRUE(info->Save(GetFd(profile)));
ASSERT_EQ(0, profile.GetFile()->Flush());
ASSERT_TRUE(profile.GetFile()->ResetOffset());
@@ -89,9 +94,9 @@ TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
const uint16_t kNumberOfMethodsToEnableCompilation = 100;
ProfileCompilationInfo info1;
- SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, profile1, &info1);
+ SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, 0, profile1, &info1);
ProfileCompilationInfo info2;
- SetupProfile("p2", 2, kNumberOfMethodsToEnableCompilation, profile2, &info2);
+ SetupProfile("p2", 2, kNumberOfMethodsToEnableCompilation, 0, profile2, &info2);
// We should advise compilation.
ASSERT_EQ(ProfileAssistant::kCompile,
@@ -111,6 +116,35 @@ TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
CheckProfileInfo(profile2, info2);
}
+// TODO(calin): Add more tests for classes.
+TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferencesBecauseOfClasses) {
+ ScratchFile profile1;
+ ScratchFile reference_profile;
+
+ std::vector<int> profile_fds({
+ GetFd(profile1)});
+ int reference_profile_fd = GetFd(reference_profile);
+
+ const uint16_t kNumberOfClassesToEnableCompilation = 100;
+ ProfileCompilationInfo info1;
+ SetupProfile("p1", 1, 0, kNumberOfClassesToEnableCompilation, profile1, &info1);
+
+ // We should advise compilation.
+ ASSERT_EQ(ProfileAssistant::kCompile,
+ ProcessProfiles(profile_fds, reference_profile_fd));
+ // The resulting compilation info must be equal to the merge of the inputs.
+ ProfileCompilationInfo result;
+ ASSERT_TRUE(reference_profile.GetFile()->ResetOffset());
+ ASSERT_TRUE(result.Load(reference_profile_fd));
+
+ ProfileCompilationInfo expected;
+ ASSERT_TRUE(expected.MergeWith(info1));
+ ASSERT_TRUE(expected.Equals(result));
+
+ // The information from profiles must remain the same.
+ CheckProfileInfo(profile1, info1);
+}
+
TEST_F(ProfileAssistantTest, AdviseCompilationNonEmptyReferences) {
ScratchFile profile1;
ScratchFile profile2;
@@ -124,15 +158,15 @@ TEST_F(ProfileAssistantTest, AdviseCompilationNonEmptyReferences) {
// The new profile info will contain the methods with indices 0-100.
const uint16_t kNumberOfMethodsToEnableCompilation = 100;
ProfileCompilationInfo info1;
- SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, profile1, &info1);
+ SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, 0, profile1, &info1);
ProfileCompilationInfo info2;
- SetupProfile("p2", 2, kNumberOfMethodsToEnableCompilation, profile2, &info2);
+ SetupProfile("p2", 2, kNumberOfMethodsToEnableCompilation, 0, profile2, &info2);
// The reference profile info will contain the methods with indices 50-150.
const uint16_t kNumberOfMethodsAlreadyCompiled = 100;
ProfileCompilationInfo reference_info;
- SetupProfile("p1", 1, kNumberOfMethodsAlreadyCompiled, reference_profile,
+ SetupProfile("p1", 1, kNumberOfMethodsAlreadyCompiled, 0, reference_profile,
&reference_info, kNumberOfMethodsToEnableCompilation / 2);
// We should advise compilation.
@@ -167,9 +201,9 @@ TEST_F(ProfileAssistantTest, DoNotAdviseCompilation) {
const uint16_t kNumberOfMethodsToSkipCompilation = 1;
ProfileCompilationInfo info1;
- SetupProfile("p1", 1, kNumberOfMethodsToSkipCompilation, profile1, &info1);
+ SetupProfile("p1", 1, kNumberOfMethodsToSkipCompilation, 0, profile1, &info1);
ProfileCompilationInfo info2;
- SetupProfile("p2", 2, kNumberOfMethodsToSkipCompilation, profile2, &info2);
+ SetupProfile("p2", 2, kNumberOfMethodsToSkipCompilation, 0, profile2, &info2);
// We should not advise compilation.
ASSERT_EQ(ProfileAssistant::kSkipCompilation,
@@ -207,9 +241,9 @@ TEST_F(ProfileAssistantTest, FailProcessingBecauseOfProfiles) {
const uint16_t kNumberOfMethodsToEnableCompilation = 100;
// Assign different hashes for the same dex file. This will make merging of information to fail.
ProfileCompilationInfo info1;
- SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, profile1, &info1);
+ SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, 0, profile1, &info1);
ProfileCompilationInfo info2;
- SetupProfile("p1", 2, kNumberOfMethodsToEnableCompilation, profile2, &info2);
+ SetupProfile("p1", 2, kNumberOfMethodsToEnableCompilation, 0, profile2, &info2);
// We should fail processing.
ASSERT_EQ(ProfileAssistant::kErrorBadProfiles,
@@ -234,9 +268,9 @@ TEST_F(ProfileAssistantTest, FailProcessingBecauseOfReferenceProfiles) {
const uint16_t kNumberOfMethodsToEnableCompilation = 100;
// Assign different hashes for the same dex file. This will make merging of information to fail.
ProfileCompilationInfo info1;
- SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, profile1, &info1);
+ SetupProfile("p1", 1, kNumberOfMethodsToEnableCompilation, 0, profile1, &info1);
ProfileCompilationInfo reference_info;
- SetupProfile("p1", 2, kNumberOfMethodsToEnableCompilation, reference_profile, &reference_info);
+ SetupProfile("p1", 2, kNumberOfMethodsToEnableCompilation, 0, reference_profile, &reference_info);
// We should not advise compilation.
ASSERT_TRUE(profile1.GetFile()->ResetOffset());