diff options
author | Andreas Gampe <agampe@google.com> | 2015-03-05 13:08:45 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-03-05 18:42:21 -0800 |
commit | 6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d (patch) | |
tree | 126d4a09078ebfb6b5eed5d67d6300217132a1bb | |
parent | 66b26662ad0c52c648c9b5ea4a99149091e842b4 (diff) | |
download | art-6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d.zip art-6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d.tar.gz art-6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d.tar.bz2 |
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
-rw-r--r-- | compiler/driver/compiler_driver.cc | 8 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 6 | ||||
-rw-r--r-- | compiler/driver/compiler_options.cc | 5 | ||||
-rw-r--r-- | compiler/driver/compiler_options.h | 11 | ||||
-rw-r--r-- | compiler/jit/jit_compiler.cc | 3 | ||||
-rw-r--r-- | 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 a52a83a..df2b520 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::vector<const De Verify(class_loader, dex_files, thread_pool, timings); VLOG(compiler) << "Verify: " << GetMemoryUsageString(false); + if (had_hard_verifier_failure_ && GetCompilerOptions().AbortOnHardVerifierFailure()) { + LOG(FATAL) << "Had a hard failure verifying all classes, and was asked to abort in such " + << "situations. Please check the log."; + } + InitializeClasses(class_loader, dex_files, thread_pool, timings); VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false); @@ -1839,6 +1845,7 @@ static void VerifyClass(const ParallelCompilationManager* manager, size_t class_ verifier::MethodVerifier::kHardFailure) { LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor) << " because: " << error_msg; + manager->GetCompiler()->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 24b6f17..f949667 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<std::set<std::string>> 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 067e1bd..e436f52 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<std::string>* 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 fecc600..5042c75 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<std::string>* 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<PassManagerOptions> 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 ff98d4a..04efa21 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 c080453..8572f4d 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) { |