summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-03-05 13:08:45 -0800
committerAndreas Gampe <agampe@google.com>2015-03-05 18:42:21 -0800
commit6cf49e57ad7a61e1fffd5b1dfae9179c3ca5703d (patch)
tree126d4a09078ebfb6b5eed5d67d6300217132a1bb
parent66b26662ad0c52c648c9b5ea4a99149091e842b4 (diff)
downloadart-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.cc8
-rw-r--r--compiler/driver/compiler_driver.h6
-rw-r--r--compiler/driver/compiler_options.cc5
-rw-r--r--compiler/driver/compiler_options.h11
-rw-r--r--compiler/jit/jit_compiler.cc3
-rw-r--r--dex2oat/dex2oat.cc6
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) {