diff options
-rw-r--r-- | compiler/dex/quick_compiler_callbacks.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick_compiler_callbacks.h | 2 | ||||
-rw-r--r-- | compiler/dex/verification_results.cc | 9 | ||||
-rw-r--r-- | compiler/dex/verification_results.h | 2 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 1 | ||||
-rw-r--r-- | runtime/class_linker.cc | 6 | ||||
-rw-r--r-- | runtime/compiler_callbacks.h | 4 | ||||
-rw-r--r-- | runtime/noop_compiler_callbacks.h | 3 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 50 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.h | 59 | ||||
-rw-r--r-- | runtime/verifier/method_verifier_test.cc | 4 |
11 files changed, 99 insertions, 53 deletions
diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc index 03bda78498..2532bda632 100644 --- a/compiler/dex/quick_compiler_callbacks.cc +++ b/compiler/dex/quick_compiler_callbacks.cc @@ -22,14 +22,10 @@ namespace art { -bool QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { - bool result = verification_results_->ProcessVerifiedMethod(verifier); - if (result) { - MethodReference ref = verifier->GetMethodReference(); - method_inliner_map_->GetMethodInliner(ref.dex_file) - ->AnalyseMethodCode(verifier); - } - return result; +void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { + verification_results_->ProcessVerifiedMethod(verifier); + MethodReference ref = verifier->GetMethodReference(); + method_inliner_map_->GetMethodInliner(ref.dex_file)->AnalyseMethodCode(verifier); } void QuickCompilerCallbacks::ClassRejected(ClassReference ref) { diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h index 03bf57bded..4f5ea766d8 100644 --- a/compiler/dex/quick_compiler_callbacks.h +++ b/compiler/dex/quick_compiler_callbacks.h @@ -37,7 +37,7 @@ class QuickCompilerCallbacks FINAL : public CompilerCallbacks { ~QuickCompilerCallbacks() { } - bool MethodVerified(verifier::MethodVerifier* verifier) + void MethodVerified(verifier::MethodVerifier* verifier) SHARED_REQUIRES(Locks::mutator_lock_) OVERRIDE; void ClassRejected(ClassReference ref) OVERRIDE; diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 65b0ad6400..dd24220e0e 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -44,14 +44,14 @@ VerificationResults::~VerificationResults() { } } -bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { +void VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { DCHECK(method_verifier != nullptr); MethodReference ref = method_verifier->GetMethodReference(); bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); if (verified_method == nullptr) { - // Do not report an error to the verifier. We'll just punt this later. - return true; + // We'll punt this later. + return; } WriterMutexLock mu(Thread::Current(), verified_methods_lock_); @@ -69,11 +69,10 @@ bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method // is unsafe to replace the existing one since the JIT may be using it to generate a // native GC map. delete verified_method; - return true; + return; } verified_methods_.Put(ref, verified_method); DCHECK(verified_methods_.find(ref) != verified_methods_.end()); - return true; } const VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) { diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h index 9934f6b13b..da80bf07db 100644 --- a/compiler/dex/verification_results.h +++ b/compiler/dex/verification_results.h @@ -42,7 +42,7 @@ class VerificationResults { explicit VerificationResults(const CompilerOptions* compiler_options); ~VerificationResults(); - bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) + void ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!verified_methods_lock_); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index a05105b84e..82af541765 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2037,6 +2037,7 @@ class VerifyClassVisitor : public CompilationVisitor { dex_cache, class_loader, &class_def, + Runtime::Current()->GetCompilerCallbacks(), true /* allow soft failures */, true /* log hard failures */, &error_msg) == diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 0a37f26135..f5085ed417 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -3056,10 +3056,12 @@ void ClassLinker::VerifyClass(Thread* self, Handle<mirror::Class> klass) { verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure; std::string error_msg; if (!preverified) { + Runtime* runtime = Runtime::Current(); verifier_failure = verifier::MethodVerifier::VerifyClass(self, klass.Get(), - Runtime::Current()->IsAotCompiler(), - Runtime::Current()->IsAotCompiler(), + runtime->GetCompilerCallbacks(), + runtime->IsAotCompiler(), + runtime->IsAotCompiler(), &error_msg); } if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) { diff --git a/runtime/compiler_callbacks.h b/runtime/compiler_callbacks.h index af7b04f62e..a39d6822aa 100644 --- a/runtime/compiler_callbacks.h +++ b/runtime/compiler_callbacks.h @@ -37,8 +37,8 @@ class CompilerCallbacks { virtual ~CompilerCallbacks() { } - virtual bool MethodVerified(verifier::MethodVerifier* verifier) - SHARED_REQUIRES(Locks::mutator_lock_) = 0; + virtual void MethodVerified(verifier::MethodVerifier* verifier) + SHARED_REQUIRES(Locks::mutator_lock_) = 0; virtual void ClassRejected(ClassReference ref) = 0; // Return true if we should attempt to relocate to a random base address if we have not already diff --git a/runtime/noop_compiler_callbacks.h b/runtime/noop_compiler_callbacks.h index 1cbf2bbda4..02081cbb60 100644 --- a/runtime/noop_compiler_callbacks.h +++ b/runtime/noop_compiler_callbacks.h @@ -26,8 +26,7 @@ class NoopCompilerCallbacks FINAL : public CompilerCallbacks { NoopCompilerCallbacks() : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp) {} ~NoopCompilerCallbacks() {} - bool MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE { - return true; + void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE { } void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) OVERRIDE {} diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index cf27ff2f60..3b0d7c4a03 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -116,6 +116,7 @@ static void SafelyMarkAllRegistersAsConflicts(MethodVerifier* verifier, Register MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, mirror::Class* klass, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, std::string* error) { @@ -140,9 +141,9 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, } if (early_failure) { *error = "Verifier rejected class " + PrettyDescriptor(klass) + failure_message; - if (Runtime::Current()->IsAotCompiler()) { + if (callbacks != nullptr) { ClassReference ref(&dex_file, klass->GetDexClassDefIndex()); - Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref); + callbacks->ClassRejected(ref); } return kHardFailure; } @@ -154,6 +155,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, dex_cache, class_loader, class_def, + callbacks, allow_soft_failures, log_hard_failures, error); @@ -172,6 +174,7 @@ void MethodVerifier::VerifyMethods(Thread* self, ClassDataItemIterator* it, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, bool need_precise_constants, @@ -212,6 +215,7 @@ void MethodVerifier::VerifyMethods(Thread* self, it->GetMethodCodeItem(), method, it->GetMethodAccessFlags(), + callbacks, allow_soft_failures, log_hard_failures, need_precise_constants, @@ -241,6 +245,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, std::string* error) { @@ -274,6 +279,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, &it, dex_cache, class_loader, + callbacks, allow_soft_failures, log_hard_failures, false /* need precise constants */, @@ -288,6 +294,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(Thread* self, &it, dex_cache, class_loader, + callbacks, allow_soft_failures, log_hard_failures, false /* need precise constants */, @@ -322,6 +329,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(Thread* self, const DexFile::CodeItem* code_item, ArtMethod* method, uint32_t method_access_flags, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, bool need_precise_constants, @@ -336,6 +344,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(Thread* self, // Verification completed, however failures may be pending that didn't cause the verification // to hard fail. CHECK(!verifier.have_pending_hard_failure_); + + if (code_item != nullptr && callbacks != nullptr) { + // Let the interested party know that the method was verified. + callbacks->MethodVerified(&verifier); + } + if (verifier.failures_.size() != 0) { if (VLOG_IS_ON(verifier)) { verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in " @@ -363,8 +377,14 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(Thread* self, verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str(); } result = kHardFailure; + + if (callbacks != nullptr) { + // Let the interested party know that we failed the class. + ClassReference ref(dex_file, dex_file->GetIndexForClassDef(*class_def)); + callbacks->ClassRejected(ref); + } } - if (kDebugVerify) { + if (VLOG_IS_ON(verifier)) { std::cout << "\n" << verifier.info_messages_.str(); verifier.Dump(std::cout); } @@ -408,13 +428,18 @@ MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self, } MethodVerifier::MethodVerifier(Thread* self, - const DexFile* dex_file, Handle<mirror::DexCache> dex_cache, + const DexFile* dex_file, + Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, - const DexFile::CodeItem* code_item, uint32_t dex_method_idx, - ArtMethod* method, uint32_t method_access_flags, - bool can_load_classes, bool allow_soft_failures, - bool need_precise_constants, bool verify_to_dump, + const DexFile::CodeItem* code_item, + uint32_t dex_method_idx, + ArtMethod* method, + uint32_t method_access_flags, + bool can_load_classes, + bool allow_soft_failures, + bool need_precise_constants, + bool verify_to_dump, bool allow_thread_suspension) : self_(self), arena_stack_(Runtime::Current()->GetArenaPool()), @@ -739,10 +764,7 @@ bool MethodVerifier::Verify() { result = result && VerifyInstructions(); // Perform code-flow analysis and return. result = result && VerifyCodeFlow(); - // Compute information for compiler. - if (result && runtime->IsCompiler()) { - result = runtime->GetCompilerCallbacks()->MethodVerified(this); - } + return result; } @@ -802,10 +824,6 @@ std::ostream& MethodVerifier::Fail(VerifyError error) { // Hard verification failures at compile time will still fail at runtime, so the class is // marked as rejected to prevent it from being compiled. case VERIFY_ERROR_BAD_CLASS_HARD: { - if (Runtime::Current()->IsAotCompiler()) { - ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_)); - Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref); - } have_pending_hard_failure_ = true; if (VLOG_IS_ON(verifier) && kDumpRegLinesOnHardFailureIfVLOG) { ScopedObjectAccess soa(Thread::Current()); diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index 719f0d7d40..79db576993 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -33,6 +33,7 @@ namespace art { +class CompilerCallbacks; class Instruction; struct ReferenceMap2Visitor; class Thread; @@ -141,6 +142,7 @@ class MethodVerifier { /* Verify a class. Returns "kNoFailure" on success. */ static FailureKind VerifyClass(Thread* self, mirror::Class* klass, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, std::string* error) @@ -150,6 +152,7 @@ class MethodVerifier { Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, std::string* error) @@ -216,16 +219,34 @@ class MethodVerifier { return can_load_classes_; } - MethodVerifier(Thread* self, const DexFile* dex_file, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, - const DexFile::CodeItem* code_item, uint32_t method_idx, + MethodVerifier(Thread* self, + const DexFile* dex_file, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, + const DexFile::ClassDef* class_def, + const DexFile::CodeItem* code_item, + uint32_t method_idx, ArtMethod* method, - uint32_t access_flags, bool can_load_classes, bool allow_soft_failures, - bool need_precise_constants, bool allow_thread_suspension) + uint32_t access_flags, + bool can_load_classes, + bool allow_soft_failures, + bool need_precise_constants, + bool allow_thread_suspension) SHARED_REQUIRES(Locks::mutator_lock_) - : MethodVerifier(self, dex_file, dex_cache, class_loader, class_def, code_item, method_idx, - method, access_flags, can_load_classes, allow_soft_failures, - need_precise_constants, false, allow_thread_suspension) {} + : MethodVerifier(self, + dex_file, + dex_cache, + class_loader, + class_def, + code_item, + method_idx, + method, + access_flags, + can_load_classes, + allow_soft_failures, + need_precise_constants, + false, + allow_thread_suspension) {} ~MethodVerifier(); @@ -299,12 +320,20 @@ class MethodVerifier { } // Private constructor for dumping. - MethodVerifier(Thread* self, const DexFile* dex_file, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, - const DexFile::CodeItem* code_item, uint32_t method_idx, - ArtMethod* method, uint32_t access_flags, - bool can_load_classes, bool allow_soft_failures, bool need_precise_constants, - bool verify_to_dump, bool allow_thread_suspension) + MethodVerifier(Thread* self, + const DexFile* dex_file, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, + const DexFile::ClassDef* class_def, + const DexFile::CodeItem* code_item, + uint32_t method_idx, + ArtMethod* method, + uint32_t access_flags, + bool can_load_classes, + bool allow_soft_failures, + bool need_precise_constants, + bool verify_to_dump, + bool allow_thread_suspension) SHARED_REQUIRES(Locks::mutator_lock_); // Adds the given string to the beginning of the last failure message. @@ -323,6 +352,7 @@ class MethodVerifier { ClassDataItemIterator* it, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, bool need_precise_constants, @@ -350,6 +380,7 @@ class MethodVerifier { const DexFile::CodeItem* code_item, ArtMethod* method, uint32_t method_access_flags, + CompilerCallbacks* callbacks, bool allow_soft_failures, bool log_hard_failures, bool need_precise_constants, diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc index c4123d5f52..946f842fd0 100644 --- a/runtime/verifier/method_verifier_test.cc +++ b/runtime/verifier/method_verifier_test.cc @@ -37,8 +37,8 @@ class MethodVerifierTest : public CommonRuntimeTest { // Verify the class std::string error_msg; - ASSERT_TRUE(MethodVerifier::VerifyClass(self, klass, true, true, &error_msg) == MethodVerifier::kNoFailure) - << error_msg; + ASSERT_TRUE(MethodVerifier::VerifyClass(self, klass, nullptr, true, true, &error_msg) + == MethodVerifier::kNoFailure) << error_msg; } void VerifyDexFile(const DexFile& dex) |