summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-05-25 00:07:39 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-05-25 00:07:39 +0000
commit0cb22d07e18e1bcf7f545f1a587e3ebbec9f99cb (patch)
treebbb5bc561edb97a926cd06680405e1b157894024
parent3b8e0b2cb67d5cb5d04c84be4294668703f4c7c1 (diff)
parent27ed3a44e87690595f612f6ca03a6c8e6f38451c (diff)
Merge "Add methods with samples during launch to profile"
-rw-r--r--runtime/jit/profile_saver.cc56
-rw-r--r--runtime/jit/profile_saver.h6
2 files changed, 53 insertions, 9 deletions
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index b0a786e9e3..c5d3ccd748 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -35,6 +35,8 @@ namespace art {
// with all profile savers running at the same time.
static constexpr const uint64_t kMinSavePeriodNs = MsToNs(20 * 1000); // 20 seconds
static constexpr const uint64_t kSaveResolvedClassesDelayMs = 2 * 1000; // 2 seconds
+// Minimum number of JIT samples during launch to include a method into the profile.
+static constexpr const size_t kStartupMethodSamples = 1;
static constexpr const uint32_t kMinimumNumberOfMethodsToSave = 10;
static constexpr const uint32_t kMinimumNumberOfClassesToSave = 10;
@@ -108,7 +110,7 @@ void ProfileSaver::Run() {
}
total_ms_of_sleep_ += kSaveResolvedClassesDelayMs;
}
- FetchAndCacheResolvedClasses();
+ FetchAndCacheResolvedClassesAndMethods();
// Loop for the profiled methods.
while (!ShuttingDown(self)) {
@@ -204,11 +206,48 @@ ProfileCompilationInfo* ProfileSaver::GetCachedProfiledInfo(const std::string& f
return &info_it->second;
}
-void ProfileSaver::FetchAndCacheResolvedClasses() {
+// Get resolved methods that have a profile info or more than kStartupMethodSamples samples.
+// Excludes native methods and classes in the boot image.
+class GetMethodsVisitor : public ClassVisitor {
+ public:
+ explicit GetMethodsVisitor(std::vector<MethodReference>* methods) : methods_(methods) {}
+
+ virtual bool operator()(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_) {
+ if (Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass)) {
+ return true;
+ }
+ for (ArtMethod& method : klass->GetMethods(sizeof(void*))) {
+ if (!method.IsNative()) {
+ if (method.GetCounter() >= kStartupMethodSamples ||
+ method.GetProfilingInfo(sizeof(void*)) != nullptr) {
+ // Have samples, add to profile.
+ const DexFile* dex_file = method.GetInterfaceMethodIfProxy(sizeof(void*))->GetDexFile();
+ methods_->push_back(MethodReference(dex_file, method.GetDexMethodIndex()));
+ }
+ }
+ }
+ return true;
+ }
+
+ private:
+ std::vector<MethodReference>* const methods_;
+};
+
+void ProfileSaver::FetchAndCacheResolvedClassesAndMethods() {
ScopedTrace trace(__PRETTY_FUNCTION__);
ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
std::set<DexCacheResolvedClasses> resolved_classes =
class_linker->GetResolvedClasses(/*ignore boot classes*/ true);
+
+ std::vector<MethodReference> methods;
+ {
+ ScopedTrace trace2("Get hot methods");
+ GetMethodsVisitor visitor(&methods);
+ ScopedObjectAccess soa(Thread::Current());
+ class_linker->VisitClasses(&visitor);
+ VLOG(profiler) << "Methods with samples greater than "
+ << kStartupMethodSamples << " = " << methods.size();
+ }
MutexLock mu(Thread::Current(), *Locks::profiler_lock_);
uint64_t total_number_of_profile_entries_cached = 0;
@@ -216,11 +255,16 @@ void ProfileSaver::FetchAndCacheResolvedClasses() {
std::set<DexCacheResolvedClasses> resolved_classes_for_location;
const std::string& filename = it.first;
const std::set<std::string>& locations = it.second;
-
+ std::vector<MethodReference> methods_for_location;
+ for (const MethodReference& ref : methods) {
+ if (locations.find(ref.dex_file->GetBaseLocation()) != locations.end()) {
+ methods_for_location.push_back(ref);
+ }
+ }
for (const DexCacheResolvedClasses& classes : resolved_classes) {
if (locations.find(classes.GetBaseLocation()) != locations.end()) {
- VLOG(profiler) << "Added classes for location " << classes.GetBaseLocation()
- << " (" << classes.GetDexLocation() << ")";
+ VLOG(profiler) << "Added " << classes.GetClasses().size() << " classes for location "
+ << classes.GetBaseLocation() << " (" << classes.GetDexLocation() << ")";
resolved_classes_for_location.insert(classes);
} else {
VLOG(profiler) << "Location not found " << classes.GetBaseLocation()
@@ -228,7 +272,7 @@ void ProfileSaver::FetchAndCacheResolvedClasses() {
}
}
ProfileCompilationInfo* info = GetCachedProfiledInfo(filename);
- info->AddMethodsAndClasses(std::vector<MethodReference>(), resolved_classes_for_location);
+ info->AddMethodsAndClasses(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(
diff --git a/runtime/jit/profile_saver.h b/runtime/jit/profile_saver.h
index c6da95931c..9c6d0fa1cf 100644
--- a/runtime/jit/profile_saver.h
+++ b/runtime/jit/profile_saver.h
@@ -95,9 +95,9 @@ class ProfileSaver {
// If no entry exists, a new empty one will be created, added to the cache and
// then returned.
ProfileCompilationInfo* GetCachedProfiledInfo(const std::string& filename);
- // Fetches the current resolved classes from the ClassLinker and stores them
- // in the profile_cache_ for later save.
- void FetchAndCacheResolvedClasses();
+ // Fetches the current resolved classes and methods from the ClassLinker and stores them in the
+ // profile_cache_ for later save.
+ void FetchAndCacheResolvedClassesAndMethods();
static bool MaybeRecordDexUseInternal(
const std::string& dex_location,