summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Calin Juravle <calin@google.com> 2017-03-14 17:58:21 -0700
committer Calin Juravle <calin@google.com> 2017-03-15 16:18:33 -0700
commit51e417b45fa13050318715d2ad3da99d90b5f334 (patch)
treee32464e15dbce92747a0383d11498ec5d9b309b9
parent13ef0447b43ecbf18d3c4e4c72d66bbbc1815f0c (diff)
Tweak ProfileSaver saving strategy
To minimize the I/O, we used to store the number of methods/classes we last saved globally in the profiler saver. This is no longer viable once we want to track secondary dex files for profiling because each file might save a different set of methods. To make sure we do not miss data for secondary dex profiles, store the number of last saved methods separetely for each profile file. Test: test-art-host Bug: 26719109 Change-Id: I3a657f63d26f68c7ca83a754f6e4aa2c9d946176
-rw-r--r--runtime/jit/profile_saver.cc42
-rw-r--r--runtime/jit/profile_saver.h14
2 files changed, 30 insertions, 26 deletions
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index 00487c6728..2724b0062a 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -42,8 +42,6 @@ ProfileSaver::ProfileSaver(const ProfileSaverOptions& options,
const std::vector<std::string>& code_paths)
: jit_code_cache_(jit_code_cache),
shutting_down_(false),
- last_save_number_of_methods_(0),
- last_save_number_of_classes_(0),
last_time_ns_saver_woke_up_(0),
jit_activity_notifications_(0),
wait_lock_("ProfileSaver wait lock"),
@@ -171,10 +169,10 @@ void ProfileSaver::NotifyJitActivityInternal() {
}
}
-ProfileCompilationInfo* ProfileSaver::GetCachedProfiledInfo(const std::string& filename) {
+ProfileSaver::ProfileInfoCache* ProfileSaver::GetCachedProfiledInfo(const std::string& filename) {
auto info_it = profile_cache_.find(filename);
if (info_it == profile_cache_.end()) {
- info_it = profile_cache_.Put(filename, ProfileCompilationInfo());
+ info_it = profile_cache_.Put(filename, ProfileInfoCache());
}
return &info_it->second;
}
@@ -248,8 +246,9 @@ void ProfileSaver::FetchAndCacheResolvedClassesAndMethods() {
<< " (" << classes.GetDexLocation() << ")";
}
}
- ProfileCompilationInfo* info = GetCachedProfiledInfo(filename);
- info->AddMethodsAndClasses(profile_methods_for_location, resolved_classes_for_location);
+ ProfileInfoCache* cached_info = GetCachedProfiledInfo(filename);
+ cached_info->profile.AddMethodsAndClasses(profile_methods_for_location,
+ resolved_classes_for_location);
total_number_of_profile_entries_cached += resolved_classes_for_location.size();
}
max_number_of_profile_entries_cached_ = std::max(
@@ -283,14 +282,15 @@ bool ProfileSaver::ProcessProfilingInfo(uint16_t* new_methods) {
total_number_of_code_cache_queries_++;
}
- ProfileCompilationInfo* cached_info = GetCachedProfiledInfo(filename);
- cached_info->AddMethodsAndClasses(profile_methods, std::set<DexCacheResolvedClasses>());
+ ProfileInfoCache* cached_info = GetCachedProfiledInfo(filename);
+ ProfileCompilationInfo* cached_profile = &cached_info->profile;
+ cached_profile->AddMethodsAndClasses(profile_methods, std::set<DexCacheResolvedClasses>());
int64_t delta_number_of_methods =
- cached_info->GetNumberOfMethods() -
- static_cast<int64_t>(last_save_number_of_methods_);
+ cached_profile->GetNumberOfMethods() -
+ static_cast<int64_t>(cached_info->last_save_number_of_methods);
int64_t delta_number_of_classes =
- cached_info->GetNumberOfResolvedClasses() -
- static_cast<int64_t>(last_save_number_of_classes_);
+ cached_profile->GetNumberOfResolvedClasses() -
+ static_cast<int64_t>(cached_info->last_save_number_of_classes);
if (delta_number_of_methods < options_.GetMinMethodsToSave() &&
delta_number_of_classes < options_.GetMinClassesToSave()) {
@@ -304,12 +304,12 @@ bool ProfileSaver::ProcessProfilingInfo(uint16_t* new_methods) {
uint64_t bytes_written;
// Force the save. In case the profile data is corrupted or the the profile
// has the wrong version this will "fix" the file to the correct format.
- if (cached_info->MergeAndSave(filename, &bytes_written, /*force*/ true)) {
- last_save_number_of_methods_ = cached_info->GetNumberOfMethods();
- last_save_number_of_classes_ = cached_info->GetNumberOfResolvedClasses();
+ if (cached_profile->MergeAndSave(filename, &bytes_written, /*force*/ true)) {
+ cached_info->last_save_number_of_methods = cached_profile->GetNumberOfMethods();
+ cached_info->last_save_number_of_classes = cached_profile->GetNumberOfResolvedClasses();
// Clear resolved classes. No need to store them around as
// they don't change after the first write.
- cached_info->ClearResolvedClasses();
+ cached_profile->ClearResolvedClasses();
if (bytes_written > 0) {
total_number_of_writes_++;
total_bytes_written_ += bytes_written;
@@ -326,8 +326,8 @@ bool ProfileSaver::ProcessProfilingInfo(uint16_t* new_methods) {
total_number_of_failed_writes_++;
}
total_number_of_profile_entries_cached +=
- cached_info->GetNumberOfMethods() +
- cached_info->GetNumberOfResolvedClasses();
+ cached_profile->GetNumberOfMethods() +
+ cached_profile->GetNumberOfResolvedClasses();
}
max_number_of_profile_entries_cached_ = std::max(
max_number_of_profile_entries_cached_,
@@ -526,10 +526,8 @@ bool ProfileSaver::HasSeenMethod(const std::string& profile,
uint16_t method_idx) {
MutexLock mu(Thread::Current(), *Locks::profiler_lock_);
if (instance_ != nullptr) {
- ProfileCompilationInfo* info = instance_->GetCachedProfiledInfo(profile);
- if (info != nullptr) {
- return info->ContainsMethod(MethodReference(dex_file, method_idx));
- }
+ const ProfileCompilationInfo& info = instance_->GetCachedProfiledInfo(profile)->profile;
+ return info.ContainsMethod(MethodReference(dex_file, method_idx));
}
return false;
}
diff --git a/runtime/jit/profile_saver.h b/runtime/jit/profile_saver.h
index ec8342ad9e..8e0682d3fe 100644
--- a/runtime/jit/profile_saver.h
+++ b/runtime/jit/profile_saver.h
@@ -59,6 +59,14 @@ class ProfileSaver {
uint16_t method_idx);
private:
+ // A cache structure which keeps track of the data saved to disk.
+ // It is used to reduce the number of disk read/writes.
+ struct ProfileInfoCache {
+ ProfileCompilationInfo profile;
+ uint32_t last_save_number_of_methods = 0;
+ uint32_t last_save_number_of_classes = 0;
+ };
+
ProfileSaver(const ProfileSaverOptions& options,
const std::string& output_filename,
jit::JitCodeCache* jit_code_cache,
@@ -90,7 +98,7 @@ class ProfileSaver {
// Retrieves the cached profile compilation info for the given profile file.
// If no entry exists, a new empty one will be created, added to the cache and
// then returned.
- ProfileCompilationInfo* GetCachedProfiledInfo(const std::string& filename);
+ ProfileInfoCache* GetCachedProfiledInfo(const std::string& filename);
// Fetches the current resolved classes and methods from the ClassLinker and stores them in the
// profile_cache_ for later save.
void FetchAndCacheResolvedClassesAndMethods();
@@ -110,8 +118,6 @@ class ProfileSaver {
GUARDED_BY(Locks::profiler_lock_);
bool shutting_down_ GUARDED_BY(Locks::profiler_lock_);
- uint32_t last_save_number_of_methods_;
- uint32_t last_save_number_of_classes_;
uint64_t last_time_ns_saver_woke_up_ GUARDED_BY(wait_lock_);
uint32_t jit_activity_notifications_;
@@ -119,7 +125,7 @@ class ProfileSaver {
// profile information. The size of this cache is usually very small and tops
// to just a few hundreds entries in the ProfileCompilationInfo objects.
// It helps avoiding unnecessary writes to disk.
- SafeMap<std::string, ProfileCompilationInfo> profile_cache_;
+ SafeMap<std::string, ProfileInfoCache> profile_cache_;
// Save period condition support.
Mutex wait_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;