Add new profile saver options: save without jit & profile AOT code
--Xps-save-without-jit-notifications
The hotness for system server code is increased in AOT-ed code. The flow
does not call into JIT and as such notifications are not triggered.
Instead of relying on the JIT system, make use of a simple back off
strategy to save the profile.
--Xps-profile-aot-code
Starts the profile saver even if the oat file is speed compiled.
Test: m test-art-host
boot a device with system server profiling enabled.
Bug: 73313191
Change-Id: I66ec422a76bc9244349da7a5d18a3df5bcc9ccb7
diff --git a/cmdline/cmdline_types.h b/cmdline/cmdline_types.h
index 5a25a6c..48da755 100644
--- a/cmdline/cmdline_types.h
+++ b/cmdline/cmdline_types.h
@@ -643,6 +643,16 @@
return Result::SuccessNoValue();
}
+ if (option == "profile-aot-code") {
+ existing.profile_aot_code_ = true;
+ return Result::SuccessNoValue();
+ }
+
+ if (option == "save-without-jit-notifications") {
+ existing.wait_for_jit_notifications_to_save_ = false;
+ return Result::SuccessNoValue();
+ }
+
// The rest of these options are always the wildcard from '-Xps-*'
std::string suffix = RemovePrefix(option);
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 6d27cfe..4b8b891 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -252,6 +252,13 @@
void SetSaveProfilingInfo(bool save_profiling_info) {
profile_saver_options_.SetEnabled(save_profiling_info);
}
+ void SetWaitForJitNotificationsToSaveProfile(bool value) {
+ profile_saver_options_.SetWaitForJitNotificationsToSave(value);
+ }
+ void SetProfileAOTCode(bool value) {
+ profile_saver_options_.SetProfileAOTCode(value);
+ }
+
void SetJitAtFirstUse() {
use_jit_compilation_ = true;
compile_threshold_ = 0;
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index 618fde8..efa8a4d 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -131,6 +131,11 @@
}
FetchAndCacheResolvedClassesAndMethods(/*startup*/ true);
+
+ // When we save without waiting for JIT notifications we use a simple
+ // exponential back off policy bounded by max_wait_without_jit.
+ uint32_t max_wait_without_jit = options_.GetMinSavePeriodMs() * 16;
+ uint64_t cur_wait_without_jit = options_.GetMinSavePeriodMs();
// Loop for the profiled methods.
while (!ShuttingDown(self)) {
uint64_t sleep_start = NanoTime();
@@ -138,7 +143,14 @@
uint64_t sleep_time = 0;
{
MutexLock mu(self, wait_lock_);
- period_condition_.Wait(self);
+ if (options_.GetWaitForJitNotificationsToSave()) {
+ period_condition_.Wait(self);
+ } else {
+ period_condition_.TimedWait(self, cur_wait_without_jit, 0);
+ if (cur_wait_without_jit < max_wait_without_jit) {
+ cur_wait_without_jit *= 2;
+ }
+ }
sleep_time = NanoTime() - sleep_start;
}
// Check if the thread was woken up for shutdown.
@@ -597,7 +609,13 @@
return nullptr;
}
-static bool ShouldProfileLocation(const std::string& location) {
+static bool ShouldProfileLocation(const std::string& location, bool profile_aot_code) {
+ if (profile_aot_code) {
+ // If we have to profile all the code, irrespective of its compilation state, return true
+ // right away.
+ return true;
+ }
+
OatFileManager& oat_manager = Runtime::Current()->GetOatFileManager();
const OatFile* oat_file = oat_manager.FindOpenedOatFileFromDexLocation(location);
if (oat_file == nullptr) {
@@ -629,7 +647,7 @@
std::vector<std::string> code_paths_to_profile;
for (const std::string& location : code_paths) {
- if (ShouldProfileLocation(location)) {
+ if (ShouldProfileLocation(location, options.GetProfileAOTCode())) {
code_paths_to_profile.push_back(location);
}
}
diff --git a/runtime/jit/profile_saver_options.h b/runtime/jit/profile_saver_options.h
index d1e14e2..18f7899 100644
--- a/runtime/jit/profile_saver_options.h
+++ b/runtime/jit/profile_saver_options.h
@@ -41,7 +41,9 @@
min_notification_before_wake_(kMinNotificationBeforeWake),
max_notification_before_wake_(kMaxNotificationBeforeWake),
profile_path_(""),
- profile_boot_class_path_(false) {}
+ profile_boot_class_path_(false),
+ profile_aot_code_(false),
+ wait_for_jit_notifications_to_save_(true) {}
ProfileSaverOptions(
bool enabled,
@@ -53,7 +55,9 @@
uint32_t min_notification_before_wake,
uint32_t max_notification_before_wake,
const std::string& profile_path,
- bool profile_boot_class_path)
+ bool profile_boot_class_path,
+ bool profile_aot_code = false,
+ bool wait_for_jit_notifications_to_save = true)
: enabled_(enabled),
min_save_period_ms_(min_save_period_ms),
save_resolved_classes_delay_ms_(save_resolved_classes_delay_ms),
@@ -63,7 +67,9 @@
min_notification_before_wake_(min_notification_before_wake),
max_notification_before_wake_(max_notification_before_wake),
profile_path_(profile_path),
- profile_boot_class_path_(profile_boot_class_path) {}
+ profile_boot_class_path_(profile_boot_class_path),
+ profile_aot_code_(profile_aot_code),
+ wait_for_jit_notifications_to_save_(wait_for_jit_notifications_to_save) {}
bool IsEnabled() const {
return enabled_;
@@ -103,6 +109,18 @@
bool GetProfileBootClassPath() const {
return profile_boot_class_path_;
}
+ bool GetProfileAOTCode() const {
+ return profile_aot_code_;
+ }
+ void SetProfileAOTCode(bool value) {
+ profile_aot_code_ = value;
+ }
+ bool GetWaitForJitNotificationsToSave() const {
+ return wait_for_jit_notifications_to_save_;
+ }
+ void SetWaitForJitNotificationsToSave(bool value) {
+ wait_for_jit_notifications_to_save_ = value;
+ }
friend std::ostream & operator<<(std::ostream &os, const ProfileSaverOptions& pso) {
os << "enabled_" << pso.enabled_
@@ -113,7 +131,9 @@
<< ", min_classes_to_save_" << pso.min_classes_to_save_
<< ", min_notification_before_wake_" << pso.min_notification_before_wake_
<< ", max_notification_before_wake_" << pso.max_notification_before_wake_
- << ", profile_boot_class_path_" << pso.profile_boot_class_path_;
+ << ", profile_boot_class_path_" << pso.profile_boot_class_path_
+ << ", profile_aot_code_" << pso.profile_aot_code_
+ << ", wait_for_jit_notifications_to_save_" << pso.wait_for_jit_notifications_to_save_;
return os;
}
@@ -129,6 +149,8 @@
uint32_t max_notification_before_wake_;
std::string profile_path_;
bool profile_boot_class_path_;
+ bool profile_aot_code_;
+ bool wait_for_jit_notifications_to_save_;
};
} // namespace art