summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/driver/compiler_driver.cc22
-rw-r--r--compiler/verifier_deps_test.cc23
2 files changed, 38 insertions, 7 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a5e4cb0877..057e3c9960 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -535,9 +535,8 @@ static optimizer::DexToDexCompilationLevel GetDexToDexCompilationLevel(
if (klass->IsVerified()) {
// Class is verified so we can enable DEX-to-DEX compilation for performance.
return max_level;
- } else if (klass->IsCompileTimeVerified()) {
+ } else if (klass->ShouldVerifyAtRuntime()) {
// Class verification has soft-failed. Anyway, ensure at least correctness.
- DCHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime);
return optimizer::DexToDexCompilationLevel::kRequired;
} else {
// Class verification has failed: do not run DEX-to-DEX compilation.
@@ -964,7 +963,7 @@ static void EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader,
if (cls == nullptr) {
soa.Self()->ClearException();
} else if (&cls->GetDexFile() == dex_file) {
- DCHECK(cls->IsErroneous() || cls->IsVerified() || cls->IsCompileTimeVerified())
+ DCHECK(cls->IsErroneous() || cls->IsVerified() || cls->ShouldVerifyAtRuntime())
<< cls->PrettyClass()
<< " " << cls->GetStatus();
}
@@ -2160,6 +2159,14 @@ class VerifyClassVisitor : public CompilationVisitor {
LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
<< " because: " << error_msg;
manager_->GetCompiler()->SetHadHardVerifierFailure();
+ } else {
+ // Force a soft failure for the VerifierDeps. This is a sanity measure, as
+ // the vdex file already records that the class hasn't been resolved. It avoids
+ // trying to do future verification optimizations when processing the vdex file.
+ DCHECK(failure_kind == verifier::MethodVerifier::kSoftFailure ||
+ failure_kind == verifier::MethodVerifier::kNoFailure)
+ << failure_kind;
+ failure_kind = verifier::MethodVerifier::kSoftFailure;
}
} else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
CHECK(klass->IsResolved()) << klass->PrettyClass();
@@ -2172,7 +2179,7 @@ class VerifyClassVisitor : public CompilationVisitor {
manager_->GetCompiler()->SetHadHardVerifierFailure();
}
- CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
+ CHECK(klass->ShouldVerifyAtRuntime() || klass->IsVerified() || klass->IsErroneous())
<< klass->PrettyDescriptor() << ": state=" << klass->GetStatus();
// It is *very* problematic if there are verification errors in the boot classpath. For example,
@@ -2186,6 +2193,13 @@ class VerifyClassVisitor : public CompilationVisitor {
DCHECK(klass->IsVerified()) << "Boot classpath class " << klass->PrettyClass()
<< " failed to fully verify: state= " << klass->GetStatus();
}
+ if (klass->IsVerified()) {
+ DCHECK_EQ(failure_kind, verifier::MethodVerifier::kNoFailure);
+ } else if (klass->ShouldVerifyAtRuntime()) {
+ DCHECK_EQ(failure_kind, verifier::MethodVerifier::kSoftFailure);
+ } else {
+ DCHECK_EQ(failure_kind, verifier::MethodVerifier::kHardFailure);
+ }
}
} else {
// Make the skip a soft failure, essentially being considered as verify at runtime.
diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc
index c892b25ed3..01c33591e5 100644
--- a/compiler/verifier_deps_test.cc
+++ b/compiler/verifier_deps_test.cc
@@ -246,9 +246,13 @@ class VerifierDepsTest : public CommonCompilerTest {
}
bool HasUnverifiedClass(const std::string& cls) {
- const DexFile::TypeId* type_id = primary_dex_file_->FindTypeId(cls.c_str());
+ return HasUnverifiedClass(cls, *primary_dex_file_);
+ }
+
+ bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
+ const DexFile::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
DCHECK(type_id != nullptr);
- dex::TypeIndex index = primary_dex_file_->GetIndexForTypeId(*type_id);
+ dex::TypeIndex index = dex_file.GetIndexForTypeId(*type_id);
for (const auto& dex_dep : verifier_deps_->dex_deps_) {
for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) {
if (index == entry) {
@@ -1141,7 +1145,7 @@ TEST_F(VerifierDepsTest, UnverifiedClasses) {
// Test that a class with hard failure is recorded.
ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
// Test that a class with unresolved super is recorded.
- ASSERT_FALSE(HasUnverifiedClass("LMyClassWithNoSuper;"));
+ ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuper;"));
// Test that a class with unresolved super and hard failure is recorded.
ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
}
@@ -1511,5 +1515,18 @@ TEST_F(VerifierDepsTest, CompilerDriver) {
}
}
+TEST_F(VerifierDepsTest, MultiDexVerification) {
+ VerifyDexFile("VerifierDepsMulti");
+ ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
+
+ ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
+ ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
+ ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
+
+ std::vector<uint8_t> buffer;
+ verifier_deps_->Encode(dex_files_, &buffer);
+ ASSERT_FALSE(buffer.empty());
+}
+
} // namespace verifier
} // namespace art