diff options
| -rw-r--r-- | runtime/jit/jit_code_cache.cc | 2 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.h | 2 | ||||
| -rw-r--r-- | runtime/jit/profile_saver.cc | 64 | ||||
| -rw-r--r-- | runtime/jit/profile_saver.h | 12 |
4 files changed, 58 insertions, 22 deletions
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 64b2c899aa..bec6e13d53 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -719,7 +719,7 @@ void* JitCodeCache::MoreCore(const void* mspace, intptr_t increment) NO_THREAD_S } } -void JitCodeCache::GetCompiledArtMethods(const std::set<const std::string>& dex_base_locations, +void JitCodeCache::GetCompiledArtMethods(const std::set<std::string>& dex_base_locations, std::vector<ArtMethod*>& methods) { MutexLock mu(Thread::Current(), lock_); for (auto it : method_code_map_) { diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h index 67fa928f61..69fc5532c1 100644 --- a/runtime/jit/jit_code_cache.h +++ b/runtime/jit/jit_code_cache.h @@ -153,7 +153,7 @@ class JitCodeCache { void* MoreCore(const void* mspace, intptr_t increment); // Adds to `methods` all the compiled ArtMethods which are part of any of the given dex locations. - void GetCompiledArtMethods(const std::set<const std::string>& dex_base_locations, + void GetCompiledArtMethods(const std::set<std::string>& dex_base_locations, std::vector<ArtMethod*>& methods) REQUIRES(!lock_) SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc index f3f5f95fb2..b1a5a4b24c 100644 --- a/runtime/jit/profile_saver.cc +++ b/runtime/jit/profile_saver.cc @@ -42,13 +42,12 @@ pthread_t ProfileSaver::profiler_pthread_ = 0U; ProfileSaver::ProfileSaver(const std::string& output_filename, jit::JitCodeCache* jit_code_cache, const std::vector<std::string>& code_paths) - : output_filename_(output_filename), - jit_code_cache_(jit_code_cache), - tracked_dex_base_locations_(code_paths.begin(), code_paths.end()), + : jit_code_cache_(jit_code_cache), code_cache_last_update_time_ns_(0), shutting_down_(false), wait_lock_("ProfileSaver wait lock"), period_condition_("ProfileSaver period condition", wait_lock_) { + AddTrackedLocations(output_filename, code_paths); } void ProfileSaver::Run() { @@ -86,8 +85,6 @@ void ProfileSaver::Run() { } bool ProfileSaver::ProcessProfilingInfo() { - VLOG(profiler) << "Save profiling information to: " << output_filename_; - uint64_t last_update_time_ns = jit_code_cache_->GetLastUpdateTimeNs(); if (last_update_time_ns - code_cache_last_update_time_ns_ < kMinimumTimeBetweenCodeCacheUpdatesNs) { @@ -99,18 +96,36 @@ bool ProfileSaver::ProcessProfilingInfo() { uint64_t start = NanoTime(); code_cache_last_update_time_ns_ = last_update_time_ns; - std::vector<ArtMethod*> methods; + SafeMap<std::string, std::set<std::string>> tracked_locations; { - ScopedObjectAccess soa(Thread::Current()); - jit_code_cache_->GetCompiledArtMethods(tracked_dex_base_locations_, methods); - } - if (methods.size() < kMinimumNrOrMethodsToSave) { - VLOG(profiler) << "Not enough information to save. Nr of methods: " << methods.size(); - return false; + // Make a copy so that we don't hold the lock while doing I/O. + MutexLock mu(Thread::Current(), *Locks::profiler_lock_); + tracked_locations = tracked_dex_base_locations_; } + for (const auto& it : tracked_locations) { + if (ShuttingDown(Thread::Current())) { + return true; + } + const std::string& filename = it.first; + const std::set<std::string>& locations = it.second; + std::vector<ArtMethod*> methods; + { + ScopedObjectAccess soa(Thread::Current()); + jit_code_cache_->GetCompiledArtMethods(locations, methods); + } + if (methods.size() < kMinimumNrOrMethodsToSave) { + VLOG(profiler) << "Not enough information to save to: " << filename + <<" Nr of methods: " << methods.size(); + return false; + } - ProfileCompilationInfo::SaveProfilingInfo(output_filename_, methods); - VLOG(profiler) << "Profile process time: " << PrettyDuration(NanoTime() - start); + if (!ProfileCompilationInfo::SaveProfilingInfo(filename, methods)) { + LOG(WARNING) << "Could not save profiling info to " << filename; + return false; + } + + VLOG(profiler) << "Profile process time: " << PrettyDuration(NanoTime() - start); + } return true; } @@ -137,9 +152,13 @@ void ProfileSaver::Start(const std::string& output_filename, DCHECK(jit_code_cache != nullptr); MutexLock mu(Thread::Current(), *Locks::profiler_lock_); - // Don't start two profile saver threads. if (instance_ != nullptr) { - DCHECK(false) << "Tried to start two profile savers"; + // If we already have an instance, make sure it uses the same jit_code_cache. + // This may be called multiple times via Runtime::registerAppInfo (e.g. for + // apps which share the same runtime). + DCHECK_EQ(instance_->jit_code_cache_, jit_code_cache); + // Add the code_paths to the tracked locations. + instance_->AddTrackedLocations(output_filename, code_paths); return; } @@ -161,7 +180,7 @@ void ProfileSaver::Stop() { { MutexLock profiler_mutex(Thread::Current(), *Locks::profiler_lock_); - VLOG(profiler) << "Stopping profile saver thread for file: " << instance_->output_filename_; + VLOG(profiler) << "Stopping profile saver thread"; profile_saver = instance_; profiler_pthread = profiler_pthread_; if (instance_ == nullptr) { @@ -202,4 +221,15 @@ bool ProfileSaver::IsStarted() { return instance_ != nullptr; } +void ProfileSaver::AddTrackedLocations(const std::string& output_filename, + const std::vector<std::string>& code_paths) { + auto it = tracked_dex_base_locations_.find(output_filename); + if (it == tracked_dex_base_locations_.end()) { + tracked_dex_base_locations_.Put(output_filename, + std::set<std::string>(code_paths.begin(), code_paths.end())); + } else { + it->second.insert(code_paths.begin(), code_paths.end()); + } +} + } // namespace art diff --git a/runtime/jit/profile_saver.h b/runtime/jit/profile_saver.h index d60142b205..3342790e43 100644 --- a/runtime/jit/profile_saver.h +++ b/runtime/jit/profile_saver.h @@ -20,12 +20,14 @@ #include "base/mutex.h" #include "jit_code_cache.h" #include "offline_profiling_info.h" +#include "safe_map.h" namespace art { class ProfileSaver { public: - // Starts the profile saver thread. + // Starts the profile saver thread if not already started. + // If the saver is already running it adds (output_filename, code_paths) to its tracked locations. static void Start(const std::string& output_filename, jit::JitCodeCache* jit_code_cache, const std::vector<std::string>& code_paths) @@ -58,14 +60,18 @@ class ProfileSaver { // Returns true if the saver is shutting down (ProfileSaver::Stop() has been called). bool ShuttingDown(Thread* self) REQUIRES(!Locks::profiler_lock_); + void AddTrackedLocations(const std::string& output_filename, + const std::vector<std::string>& code_paths) + REQUIRES(Locks::profiler_lock_); + // The only instance of the saver. static ProfileSaver* instance_ GUARDED_BY(Locks::profiler_lock_); // Profile saver thread. static pthread_t profiler_pthread_ GUARDED_BY(Locks::profiler_lock_); - const std::string output_filename_; jit::JitCodeCache* jit_code_cache_; - const std::set<const std::string> tracked_dex_base_locations_; + SafeMap<std::string, std::set<std::string>> tracked_dex_base_locations_ + GUARDED_BY(Locks::profiler_lock_); uint64_t code_cache_last_update_time_ns_; bool shutting_down_ GUARDED_BY(Locks::profiler_lock_); |