From 6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Thu, 5 Mar 2015 13:08:45 -0800 Subject: [PATCH] ART: Add option to abort dex2oat on hard failure Add an option that aborts dex2oat when a hard verifier failure occurs. Bug: 19606409 Change-Id: I53195284e22fe6207274101e85745af763c06271 --- compiler/driver/compiler_driver.cc | 8 ++++++++ compiler/driver/compiler_driver.h | 6 ++++++ compiler/driver/compiler_options.cc | 5 ++++- compiler/driver/compiler_options.h | 11 ++++++++++- compiler/jit/jit_compiler.cc | 3 ++- dex2oat/dex2oat.cc | 6 +++++- 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index a52a83a28..df2b520b5 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -358,6 +358,7 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options, image_(image), image_classes_(image_classes), classes_to_compile_(compiled_classes), + had_hard_verifier_failure_(false), thread_count_(thread_count), stats_(new AOTCompilationStats), dedupe_enabled_(true), @@ -616,6 +617,11 @@ void CompilerDriver::PreCompile(jobject class_loader, const std::vectorGetCompiler()->SetHadHardVerifierFailure(); } } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) { CHECK(klass->IsResolved()) << PrettyClass(klass.Get()); @@ -1848,6 +1855,7 @@ static void VerifyClass(const ParallelCompilationManager* manager, size_t class_ // ClassLinker::VerifyClass throws, which isn't useful in the compiler. CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); + manager->GetCompiler()->SetHadHardVerifierFailure(); } CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous()) diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 24b6f177d..f94966733 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -437,6 +437,10 @@ class CompilerDriver { // Get memory usage during compilation. std::string GetMemoryUsageString(bool extended) const; + void SetHadHardVerifierFailure() { + had_hard_verifier_failure_ = true; + } + private: // These flags are internal to CompilerDriver for collecting INVOKE resolution statistics. // The only external contract is that unresolved method has flags 0 and resolved non-0. @@ -575,6 +579,8 @@ class CompilerDriver { // included in the image. std::unique_ptr> classes_to_compile_; + bool had_hard_verifier_failure_; + size_t thread_count_; class AOTCompilationStats; diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index 067e1bd7d..e436f52db 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -38,6 +38,7 @@ CompilerOptions::CompilerOptions() compile_pic_(false), verbose_methods_(nullptr), pass_manager_options_(new PassManagerOptions), + abort_on_hard_verifier_failure_(false), init_failure_output_(nullptr) { } @@ -58,7 +59,8 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter, bool compile_pic, const std::vector* verbose_methods, PassManagerOptions* pass_manager_options, - std::ostream* init_failure_output + std::ostream* init_failure_output, + bool abort_on_hard_verifier_failure ) : // NOLINT(whitespace/parens) compiler_filter_(compiler_filter), huge_method_threshold_(huge_method_threshold), @@ -77,6 +79,7 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter, compile_pic_(compile_pic), verbose_methods_(verbose_methods), pass_manager_options_(pass_manager_options), + abort_on_hard_verifier_failure_(abort_on_hard_verifier_failure), init_failure_output_(init_failure_output) { } diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index fecc600d6..5042c7594 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -70,7 +70,8 @@ class CompilerOptions FINAL { bool compile_pic, const std::vector* verbose_methods, PassManagerOptions* pass_manager_options, - std::ostream* init_failure_output); + std::ostream* init_failure_output, + bool abort_on_hard_verifier_failure); CompilerFilter GetCompilerFilter() const { return compiler_filter_; @@ -183,6 +184,10 @@ class CompilerOptions FINAL { return pass_manager_options_.get(); } + bool AbortOnHardVerifierFailure() const { + return abort_on_hard_verifier_failure_; + } + private: CompilerFilter compiler_filter_; const size_t huge_method_threshold_; @@ -206,6 +211,10 @@ class CompilerOptions FINAL { std::unique_ptr pass_manager_options_; + // Abort compilation with an error if we find a class that fails verification with a hard + // failure. + const bool abort_on_hard_verifier_failure_; + // Log initialization of initialization failures to this stream if not null. std::ostream* const init_failure_output_; diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index ff98d4af2..04efa21f4 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -80,7 +80,8 @@ JitCompiler::JitCompiler() : total_time_(0) { false, // pic nullptr, pass_manager_options, - nullptr)); + nullptr, + false)); const InstructionSet instruction_set = kRuntimeISA; instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines()); cumulative_logger_.reset(new CumulativeLogger("jit times")); diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index c080453de..8572f4d53 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -492,6 +492,7 @@ class Dex2Oat FINAL { bool include_debug_symbols = kIsDebugBuild; bool watch_dog_enabled = true; bool generate_gdb_information = kIsDebugBuild; + bool abort_on_hard_verifier_error = false; PassManagerOptions pass_manager_options; @@ -732,6 +733,8 @@ class Dex2Oat FINAL { if (swap_fd_ < 0) { Usage("--swap-fd passed a negative value %d", swap_fd_); } + } else if (option == "--abort-on-hard-verifier-error") { + abort_on_hard_verifier_error = true; } else { Usage("Unknown argument %s", option.data()); } @@ -941,7 +944,8 @@ class Dex2Oat FINAL { nullptr : &verbose_methods_, new PassManagerOptions(pass_manager_options), - init_failure_output_.get())); + init_failure_output_.get(), + abort_on_hard_verifier_error)); // Done with usage checks, enable watchdog if requested if (watch_dog_enabled) { -- 2.11.0