summaryrefslogtreecommitdiffstats
path: root/profman
diff options
context:
space:
mode:
authorCalin Juravle <calin@google.com>2018-12-11 13:38:35 -0800
committerCalin Juravle <calin@google.com>2018-12-20 05:11:02 -0800
commit3ee9cfd97cb3c7d6f8f47a166d2a001e12cc63ce (patch)
tree4a4d7c05d235c84c697bf8d586176d6a8095e022 /profman
parentc61b8c64ed2f3bd2e29f5bfa848e5b131d1c0f1e (diff)
downloadart-3ee9cfd97cb3c7d6f8f47a166d2a001e12cc63ce.tar.gz
art-3ee9cfd97cb3c7d6f8f47a166d2a001e12cc63ce.tar.bz2
art-3ee9cfd97cb3c7d6f8f47a166d2a001e12cc63ce.zip
Add support for aggregation counters in the profile
The profile can be configured to keep track of aggregation counters for methods and classes. On device, this is particular useful for the boot image profile. When aggregating multiple profiles into one and keep track of counters we can tell: 1. how many times we aggregated a method or a class. This tells us how popular is a particular method or class amongst the apps. 2. how many times we aggregated the profile. This tells how many apps contributed to the profile (on a single device). NOTE: This expands the memory footprint and makes the aggregation slower. As such it is disabled by default and not intended to use for the regular profiling path of apps in prod. Test: profile_compilation_info_test, profile_assistant_test Bug: 112617266 Change-Id: I731abf31f65b12bf405c77fb7803bb0bda3b9908
Diffstat (limited to 'profman')
-rw-r--r--profman/profile_assistant.cc21
-rw-r--r--profman/profile_assistant.h9
-rw-r--r--profman/profile_assistant_test.cc55
-rw-r--r--profman/profman.cc15
4 files changed, 88 insertions, 12 deletions
diff --git a/profman/profile_assistant.cc b/profman/profile_assistant.cc
index 4dc5262608..b65bb43cc3 100644
--- a/profman/profile_assistant.cc
+++ b/profman/profile_assistant.cc
@@ -32,7 +32,8 @@ static constexpr const uint32_t kMinNewClassesPercentChangeForCompilation = 2;
ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfilesInternal(
const std::vector<ScopedFlock>& profile_files,
const ScopedFlock& reference_profile_file,
- const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn) {
+ const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn,
+ bool store_aggregation_counters) {
DCHECK(!profile_files.empty());
ProfileCompilationInfo info;
@@ -42,6 +43,12 @@ ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfilesInternal(
return kErrorBadProfiles;
}
+ // If we need to store aggregation counters (e.g. for the boot image profile),
+ // prepare the reference profile now.
+ if (store_aggregation_counters) {
+ info.PrepareForAggregationCounters();
+ }
+
// 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();
@@ -124,7 +131,8 @@ class ScopedFlockList {
ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfiles(
const std::vector<int>& profile_files_fd,
int reference_profile_file_fd,
- const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn) {
+ const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn,
+ bool store_aggregation_counters) {
DCHECK_GE(reference_profile_file_fd, 0);
std::string error;
@@ -147,13 +155,15 @@ ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfiles(
return ProcessProfilesInternal(profile_files.Get(),
reference_profile_file,
- filter_fn);
+ filter_fn,
+ store_aggregation_counters);
}
ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfiles(
const std::vector<std::string>& profile_files,
const std::string& reference_profile_file,
- const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn) {
+ const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn,
+ bool store_aggregation_counters) {
std::string error;
ScopedFlockList profile_files_list(profile_files.size());
@@ -171,7 +181,8 @@ ProfileAssistant::ProcessingResult ProfileAssistant::ProcessProfiles(
return ProcessProfilesInternal(profile_files_list.Get(),
locked_reference_profile_file,
- filter_fn);
+ filter_fn,
+ store_aggregation_counters);
}
} // namespace art
diff --git a/profman/profile_assistant.h b/profman/profile_assistant.h
index c1d6f8e7a9..45d4e3817a 100644
--- a/profman/profile_assistant.h
+++ b/profman/profile_assistant.h
@@ -55,19 +55,22 @@ class ProfileAssistant {
const std::vector<std::string>& profile_files,
const std::string& reference_profile_file,
const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn
- = ProfileCompilationInfo::ProfileFilterFnAcceptAll);
+ = ProfileCompilationInfo::ProfileFilterFnAcceptAll,
+ bool store_aggregation_counters = false);
static ProcessingResult ProcessProfiles(
const std::vector<int>& profile_files_fd_,
int reference_profile_file_fd,
const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn
- = ProfileCompilationInfo::ProfileFilterFnAcceptAll);
+ = ProfileCompilationInfo::ProfileFilterFnAcceptAll,
+ bool store_aggregation_counters = false);
private:
static ProcessingResult ProcessProfilesInternal(
const std::vector<ScopedFlock>& profile_files,
const ScopedFlock& reference_profile_file,
- const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn);
+ const ProfileCompilationInfo::ProfileLoadFilterFn& filter_fn,
+ bool store_aggregation_counters);
DISALLOW_COPY_AND_ASSIGN(ProfileAssistant);
};
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index e9d3290faa..e9061515ad 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -102,7 +102,7 @@ class ProfileAssistantTest : public CommonRuntimeTest {
}
}
for (uint16_t i = 0; i < number_of_classes; i++) {
- ASSERT_TRUE(info->AddClassIndex(dex_location1,
+ ASSERT_TRUE(info->AddClassIndex(ProfileCompilationInfo::GetProfileDexFileKey(dex_location1),
dex_location_checksum1,
dex::TypeIndex(i),
number_of_methods1));
@@ -1300,4 +1300,57 @@ TEST_F(ProfileAssistantTest, CopyAndUpdateProfileKey) {
}
}
+TEST_F(ProfileAssistantTest, MergeProfilesWithCounters) {
+ ScratchFile profile1;
+ ScratchFile profile2;
+ ScratchFile reference_profile;
+
+ // The new profile info will contain methods with indices 0-100.
+ const uint16_t kNumberOfMethodsToEnableCompilation = 100;
+ const uint16_t kNumberOfClasses = 50;
+
+ std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ProfileTestMultiDex");
+ const DexFile& d1 = *dex_files[0];
+ const DexFile& d2 = *dex_files[1];
+ ProfileCompilationInfo info1;
+ SetupProfile(
+ d1.GetLocation(), d1.GetLocationChecksum(),
+ d2.GetLocation(), d2.GetLocationChecksum(),
+ kNumberOfMethodsToEnableCompilation, kNumberOfClasses, profile1, &info1);
+ ProfileCompilationInfo info2;
+ SetupProfile(
+ d1.GetLocation(), d1.GetLocationChecksum(),
+ d2.GetLocation(), d2.GetLocationChecksum(),
+ kNumberOfMethodsToEnableCompilation, kNumberOfClasses, profile2, &info2);
+
+ std::string profman_cmd = GetProfmanCmd();
+ std::vector<std::string> argv_str;
+ argv_str.push_back(profman_cmd);
+ argv_str.push_back("--profile-file-fd=" + std::to_string(profile1.GetFd()));
+ argv_str.push_back("--profile-file-fd=" + std::to_string(profile2.GetFd()));
+ argv_str.push_back("--reference-profile-file-fd=" + std::to_string(reference_profile.GetFd()));
+ argv_str.push_back("--store-aggregation-counters");
+ std::string error;
+
+ EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0) << error;
+
+ // Verify that we can load the result and that the counters are in place.
+
+ ProfileCompilationInfo result;
+ result.PrepareForAggregationCounters();
+ ASSERT_TRUE(reference_profile.GetFile()->ResetOffset());
+ ASSERT_TRUE(result.Load(reference_profile.GetFd()));
+
+ ASSERT_TRUE(result.StoresAggregationCounters());
+ ASSERT_EQ(2, result.GetAggregationCounter());
+
+ for (uint16_t i = 0; i < kNumberOfMethodsToEnableCompilation; i++) {
+ ASSERT_EQ(1, result.GetMethodAggregationCounter(MethodReference(&d1, i)));
+ ASSERT_EQ(1, result.GetMethodAggregationCounter(MethodReference(&d2, i)));
+ }
+ for (uint16_t i = 0; i < kNumberOfClasses; i++) {
+ ASSERT_EQ(1, result.GetClassAggregationCounter(TypeReference(&d1, dex::TypeIndex(i))));
+ }
+}
+
} // namespace art
diff --git a/profman/profman.cc b/profman/profman.cc
index 2935a05b48..a0c387db88 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -157,6 +157,9 @@ NO_RETURN static void Usage(const char *fmt, ...) {
UsageError(" the file passed with --profile-fd(file) to the profile passed with");
UsageError(" --reference-profile-fd(file) and update at the same time the profile-key");
UsageError(" of entries corresponding to the apks passed with --apk(-fd).");
+ UsageError(" --store-aggregation-counters: if present, profman will compute and store");
+ UsageError(" the aggregation counters of classes and methods in the output profile.");
+ UsageError(" In this case the profile will have a different version.");
UsageError("");
exit(EXIT_FAILURE);
@@ -200,7 +203,8 @@ class ProfMan final {
test_profile_class_percentage_(kDefaultTestProfileClassPercentage),
test_profile_seed_(NanoTime()),
start_ns_(NanoTime()),
- copy_and_update_profile_key_(false) {}
+ copy_and_update_profile_key_(false),
+ store_aggregation_counters_(false) {}
~ProfMan() {
LogCompletionTime();
@@ -287,6 +291,8 @@ class ProfMan final {
ParseUintOption(option, "--generate-test-profile-seed", &test_profile_seed_, Usage);
} else if (option.starts_with("--copy-and-update-profile-key")) {
copy_and_update_profile_key_ = true;
+ } else if (option.starts_with("--store-aggregation-counters")) {
+ store_aggregation_counters_ = true;
} else {
Usage("Unknown argument '%s'", option.data());
}
@@ -363,12 +369,14 @@ class ProfMan final {
File file(reference_profile_file_fd_, false);
result = ProfileAssistant::ProcessProfiles(profile_files_fd_,
reference_profile_file_fd_,
- filter_fn);
+ filter_fn,
+ store_aggregation_counters_);
CloseAllFds(profile_files_fd_, "profile_files_fd_");
} else {
result = ProfileAssistant::ProcessProfiles(profile_files_,
reference_profile_file_,
- filter_fn);
+ filter_fn,
+ store_aggregation_counters_);
}
return result;
}
@@ -1279,6 +1287,7 @@ class ProfMan final {
uint32_t test_profile_seed_;
uint64_t start_ns_;
bool copy_and_update_profile_key_;
+ bool store_aggregation_counters_;
};
// See ProfileAssistant::ProcessingResult for return codes.