diff options
| author | 2017-03-14 17:58:21 -0700 | |
|---|---|---|
| committer | 2017-03-15 16:18:33 -0700 | |
| commit | 51e417b45fa13050318715d2ad3da99d90b5f334 (patch) | |
| tree | e32464e15dbce92747a0383d11498ec5d9b309b9 | |
| parent | 13ef0447b43ecbf18d3c4e4c72d66bbbc1815f0c (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.cc | 42 | ||||
| -rw-r--r-- | runtime/jit/profile_saver.h | 14 |
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; |