Create CompilerOptions
Package up most compiler related options in CompilerOptions. Details include:
- Includes compiler filter, method thresholds, SEA IR mode.
- Excludes those needed during Runtime::Init such as CompilerCallbacks and VerificationResults.
- Pass CompilerOptions to CompilerDriver.
- Remove CompilerOptions from Runtime.
- Add ability to pass options for app and image dex2oat to runtime via
-Xcompiler-option and -Ximage-compiler-option respectively.
Other
- Replace 2x CompilerCallbacks implementations with one.
- Factor out execv code for use by both image and oat generation.
- More OatFile error_msg reporting.
- DCHECK for SuspendAll found trying to run valgrind.
Change-Id: Iecb57da907be0c856d00c3cd634b5042a229e620
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 591d92a..6800f7b 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -211,7 +211,7 @@
class_loader, dex_file);
cu.NewTimingSplit("MIROpt:CheckFilters");
- if (cu.mir_graph->SkipCompilation(Runtime::Current()->GetCompilerFilter())) {
+ if (cu.mir_graph->SkipCompilation()) {
return NULL;
}
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index ab55333..7ce8f69 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -18,6 +18,7 @@
#include "dataflow_iterator-inl.h"
#include "dex/quick/dex_file_method_inliner.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
+#include "driver/compiler_options.h"
namespace art {
@@ -958,7 +959,7 @@
}
// Complex, logic-intensive?
- if ((GetNumDalvikInsns() > Runtime::Current()->GetSmallMethodThreshold()) &&
+ if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
stats->branch_ratio > 0.3) {
return false;
}
@@ -984,7 +985,7 @@
}
// If significant in size and high proportion of expensive operations, skip.
- if ((GetNumDalvikInsns() > Runtime::Current()->GetSmallMethodThreshold()) &&
+ if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
(stats->heavyweight_ratio > 0.3)) {
return true;
}
@@ -996,12 +997,14 @@
* 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(Runtime::CompilerFilter compiler_filter) {
- if (compiler_filter == Runtime::kEverything) {
+bool MIRGraph::SkipCompilation() {
+ const CompilerOptions& compiler_options = cu_->compiler_driver->GetCompilerOptions();
+ CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
+ if (compiler_filter == CompilerOptions::kEverything) {
return false;
}
- if (compiler_filter == Runtime::kInterpretOnly) {
+ if (compiler_filter == CompilerOptions::kInterpretOnly) {
LOG(WARNING) << "InterpretOnly should ideally be filtered out prior to parsing.";
return true;
}
@@ -1010,17 +1013,17 @@
size_t small_cutoff = 0;
size_t default_cutoff = 0;
switch (compiler_filter) {
- case Runtime::kBalanced:
- small_cutoff = Runtime::Current()->GetSmallMethodThreshold();
- default_cutoff = Runtime::Current()->GetLargeMethodThreshold();
+ case CompilerOptions::kBalanced:
+ small_cutoff = compiler_options.GetSmallMethodThreshold();
+ default_cutoff = compiler_options.GetLargeMethodThreshold();
break;
- case Runtime::kSpace:
- small_cutoff = Runtime::Current()->GetTinyMethodThreshold();
- default_cutoff = Runtime::Current()->GetSmallMethodThreshold();
+ case CompilerOptions::kSpace:
+ small_cutoff = compiler_options.GetTinyMethodThreshold();
+ default_cutoff = compiler_options.GetSmallMethodThreshold();
break;
- case Runtime::kSpeed:
- small_cutoff = Runtime::Current()->GetHugeMethodThreshold();
- default_cutoff = Runtime::Current()->GetHugeMethodThreshold();
+ case CompilerOptions::kSpeed:
+ small_cutoff = compiler_options.GetHugeMethodThreshold();
+ default_cutoff = compiler_options.GetHugeMethodThreshold();
break;
default:
LOG(FATAL) << "Unexpected compiler_filter_: " << compiler_filter;
@@ -1033,17 +1036,17 @@
* Filter 1: Huge methods are likely to be machine generated, but some aren't.
* If huge, assume we won't compile, but allow futher analysis to turn it back on.
*/
- if (GetNumDalvikInsns() > Runtime::Current()->GetHugeMethodThreshold()) {
+ if (compiler_options.IsHugeMethod(GetNumDalvikInsns())) {
skip_compilation = true;
// If we're got a huge number of basic blocks, don't bother with further analysis.
- if (static_cast<size_t>(num_blocks_) > (Runtime::Current()->GetHugeMethodThreshold() / 2)) {
+ if (static_cast<size_t>(num_blocks_) > (compiler_options.GetHugeMethodThreshold() / 2)) {
return true;
}
- } else if (GetNumDalvikInsns() > Runtime::Current()->GetLargeMethodThreshold() &&
+ } else if (compiler_options.IsLargeMethod(GetNumDalvikInsns()) &&
/* If it's large and contains no branches, it's likely to be machine generated initialization */
(GetBranchCount() == 0)) {
return true;
- } else if (compiler_filter == Runtime::kSpeed) {
+ } else if (compiler_filter == CompilerOptions::kSpeed) {
// If not huge, compile.
return false;
}
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index d844aac..2174f67 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -372,7 +372,7 @@
* Examine the graph to determine whether it's worthwile to spend the time compiling
* this method.
*/
- bool SkipCompilation(Runtime::CompilerFilter compiler_filter);
+ bool SkipCompilation();
/*
* Parse dex method and add MIR at current insert point. Returns id (which is
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index edccec5..947c22d 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -19,6 +19,8 @@
#include "base/stl_util.h"
#include "base/mutex.h"
#include "base/mutex-inl.h"
+#include "driver/compiler_driver.h"
+#include "driver/compiler_options.h"
#include "thread.h"
#include "thread-inl.h"
#include "verified_method.h"
@@ -27,8 +29,9 @@
namespace art {
-VerificationResults::VerificationResults()
- : verified_methods_lock_("compiler verified methods lock"),
+VerificationResults::VerificationResults(const CompilerOptions* compiler_options)
+ : compiler_options_(compiler_options),
+ verified_methods_lock_("compiler verified methods lock"),
verified_methods_(),
rejected_classes_lock_("compiler rejected classes lock"),
rejected_classes_() {
@@ -43,6 +46,7 @@
}
bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) {
+ DCHECK(method_verifier != NULL);
MethodReference ref = method_verifier->GetMethodReference();
bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags());
// TODO: Check also for virtual/interface invokes when DEX-to-DEX supports devirtualization.
@@ -95,16 +99,18 @@
bool VerificationResults::IsCandidateForCompilation(MethodReference& method_ref,
const uint32_t access_flags) {
#ifdef ART_SEA_IR_MODE
- bool use_sea = Runtime::Current()->IsSeaIRMode();
- use_sea = use_sea && (std::string::npos != PrettyMethod(
- method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci"));
- if (use_sea) return true;
+ bool use_sea = compiler_options_->GetSeaIrMode();
+ use_sea = use_sea && (std::string::npos != PrettyMethod(
+ method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci"));
+ if (use_sea) {
+ return true;
+ }
#endif
// Don't compile class initializers, ever.
if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) {
return false;
}
- return (Runtime::Current()->GetCompilerFilter() != Runtime::kInterpretOnly);
+ return (compiler_options_->GetCompilerFilter() != CompilerOptions::kInterpretOnly);
}
} // namespace art
diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h
index 2eb0713..278182f 100644
--- a/compiler/dex/verification_results.h
+++ b/compiler/dex/verification_results.h
@@ -33,11 +33,13 @@
class MethodVerifier;
} // namespace verifier
+class CompilerOptions;
class VerifiedMethod;
+// Used by CompilerCallbacks to track verification information from the Runtime.
class VerificationResults {
public:
- VerificationResults();
+ explicit VerificationResults(const CompilerOptions* compiler_options);
~VerificationResults();
bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier)
@@ -50,15 +52,17 @@
void AddRejectedClass(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);
bool IsClassRejected(ClassReference ref) LOCKS_EXCLUDED(rejected_classes_lock_);
- static bool IsCandidateForCompilation(MethodReference& method_ref,
- const uint32_t access_flags);
+ bool IsCandidateForCompilation(MethodReference& method_ref,
+ const uint32_t access_flags);
private:
+ const CompilerOptions* compiler_options_;
+
// Verified methods.
typedef SafeMap<MethodReference, const VerifiedMethod*,
MethodReferenceComparator> VerifiedMethodMap;
ReaderWriterMutex verified_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- VerifiedMethodMap verified_methods_;
+ VerifiedMethodMap verified_methods_ GUARDED_BY(verified_methods_lock_);
// Rejected classes.
ReaderWriterMutex rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;