diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 22 | ||||
| -rw-r--r-- | compiler/verifier_deps_test.cc | 23 |
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 |