OSDN Git Service

Add support for -Xverify:none mode.
authorJeff Hao <jeffhao@google.com>
Tue, 1 Apr 2014 21:58:49 +0000 (14:58 -0700)
committerJeff Hao <jeffhao@google.com>
Thu, 3 Apr 2014 00:18:13 +0000 (17:18 -0700)
This mode skips all verification and compilation.
Public bug: https://code.google.com/p/android/issues/detail?id=67664

Change-Id: Idd00ab8e9e46d129c02988b063c41a507e07bf5b

Android.mk
compiler/dex/frontend.cc
compiler/dex/mir_analysis.cc
compiler/driver/compiler_driver.cc
compiler/driver/compiler_options.h
dex2oat/dex2oat.cc
runtime/class_linker.cc
runtime/parsed_options.cc
runtime/parsed_options.h
runtime/runtime.cc
runtime/runtime.h

index 5325abd..6139cb9 100644 (file)
@@ -435,6 +435,18 @@ use-art-interpret-only:
        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
index 3f122de..cc616f6 100644 (file)
@@ -145,9 +145,7 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver,
     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 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver,
                               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 */
index b96c40d..200795e 100644 (file)
@@ -1013,7 +1013,7 @@ bool MIRGraph::SkipCompilation() {
     return true;
   }
 
-  if (compiler_filter == CompilerOptions::kInterpretOnly || compiler_filter == CompilerOptions::kProfiled) {
+  if (!compiler_options.IsCompilationEnabled() || compiler_filter == CompilerOptions::kProfiled) {
     return true;
   }
 
index c10dd84..a120d05 100644 (file)
@@ -598,6 +598,11 @@ void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const De
                                 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 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t
 
   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 {
index 0cca1e9..20c6bc8 100644 (file)
@@ -22,7 +22,8 @@ namespace art {
 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 @@ class CompilerOptions {
     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_;
   }
index 552ec89..f665f5c 100644 (file)
@@ -153,8 +153,8 @@ static void Usage(const char* fmt, ...) {
   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 @@ static void Usage(const char* fmt, ...) {
   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 @@ static void Usage(const char* fmt, ...) {
   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 @@ static int dex2oat(int argc, char** argv) {
   }
   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 @@ static int dex2oat(int argc, char** argv) {
   }
 
   /*
-   * 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];
index 19cc23c..6c5406e 100644 (file)
@@ -569,6 +569,10 @@ bool ClassLinker::GenerateOatFile(const char* dex_filename,
 
   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 @@ void ClassLinker::VerifyClass(const SirtRef<mirror::Class>& klass) {
     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) {
index e2086f1..08a674f 100644 (file)
@@ -196,6 +196,8 @@ bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecogni
   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 @@ bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecogni
         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 @@ bool ParsedOptions::Parse(const Runtime::Options& options, bool ignore_unrecogni
                (option == "-dsa") ||
                (option == "-enablesystemassertions") ||
                (option == "-disablesystemassertions") ||
-               StartsWith(option, "-Xverify:") ||
                (option == "-Xrs") ||
                StartsWith(option, "-Xint:") ||
                StartsWith(option, "-Xdexopt:") ||
index d6516a8..416bc78 100644 (file)
@@ -80,6 +80,7 @@ class ParsedOptions {
   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;
index b0a6584..1b3c996 100644 (file)
@@ -132,7 +132,8 @@ Runtime::Runtime()
       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 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
   thread_list_ = new ThreadList;
   intern_table_ = new InternTable;
 
+  verify_ = options->verify_;
 
   if (options->interpreter_only_) {
     GetInstrumentation()->ForceInterpretOnly();
index 176b71c..7b3e04c 100644 (file)
@@ -421,6 +421,10 @@ class Runtime {
     return stack_overflow_handler_ == nullptr;
   }
 
+  bool IsVerificationEnabled() const {
+    return verify_;
+  }
+
   bool RunningOnValgrind() const {
     return running_on_valgrind_;
   }
@@ -563,6 +567,9 @@ class Runtime {
   SuspensionHandler* suspend_handler_;
   StackOverflowHandler* stack_overflow_handler_;
 
+  // If false, verification is disabled. True by default.
+  bool verify_;
+
   DISALLOW_COPY_AND_ASSIGN(Runtime);
 };