Make use of profiling information for dex2oat
If the profile file exists, the compiler driver will read it
and store the data in an internal map. Then, when we want to work
out whether to compile a method or not, the map is consulted and if
the method shows up with a high enough percentage of use we compile it.
The profile file itself is created by installd and is writeable by the
app. The file is in /data/dalvik-cache/profiles and is named by
the package name.
This also modifies the profiler itself to:
1. Only count runnable threads (not suspended threads) in the profile
2. Use system properties to allow tuning of the profile parameters
3. Merge profiles from multiple processes using file locking.
Bug: 12877748
Change-Id: Iab2f3a327a2860db2a80d5724277d6c626227f2b
Conflicts:
compiler/dex/frontend.cc
compiler/dex/mir_analysis.cc
compiler/dex/verification_results.cc
compiler/driver/compiler_driver.cc
dex2oat/dex2oat.cc
runtime/class_linker.cc
runtime/runtime.cc
runtime/runtime.h
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index ac70e5a..12463a9 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -105,7 +105,8 @@
InstructionSetFeatures instruction_set_features,
bool image, DescriptorSet* image_classes,
size_t thread_count, bool dump_stats, bool dump_passes,
- CumulativeLogger* timer);
+ CumulativeLogger* timer,
+ std::string profile_file = "");
~CompilerDriver();
@@ -141,6 +142,10 @@
return compiler_backend_.get();
}
+ bool ProfilePresent() const {
+ return profile_ok_;
+ }
+
// Are we compiling and creating an image file?
bool IsImage() const {
return image_;
@@ -554,6 +559,37 @@
return cfi_info_.get();
}
+ // Profile data. This is generated from previous runs of the program and stored
+ // in a file. It is used to determine whether to compile a particular method or not.
+ class ProfileData {
+ public:
+ ProfileData() : count_(0), method_size_(0), percent_(0) {}
+ ProfileData(std::string method_name, uint32_t count, uint32_t method_size, double percent) :
+ method_name_(method_name), count_(count), method_size_(method_size), percent_(percent) {
+ }
+
+ bool IsAbove(double v) const { return percent_ >= v; }
+ double GetPercent() const { return percent_; }
+
+ private:
+ std::string method_name_; // Method name.
+ uint32_t count_; // Number number of times it has been called.
+ uint32_t method_size_; // Size of the method on dex instructions.
+ double percent_; // Percentage of time spent in this method.
+ };
+
+ // Profile data is stored in a map, indexed by the full method name.
+ typedef std::map<const std::string, ProfileData> ProfileMap;
+ ProfileMap profile_map_;
+ bool profile_ok_;
+
+ // Read the profile data from the given file. Calculates the percentage for each method.
+ // Returns false if there was no profile file or it was malformed.
+ bool ReadProfile(const std::string& filename);
+
+ // Should the compiler run on this method given profile information?
+ bool SkipCompilation(const std::string& method_name);
+
private:
// Compute constant code and method pointers when possible
void GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,