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/dex/frontend.cc b/compiler/dex/frontend.cc
index 1c2d16f..243395a 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -17,6 +17,7 @@
#include "compiler_backend.h"
#include "compiler_internals.h"
#include "driver/compiler_driver.h"
+#include "driver/compiler_options.h"
#include "dataflow_iterator-inl.h"
#include "leb128.h"
#include "mirror/object.h"
@@ -25,7 +26,7 @@
#include "backend.h"
#include "base/logging.h"
#include "base/timing_logger.h"
-
+#include "driver/compiler_options.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
namespace art {
@@ -209,13 +210,26 @@
cu.mir_graph->EnableOpcodeCounting();
}
+ const CompilerOptions& compiler_options = cu.compiler_driver->GetCompilerOptions();
+ CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
+
+ // Check early if we should skip this compilation if using the profiled filter.
+ if (cu.compiler_driver->ProfilePresent()) {
+ std::string methodname = PrettyMethod(method_idx, dex_file);
+ if (cu.mir_graph->SkipCompilation(methodname)) {
+ return NULL;
+ }
+ }
+
/* Build the raw MIR graph */
cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
class_loader, dex_file);
cu.NewTimingSplit("MIROpt:CheckFilters");
- if (cu.mir_graph->SkipCompilation()) {
- return NULL;
+ if (compiler_filter != CompilerOptions::kInterpretOnly) {
+ if (cu.mir_graph->SkipCompilation()) {
+ return NULL;
+ }
}
/* Create the pass driver and launch it */
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index 667ee26..5314bb7 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -999,7 +999,6 @@
/*
* Will eventually want this to be a bit more sophisticated and happen at verification time.
- * Ultimate goal is to drive with profile data.
*/
bool MIRGraph::SkipCompilation() {
const CompilerOptions& compiler_options = cu_->compiler_driver->GetCompilerOptions();
@@ -1013,8 +1012,7 @@
return true;
}
- if (compiler_filter == CompilerOptions::kInterpretOnly) {
- LOG(WARNING) << "InterpretOnly should ideally be filtered out prior to parsing.";
+ if (compiler_filter == CompilerOptions::kInterpretOnly || compiler_filter == CompilerOptions::kProfiled) {
return true;
}
@@ -1170,4 +1168,8 @@
}
}
+bool MIRGraph::SkipCompilation(const std::string& methodname) {
+ return cu_->compiler_driver->SkipCompilation(methodname);
+}
+
} // namespace art
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 85d6d89..94b3816 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -383,6 +383,11 @@
bool SkipCompilation();
/*
+ * Should we skip the compilation of this method based on its name?
+ */
+ bool SkipCompilation(const std::string& methodname);
+
+ /*
* Parse dex method and add MIR at current insert point. Returns id (which is
* actually the index of the method in the m_units_ array).
*/
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index 947c22d..6b0875c 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -110,7 +110,7 @@
if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) {
return false;
}
- return (compiler_options_->GetCompilerFilter() != CompilerOptions::kInterpretOnly);
+ return true;
}
} // namespace art