Add support for -Xverify:none mode.
This mode skips all verification and compilation.
Public bug: https://code.google.com/p/android/issues/detail?id=67664
Change-Id: Idd00ab8e9e46d129c02988b063c41a507e07bf5b
diff --git a/Android.mk b/Android.mk
index 5325abd..6139cb9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -435,6 +435,18 @@
adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
adb shell start
+.PHONY: use-art-verify-none
+use-art-verify-none:
+ adb root && sleep 3
+ adb shell stop
+ adb shell rm $(ART_DALVIK_CACHE_DIR)/*.dex
+ adb shell rm $(ART_DALVIK_CACHE_DIR)/*.oat
+ adb shell rm $(ART_DALVIK_CACHE_DIR)/*.art
+ adb shell setprop dalvik.vm.dex2oat-flags "--compiler-filter=verify-none"
+ adb shell setprop dalvik.vm.image-dex2oat-flags "--compiler-filter=verify-none"
+ adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell start
+
########################################################################
endif # !art_dont_bother
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 3f122de..cc616f6 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -145,9 +145,7 @@
return NULL;
}
- const CompilerOptions& compiler_options = driver.GetCompilerOptions();
- CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
- if (compiler_filter == CompilerOptions::kInterpretOnly) {
+ if (!driver.GetCompilerOptions().IsCompilationEnabled()) {
return nullptr;
}
@@ -230,10 +228,8 @@
class_loader, dex_file);
cu.NewTimingSplit("MIROpt:CheckFilters");
- if (compiler_filter != CompilerOptions::kInterpretOnly) {
- if (cu.mir_graph->SkipCompilation()) {
- return NULL;
- }
+ 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 b96c40d..200795e 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -1013,7 +1013,7 @@
return true;
}
- if (compiler_filter == CompilerOptions::kInterpretOnly || compiler_filter == CompilerOptions::kProfiled) {
+ if (!compiler_options.IsCompilationEnabled() || compiler_filter == CompilerOptions::kProfiled) {
return true;
}
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index c10dd84..a120d05 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -598,6 +598,11 @@
ThreadPool* thread_pool, TimingLogger* timings) {
LoadImageClasses(timings);
+ if (!compiler_options_->IsVerificationEnabled()) {
+ VLOG(compiler) << "Verify none mode specified, skipping pre-compilation";
+ return;
+ }
+
Resolve(class_loader, dex_files, thread_pool, timings);
Verify(class_loader, dex_files, thread_pool, timings);
@@ -1872,7 +1877,7 @@
if ((access_flags & kAccNative) != 0) {
// Are we interpreting only and have support for generic JNI down calls?
- if ((compiler_options_->GetCompilerFilter() == CompilerOptions::kInterpretOnly) &&
+ if (!compiler_options_->IsCompilationEnabled() &&
(instruction_set_ == kX86_64 || instruction_set_ == kArm64)) {
// Leaving this empty will trigger the generic JNI version
} else {
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 0cca1e9..20c6bc8 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -22,7 +22,8 @@
class CompilerOptions {
public:
enum CompilerFilter {
- kInterpretOnly, // Compile nothing.
+ kVerifyNone, // Skip verification and compile nothing except JNI stubs.
+ kInterpretOnly, // Compile nothing except JNI stubs.
kProfiled, // Compile based on profile.
kSpace, // Maximize space savings.
kBalanced, // Try to get the best performance return on compilation investment.
@@ -86,6 +87,15 @@
compiler_filter_ = compiler_filter;
}
+ bool IsCompilationEnabled() const {
+ return ((compiler_filter_ != CompilerOptions::kVerifyNone) &&
+ (compiler_filter_ != CompilerOptions::kInterpretOnly));
+ }
+
+ bool IsVerificationEnabled() const {
+ return (compiler_filter_ != CompilerOptions::kVerifyNone);
+ }
+
size_t GetHugeMethodThreshold() const {
return huge_method_threshold_;
}
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 552ec89..f665f5c 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -153,8 +153,8 @@
UsageError(" Example: --compiler-backend=Portable");
UsageError(" Default: Quick");
UsageError("");
- UsageError(" --compiler-filter=(interpret-only|space|balanced|speed|everything): select");
- UsageError(" compiler filter.");
+ UsageError(" --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):");
+ UsageError(" select compiler filter.");
UsageError(" Example: --compiler-filter=everything");
#if ART_SMALL_MODE
UsageError(" Default: interpret-only");
@@ -189,7 +189,8 @@
UsageError("");
UsageError(" --num-dex-methods=<method-count>: threshold size for a small dex file for");
UsageError(" compiler filter tuning. If the input has fewer than this many methods");
- UsageError(" and the filter is not interpret-only, overrides the filter to use speed");
+ UsageError(" and the filter is not interpret-only or verify-none, overrides the");
+ UsageError(" filter to use speed");
UsageError(" Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
UsageError(" Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
UsageError("");
@@ -201,8 +202,8 @@
UsageError(" such as initial heap size, maximum heap size, and verbose output.");
UsageError(" Use a separate --runtime-arg switch for each argument.");
UsageError(" Example: --runtime-arg -Xms256m");
- UsageError("");
- UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation.");
+ UsageError("");
+ UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation.");
UsageError("");
UsageError(" --print-pass-names: print a list of pass names");
UsageError("");
@@ -1037,7 +1038,9 @@
}
CHECK(compiler_filter_string != nullptr);
CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
- if (strcmp(compiler_filter_string, "interpret-only") == 0) {
+ if (strcmp(compiler_filter_string, "verify-none") == 0) {
+ compiler_filter = CompilerOptions::kVerifyNone;
+ } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
compiler_filter = CompilerOptions::kInterpretOnly;
} else if (strcmp(compiler_filter_string, "space") == 0) {
compiler_filter = CompilerOptions::kSpace;
@@ -1208,10 +1211,10 @@
}
/*
- * If we're not in interpret-only mode, go ahead and compile small applications. Don't
- * bother to check if we're doing the image.
+ * If we're not in interpret-only or verify-none mode, go ahead and compile small applications.
+ * Don't bother to check if we're doing the image.
*/
- if (!image && (compiler_options.GetCompilerFilter() != CompilerOptions::kInterpretOnly)) {
+ if (!image && compiler_options.IsCompilationEnabled()) {
size_t num_methods = 0;
for (size_t i = 0; i != dex_files.size(); ++i) {
const DexFile* dex_file = dex_files[i];
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 19cc23c..6c5406e 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -569,6 +569,10 @@
Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+ if (!Runtime::Current()->IsVerificationEnabled()) {
+ argv.push_back("--compiler-filter=verify-none");
+ }
+
if (!kIsTargetBuild) {
argv.push_back("--host");
}
@@ -2533,6 +2537,12 @@
klass->SetStatus(mirror::Class::kStatusVerifyingAtRuntime, self);
}
+ // Skip verification if disabled.
+ if (!Runtime::Current()->IsVerificationEnabled()) {
+ klass->SetStatus(mirror::Class::kStatusVerified, self);
+ return;
+ }
+
// Verify super class.
SirtRef<mirror::Class> super(self, klass->GetSuperClass());
if (super.get() != NULL) {
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index e2086f1..08a674f 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -196,6 +196,8 @@
profile_backoff_coefficient_ = 2.0;
profile_clock_source_ = kDefaultProfilerClockSource;
+ verify_ = true;
+
// Default to explicit checks. Switch off with -implicit-checks:.
// or setprop dalvik.vm.implicit_checks check1,check2,...
#ifdef HAVE_ANDROID_OS
@@ -569,6 +571,16 @@
return false;
}
image_compiler_options_.push_back(options[i].first);
+ } else if (StartsWith(option, "-Xverify:")) {
+ std::string verify_mode = option.substr(strlen("-Xverify:"));
+ if (verify_mode == "none") {
+ verify_ = false;
+ } else if (verify_mode == "remote" || verify_mode == "all") {
+ verify_ = true;
+ } else {
+ Usage("Unknown -Xverify option %s", verify_mode.c_str());
+ return false;
+ }
} else if (StartsWith(option, "-ea:") ||
StartsWith(option, "-da:") ||
StartsWith(option, "-enableassertions:") ||
@@ -578,7 +590,6 @@
(option == "-dsa") ||
(option == "-enablesystemassertions") ||
(option == "-disablesystemassertions") ||
- StartsWith(option, "-Xverify:") ||
(option == "-Xrs") ||
StartsWith(option, "-Xint:") ||
StartsWith(option, "-Xdexopt:") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index d6516a8..416bc78 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -80,6 +80,7 @@
uint32_t profile_interval_us_;
double profile_backoff_coefficient_;
ProfilerClockSource profile_clock_source_;
+ bool verify_;
static constexpr uint32_t kExplicitNullCheck = 1;
static constexpr uint32_t kExplicitSuspendCheck = 2;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index b0a6584..1b3c996 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -132,7 +132,8 @@
preinitialization_transaction_(nullptr),
null_pointer_handler_(nullptr),
suspend_handler_(nullptr),
- stack_overflow_handler_(nullptr) {
+ stack_overflow_handler_(nullptr),
+ verify_(false) {
for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
callee_save_methods_[i] = nullptr;
}
@@ -521,6 +522,7 @@
thread_list_ = new ThreadList;
intern_table_ = new InternTable;
+ verify_ = options->verify_;
if (options->interpreter_only_) {
GetInstrumentation()->ForceInterpretOnly();
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 176b71c..7b3e04c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -421,6 +421,10 @@
return stack_overflow_handler_ == nullptr;
}
+ bool IsVerificationEnabled() const {
+ return verify_;
+ }
+
bool RunningOnValgrind() const {
return running_on_valgrind_;
}
@@ -563,6 +567,9 @@
SuspensionHandler* suspend_handler_;
StackOverflowHandler* stack_overflow_handler_;
+ // If false, verification is disabled. True by default.
+ bool verify_;
+
DISALLOW_COPY_AND_ASSIGN(Runtime);
};