summaryrefslogtreecommitdiff
path: root/compiler/dex/verification_results.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/verification_results.cc')
-rw-r--r--compiler/dex/verification_results.cc125
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