diff options
Diffstat (limited to 'compiler/dex/verification_results.cc')
-rw-r--r-- | compiler/dex/verification_results.cc | 125 |
1 files changed, 15 insertions, 110 deletions
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 6241ff3c6c..b819d0effa 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -20,97 +20,19 @@ #include "base/mutex-inl.h" #include "base/stl_util.h" -#include "driver/compiler_options.h" #include "runtime.h" #include "thread-current-inl.h" #include "thread.h" -#include "utils/atomic_dex_ref_map-inl.h" -#include "verified_method.h" -#include "verifier/method_verifier-inl.h" namespace art { -VerificationResults::VerificationResults(const CompilerOptions* compiler_options) - : compiler_options_(compiler_options), - verified_methods_lock_("compiler verified methods lock"), +VerificationResults::VerificationResults() + : uncompilable_methods_lock_("compiler uncompilable methods lock"), rejected_classes_lock_("compiler rejected classes lock") {} -VerificationResults::~VerificationResults() { - WriterMutexLock mu(Thread::Current(), verified_methods_lock_); - STLDeleteValues(&verified_methods_); - atomic_verified_methods_.Visit([](const DexFileReference& ref ATTRIBUTE_UNUSED, - const VerifiedMethod* method) { - delete method; - }); -} - -void VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { - DCHECK(method_verifier != nullptr); - MethodReference ref = method_verifier->GetMethodReference(); - std::unique_ptr<const VerifiedMethod> verified_method(VerifiedMethod::Create(method_verifier)); - if (verified_method == nullptr) { - // We'll punt this later. - return; - } - AtomicMap::InsertResult result = atomic_verified_methods_.Insert(ref, - /*expected*/ nullptr, - verified_method.get()); - const VerifiedMethod* existing = nullptr; - bool inserted; - if (result != AtomicMap::kInsertResultInvalidDexFile) { - inserted = (result == AtomicMap::kInsertResultSuccess); - if (!inserted) { - // Rare case. - CHECK(atomic_verified_methods_.Get(ref, &existing)); - CHECK_NE(verified_method.get(), existing); - } - } else { - WriterMutexLock mu(Thread::Current(), verified_methods_lock_); - auto it = verified_methods_.find(ref); - inserted = it == verified_methods_.end(); - if (inserted) { - verified_methods_.Put(ref, verified_method.get()); - DCHECK(verified_methods_.find(ref) != verified_methods_.end()); - } else { - existing = it->second; - } - } - if (inserted) { - // Successfully added, release the unique_ptr since we no longer have ownership. - DCHECK_EQ(GetVerifiedMethod(ref), verified_method.get()); - verified_method.release(); // NOLINT b/117926937 - } else { - // TODO: Investigate why are we doing the work again for this method and try to avoid it. - LOG(WARNING) << "Method processed more than once: " << ref.PrettyMethod(); - // Let the unique_ptr delete the new verified method since there was already an existing one - // registered. It is unsafe to replace the existing one since the JIT may be using it to - // generate a native GC map. - } -} - -const VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) const { - const VerifiedMethod* ret = nullptr; - if (atomic_verified_methods_.Get(ref, &ret)) { - return ret; - } - ReaderMutexLock mu(Thread::Current(), verified_methods_lock_); - auto it = verified_methods_.find(ref); - return (it != verified_methods_.end()) ? it->second : nullptr; -} - -void VerificationResults::CreateVerifiedMethodFor(MethodReference ref) { - // This method should only be called for classes verified at compile time, - // which have no verifier error, nor has methods that we know will throw - // at runtime. - std::unique_ptr<VerifiedMethod> verified_method = std::make_unique<VerifiedMethod>( - /* encountered_error_types= */ 0, /* has_runtime_throw= */ false); - if (atomic_verified_methods_.Insert(ref, - /*expected*/ nullptr, - verified_method.get()) == - AtomicMap::InsertResult::kInsertResultSuccess) { - verified_method.release(); // NOLINT b/117926937 - } -} +// Non-inline version of the destructor, as it does some implicit work not worth +// inlining. +VerificationResults::~VerificationResults() {} void VerificationResults::AddRejectedClass(ClassReference ref) { { @@ -122,38 +44,21 @@ void VerificationResults::AddRejectedClass(ClassReference ref) { bool VerificationResults::IsClassRejected(ClassReference ref) const { ReaderMutexLock mu(Thread::Current(), rejected_classes_lock_); - return (rejected_classes_.find(ref) != rejected_classes_.end()); + return rejected_classes_.find(ref) != rejected_classes_.end(); } -bool VerificationResults::IsCandidateForCompilation(MethodReference&, - const uint32_t access_flags) const { - if (!compiler_options_->IsAotCompilationEnabled()) { - return false; - } - // Don't compile class initializers unless kEverything. - if ((compiler_options_->GetCompilerFilter() != CompilerFilter::kEverything) && - ((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { - return false; +void VerificationResults::AddUncompilableMethod(MethodReference ref) { + { + WriterMutexLock mu(Thread::Current(), uncompilable_methods_lock_); + uncompilable_methods_.insert(ref); } - return true; + DCHECK(IsUncompilableMethod(ref)); } -void VerificationResults::AddDexFile(const DexFile* dex_file) { - atomic_verified_methods_.AddDexFile(dex_file); - WriterMutexLock mu(Thread::Current(), verified_methods_lock_); - // There can be some verified methods that are already registered for the dex_file since we set - // up well known classes earlier. Remove these and put them in the array so that we don't - // accidentally miss seeing them. - for (auto it = verified_methods_.begin(); it != verified_methods_.end(); ) { - MethodReference ref = it->first; - if (ref.dex_file == dex_file) { - CHECK(atomic_verified_methods_.Insert(ref, nullptr, it->second) == - AtomicMap::kInsertResultSuccess); - it = verified_methods_.erase(it); - } else { - ++it; - } - } +bool VerificationResults::IsUncompilableMethod(MethodReference ref) const { + ReaderMutexLock mu(Thread::Current(), uncompilable_methods_lock_); + return uncompilable_methods_.find(ref) != uncompilable_methods_.end(); } + } // namespace art |