summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2021-07-14 14:59:25 +0100
committerNicolas Geoffray <ngeoffray@google.com>2021-07-14 17:13:08 +0000
commit9e050ab1a061d9660eb0c1daa01a823ad75b0f05 (patch)
tree714f2ba3b11406310416e85357f45450634846b2
parent4f990714b13e0b4446305a5411648a1a9ae42a7a (diff)
downloadart-android-s-beta-4.tar.gz
Remove the need of VerifiedMethod in the compiler.android-s-beta-4android-s-beta-3android-s-beta-4
The compiler only needs to know if a method is compilable or not. So just record a set of uncompilable methods (in some cases, we cannot have an ArtMethod, but the method can still be compiled). Test: test.py Bug: 28313047 Change-Id: Ic4235bc8160ec91daa5ebf6504741089b43e99cb
-rw-r--r--compiler/Android.bp1
-rw-r--r--compiler/common_compiler_test.cc6
-rw-r--r--compiler/dex/verification_results.cc125
-rw-r--r--compiler/dex/verification_results.h40
-rw-r--r--compiler/dex/verified_method.cc49
-rw-r--r--compiler/dex/verified_method.h61
-rw-r--r--compiler/driver/compiler_options.cc32
-rw-r--r--compiler/driver/compiler_options.h9
-rw-r--r--compiler/optimizing/builder.cc1
-rw-r--r--compiler/optimizing/code_generator.cc1
-rw-r--r--compiler/optimizing/inliner.cc19
-rw-r--r--compiler/optimizing/optimizing_compiler.cc163
-rw-r--r--compiler/optimizing/optimizing_compiler_stats.h2
-rw-r--r--dex2oat/common_compiler_driver_test.cc3
-rw-r--r--dex2oat/dex/quick_compiler_callbacks.cc4
-rw-r--r--dex2oat/dex/quick_compiler_callbacks.h3
-rw-r--r--dex2oat/dex2oat.cc21
-rw-r--r--dex2oat/driver/compiler_driver.cc42
-rw-r--r--dex2oat/driver/compiler_driver.h9
-rw-r--r--dex2oat/verifier_deps_test.cc16
-rw-r--r--runtime/compiler_callbacks.h5
-rw-r--r--runtime/noop_compiler_callbacks.h4
-rw-r--r--runtime/verifier/class_verifier.cc14
-rw-r--r--runtime/verifier/method_verifier.cc15
-rw-r--r--runtime/verifier/method_verifier.h4
25 files changed, 133 insertions, 516 deletions
diff --git a/compiler/Android.bp b/compiler/Android.bp
index 6b74f77b73..e579e36a72 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -36,7 +36,6 @@ art_cc_defaults {
"compiled_method.cc",
"debug/elf_debug_writer.cc",
"dex/inline_method_analyser.cc",
- "dex/verified_method.cc",
"dex/verification_results.cc",
"driver/compiled_method_storage.cc",
"driver/compiler_options.cc",
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 9170a8555a..1b69f2a1d4 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -209,8 +209,7 @@ void CommonCompilerTestImpl::OverrideInstructionSetFeatures(InstructionSet instr
void CommonCompilerTestImpl::SetUpRuntimeOptionsImpl() {
compiler_options_.reset(new CompilerOptions);
- verification_results_.reset(new VerificationResults(compiler_options_.get()));
-
+ verification_results_.reset(new VerificationResults());
ApplyInstructionSet();
}
@@ -251,9 +250,6 @@ void CommonCompilerTestImpl::CompileMethod(ArtMethod* method) {
dex_file,
dex_cache);
} else {
- verification_results_->AddDexFile(&dex_file);
- verification_results_->CreateVerifiedMethodFor(
- MethodReference(&dex_file, method->GetDexMethodIndex()));
compiled_method = compiler->Compile(method->GetCodeItem(),
method->GetAccessFlags(),
method->GetInvokeType(),
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
diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h
index 04c4fa65e6..b294ed3020 100644
--- a/compiler/dex/verification_results.h
+++ b/compiler/dex/verification_results.h
@@ -17,65 +17,35 @@
#ifndef ART_COMPILER_DEX_VERIFICATION_RESULTS_H_
#define ART_COMPILER_DEX_VERIFICATION_RESULTS_H_
-#include <stdint.h>
#include <set>
-#include "base/dchecked_vector.h"
#include "base/macros.h"
#include "base/mutex.h"
-#include "base/safe_map.h"
#include "dex/class_reference.h"
#include "dex/method_reference.h"
-#include "utils/atomic_dex_ref_map.h"
namespace art {
namespace verifier {
-class MethodVerifier;
class VerifierDepsTest;
} // namespace verifier
-class CompilerOptions;
-class VerifiedMethod;
-
// Used by CompilerCallbacks to track verification information from the Runtime.
class VerificationResults {
public:
- explicit VerificationResults(const CompilerOptions* compiler_options);
+ VerificationResults();
~VerificationResults();
- void ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!verified_methods_lock_);
-
- void CreateVerifiedMethodFor(MethodReference ref)
- REQUIRES(!verified_methods_lock_);
-
- const VerifiedMethod* GetVerifiedMethod(MethodReference ref) const
- REQUIRES(!verified_methods_lock_);
-
void AddRejectedClass(ClassReference ref) REQUIRES(!rejected_classes_lock_);
bool IsClassRejected(ClassReference ref) const REQUIRES(!rejected_classes_lock_);
- bool IsCandidateForCompilation(MethodReference& method_ref, const uint32_t access_flags) const;
-
- // Add a dex file to enable using the atomic map.
- void AddDexFile(const DexFile* dex_file) REQUIRES(!verified_methods_lock_);
+ void AddUncompilableMethod(MethodReference ref) REQUIRES(!uncompilable_methods_lock_);
+ bool IsUncompilableMethod(MethodReference ref) const REQUIRES(!uncompilable_methods_lock_);
private:
- // Verified methods. The method array is fixed to avoid needing a lock to extend it.
- using AtomicMap = AtomicDexRefMap<MethodReference, const VerifiedMethod*>;
- using VerifiedMethodMap = SafeMap<MethodReference, const VerifiedMethod*>;
-
- VerifiedMethodMap verified_methods_ GUARDED_BY(verified_methods_lock_);
- const CompilerOptions* const compiler_options_;
-
- // Dex2oat can add dex files to atomic_verified_methods_ to avoid locking when calling
- // GetVerifiedMethod.
- AtomicMap atomic_verified_methods_;
-
// TODO: External locking during CompilerDriver::PreCompile(), no locking during compilation.
- mutable ReaderWriterMutex verified_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ mutable ReaderWriterMutex uncompilable_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ std::set<MethodReference> uncompilable_methods_ GUARDED_BY(uncompilable_methods_lock_);
// Rejected classes.
// TODO: External locking during CompilerDriver::PreCompile(), no locking during compilation.
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
deleted file mode 100644
index 04f7215015..0000000000
--- a/compiler/dex/verified_method.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "verified_method.h"
-
-#include <algorithm>
-#include <memory>
-
-#include <android-base/logging.h>
-
-#include "dex/code_item_accessors-inl.h"
-#include "dex/dex_file.h"
-#include "dex/dex_instruction-inl.h"
-#include "runtime.h"
-#include "verifier/method_verifier-inl.h"
-#include "verifier/reg_type-inl.h"
-#include "verifier/register_line-inl.h"
-#include "verifier/verifier_deps.h"
-
-namespace art {
-
-VerifiedMethod::VerifiedMethod(uint32_t encountered_error_types, bool has_runtime_throw)
- : encountered_error_types_(encountered_error_types),
- has_runtime_throw_(has_runtime_throw) {
-}
-
-const VerifiedMethod* VerifiedMethod::Create(verifier::MethodVerifier* method_verifier) {
- DCHECK(Runtime::Current()->IsAotCompiler());
- std::unique_ptr<VerifiedMethod> verified_method(
- new VerifiedMethod(method_verifier->GetEncounteredFailureTypes(),
- method_verifier->HasInstructionThatWillThrow()));
-
- return verified_method.release();
-}
-
-} // namespace art
diff --git a/compiler/dex/verified_method.h b/compiler/dex/verified_method.h
deleted file mode 100644
index f100f78fb0..0000000000
--- a/compiler/dex/verified_method.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_COMPILER_DEX_VERIFIED_METHOD_H_
-#define ART_COMPILER_DEX_VERIFIED_METHOD_H_
-
-#include <vector>
-
-#include "base/mutex.h"
-#include "base/safe_map.h"
-#include "dex/dex_file.h"
-#include "dex/method_reference.h"
-
-namespace art {
-
-namespace verifier {
-class MethodVerifier;
-} // namespace verifier
-
-class VerifiedMethod {
- public:
- VerifiedMethod(uint32_t encountered_error_types, bool has_runtime_throw);
-
- static const VerifiedMethod* Create(verifier::MethodVerifier* method_verifier)
- REQUIRES_SHARED(Locks::mutator_lock_);
- ~VerifiedMethod() = default;
-
- // Returns true if there were any errors during verification.
- bool HasVerificationFailures() const {
- return encountered_error_types_ != 0;
- }
-
- uint32_t GetEncounteredVerificationFailures() const {
- return encountered_error_types_;
- }
-
- bool HasRuntimeThrow() const {
- return has_runtime_throw_;
- }
-
- private:
- const uint32_t encountered_error_types_;
- const bool has_runtime_throw_;
-};
-
-} // namespace art
-
-#endif // ART_COMPILER_DEX_VERIFIED_METHOD_H_
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index a5805f953b..ad5a009808 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -31,7 +31,6 @@
#include "compiler_options_map-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/verification_results.h"
-#include "dex/verified_method.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "simple_compiler_options_map.h"
@@ -156,35 +155,4 @@ const VerificationResults* CompilerOptions::GetVerificationResults() const {
return verification_results_;
}
-const VerifiedMethod* CompilerOptions::GetVerifiedMethod(const DexFile* dex_file,
- uint32_t method_idx) const {
- MethodReference ref(dex_file, method_idx);
- return verification_results_->GetVerifiedMethod(ref);
-}
-
-bool CompilerOptions::IsMethodVerifiedWithoutFailures(uint32_t method_idx,
- uint16_t class_def_idx,
- const DexFile& dex_file) const {
- const VerifiedMethod* verified_method = GetVerifiedMethod(&dex_file, method_idx);
- if (verified_method != nullptr) {
- return !verified_method->HasVerificationFailures();
- }
-
- // If we can't find verification metadata, check if this is a system class (we trust that system
- // classes have their methods verified). If it's not, be conservative and assume the method
- // has not been verified successfully.
-
- // TODO: When compiling the boot image it should be safe to assume that everything is verified,
- // even if methods are not found in the verification cache.
- const char* descriptor = dex_file.GetClassDescriptor(dex_file.GetClassDef(class_def_idx));
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Thread* self = Thread::Current();
- ScopedObjectAccess soa(self);
- bool is_system_class = class_linker->FindSystemClass(self, descriptor) != nullptr;
- if (!is_system_class) {
- self->ClearException();
- }
- return is_system_class;
-}
-
} // namespace art
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index da75d3741a..db17bda7ac 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -48,7 +48,6 @@ enum class InstructionSet;
class InstructionSetFeatures;
class ProfileCompilationInfo;
class VerificationResults;
-class VerifiedMethod;
// Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared.
enum class ProfileMethodsCheck : uint8_t {
@@ -298,14 +297,6 @@ class CompilerOptions final {
const VerificationResults* GetVerificationResults() const;
- const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
-
- // Checks if the specified method has been verified without failures. Returns
- // false if the method is not in the verification results (GetVerificationResults).
- bool IsMethodVerifiedWithoutFailures(uint32_t method_idx,
- uint16_t class_def_idx,
- const DexFile& dex_file) const;
-
bool ParseCompilerOptions(const std::vector<std::string>& options,
bool ignore_unrecognized,
std::string* error_msg);
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 3263e9ca3a..e7826bbba3 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -23,7 +23,6 @@
#include "block_builder.h"
#include "code_generator.h"
#include "data_type-inl.h"
-#include "dex/verified_method.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
#include "instruction_builder.h"
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index a096338ee2..ca35d99f24 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -42,7 +42,6 @@
#include "compiled_method.h"
#include "dex/bytecode_utils.h"
#include "dex/code_item_accessors-inl.h"
-#include "dex/verified_method.h"
#include "graph_visualizer.h"
#include "image.h"
#include "gc/space/image_space.h"
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 664126a54d..74eae430ad 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -26,8 +26,6 @@
#include "data_type-inl.h"
#include "dead_code_elimination.h"
#include "dex/inline_method_analyser.h"
-#include "dex/verification_results.h"
-#include "dex/verified_method.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
#include "instruction_simplifier.h"
@@ -388,24 +386,9 @@ static bool IsMethodUnverified(const CompilerOptions& compiler_options, ArtMetho
// We're at runtime, we know this is cold code if the class
// is not verified, so don't bother analyzing.
return true;
- }
- uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex();
-
- const VerifiedMethod* verified_method =
- compiler_options.GetVerifiedMethod(method->GetDexFile(), method->GetDexMethodIndex());
- if (verified_method != nullptr && verified_method->HasRuntimeThrow()) {
- // Compiler doesn't handle dead code as nicely as verifier.
+ } else if (!method->GetDeclaringClass()->IsVerifiedNeedsAccessChecks()) {
return true;
}
- if (!compiler_options.IsMethodVerifiedWithoutFailures(method->GetDexMethodIndex(),
- class_def_idx,
- *method->GetDexFile())) {
- if (verified_method == nullptr ||
- !verifier::CanCompilerHandleVerificationFailure(
- verified_method->GetEncounteredVerificationFailures())) {
- return true;
- }
- }
}
return false;
}
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index b6ab9fb1b5..16abf9d37d 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -38,8 +38,6 @@
#include "debug/elf_debug_writer.h"
#include "debug/method_debug_info.h"
#include "dex/dex_file_types.h"
-#include "dex/verification_results.h"
-#include "dex/verified_method.h"
#include "driver/compiled_method_storage.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
@@ -63,7 +61,6 @@
#include "ssa_phi_elimination.h"
#include "stack_map_stream.h"
#include "utils/assembler.h"
-#include "verifier/verifier_compiler_binding.h"
namespace art {
@@ -1017,98 +1014,84 @@ CompiledMethod* OptimizingCompiler::Compile(const dex::CodeItem* code_item,
CompiledMethod* compiled_method = nullptr;
Runtime* runtime = Runtime::Current();
DCHECK(runtime->IsAotCompiler());
- const VerifiedMethod* verified_method = compiler_options.GetVerifiedMethod(&dex_file, method_idx);
- DCHECK(!verified_method->HasRuntimeThrow());
- if (compiler_options.IsMethodVerifiedWithoutFailures(method_idx, class_def_idx, dex_file) ||
- verifier::CanCompilerHandleVerificationFailure(
- verified_method->GetEncounteredVerificationFailures())) {
- ArenaAllocator allocator(runtime->GetArenaPool());
- ArenaStack arena_stack(runtime->GetArenaPool());
- CodeVectorAllocator code_allocator(&allocator);
- std::unique_ptr<CodeGenerator> codegen;
- bool compiled_intrinsic = false;
- {
- ScopedObjectAccess soa(Thread::Current());
- ArtMethod* method =
- runtime->GetClassLinker()->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
- method_idx, dex_cache, jclass_loader, /*referrer=*/ nullptr, invoke_type);
- DCHECK_EQ(method == nullptr, soa.Self()->IsExceptionPending());
- soa.Self()->ClearException(); // Suppress exception if any.
- VariableSizedHandleScope handles(soa.Self());
- Handle<mirror::Class> compiling_class =
- handles.NewHandle(method != nullptr ? method->GetDeclaringClass() : nullptr);
- DexCompilationUnit dex_compilation_unit(
- jclass_loader,
- runtime->GetClassLinker(),
- dex_file,
- code_item,
- class_def_idx,
- method_idx,
- access_flags,
- /*verified_method=*/ nullptr, // Not needed by the Optimizing compiler.
- dex_cache,
- compiling_class);
- // All signature polymorphic methods are native.
- DCHECK(method == nullptr || !method->IsSignaturePolymorphic());
- // Go to native so that we don't block GC during compilation.
- ScopedThreadSuspension sts(soa.Self(), kNative);
- // Try to compile a fully intrinsified implementation.
- if (method != nullptr && UNLIKELY(method->IsIntrinsic())) {
- DCHECK(compiler_options.IsBootImage());
- codegen.reset(
- TryCompileIntrinsic(&allocator,
- &arena_stack,
- &code_allocator,
- dex_compilation_unit,
- method,
- &handles));
- if (codegen != nullptr) {
- compiled_intrinsic = true;
- }
- }
- if (codegen == nullptr) {
- codegen.reset(
- TryCompile(&allocator,
- &arena_stack,
- &code_allocator,
- dex_compilation_unit,
- method,
- compiler_options.IsBaseline()
- ? CompilationKind::kBaseline
- : CompilationKind::kOptimized,
- &handles));
+ ArenaAllocator allocator(runtime->GetArenaPool());
+ ArenaStack arena_stack(runtime->GetArenaPool());
+ CodeVectorAllocator code_allocator(&allocator);
+ std::unique_ptr<CodeGenerator> codegen;
+ bool compiled_intrinsic = false;
+ {
+ ScopedObjectAccess soa(Thread::Current());
+ ArtMethod* method =
+ runtime->GetClassLinker()->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
+ method_idx, dex_cache, jclass_loader, /*referrer=*/ nullptr, invoke_type);
+ DCHECK_EQ(method == nullptr, soa.Self()->IsExceptionPending());
+ soa.Self()->ClearException(); // Suppress exception if any.
+ VariableSizedHandleScope handles(soa.Self());
+ Handle<mirror::Class> compiling_class =
+ handles.NewHandle(method != nullptr ? method->GetDeclaringClass() : nullptr);
+ DexCompilationUnit dex_compilation_unit(
+ jclass_loader,
+ runtime->GetClassLinker(),
+ dex_file,
+ code_item,
+ class_def_idx,
+ method_idx,
+ access_flags,
+ /*verified_method=*/ nullptr, // Not needed by the Optimizing compiler.
+ dex_cache,
+ compiling_class);
+ // All signature polymorphic methods are native.
+ DCHECK(method == nullptr || !method->IsSignaturePolymorphic());
+ // Go to native so that we don't block GC during compilation.
+ ScopedThreadSuspension sts(soa.Self(), kNative);
+ // Try to compile a fully intrinsified implementation.
+ if (method != nullptr && UNLIKELY(method->IsIntrinsic())) {
+ DCHECK(compiler_options.IsBootImage());
+ codegen.reset(
+ TryCompileIntrinsic(&allocator,
+ &arena_stack,
+ &code_allocator,
+ dex_compilation_unit,
+ method,
+ &handles));
+ if (codegen != nullptr) {
+ compiled_intrinsic = true;
}
}
- if (codegen.get() != nullptr) {
- compiled_method = Emit(&allocator,
- &code_allocator,
- codegen.get(),
- compiled_intrinsic ? nullptr : code_item);
- if (compiled_intrinsic) {
- compiled_method->MarkAsIntrinsic();
- }
+ if (codegen == nullptr) {
+ codegen.reset(
+ TryCompile(&allocator,
+ &arena_stack,
+ &code_allocator,
+ dex_compilation_unit,
+ method,
+ compiler_options.IsBaseline()
+ ? CompilationKind::kBaseline
+ : CompilationKind::kOptimized,
+ &handles));
+ }
+ }
+ if (codegen.get() != nullptr) {
+ compiled_method = Emit(&allocator,
+ &code_allocator,
+ codegen.get(),
+ compiled_intrinsic ? nullptr : code_item);
+ if (compiled_intrinsic) {
+ compiled_method->MarkAsIntrinsic();
+ }
- if (kArenaAllocatorCountAllocations) {
- codegen.reset(); // Release codegen's ScopedArenaAllocator for memory accounting.
- size_t total_allocated = allocator.BytesAllocated() + arena_stack.PeakBytesAllocated();
- if (total_allocated > kArenaAllocatorMemoryReportThreshold) {
- MemStats mem_stats(allocator.GetMemStats());
- MemStats peak_stats(arena_stack.GetPeakStats());
- LOG(INFO) << "Used " << total_allocated << " bytes of arena memory for compiling "
- << dex_file.PrettyMethod(method_idx)
- << "\n" << Dumpable<MemStats>(mem_stats)
- << "\n" << Dumpable<MemStats>(peak_stats);
- }
+ if (kArenaAllocatorCountAllocations) {
+ codegen.reset(); // Release codegen's ScopedArenaAllocator for memory accounting.
+ size_t total_allocated = allocator.BytesAllocated() + arena_stack.PeakBytesAllocated();
+ if (total_allocated > kArenaAllocatorMemoryReportThreshold) {
+ MemStats mem_stats(allocator.GetMemStats());
+ MemStats peak_stats(arena_stack.GetPeakStats());
+ LOG(INFO) << "Used " << total_allocated << " bytes of arena memory for compiling "
+ << dex_file.PrettyMethod(method_idx)
+ << "\n" << Dumpable<MemStats>(mem_stats)
+ << "\n" << Dumpable<MemStats>(peak_stats);
}
}
- } else {
- MethodCompilationStat method_stat;
- if (compiler_options.VerifyAtRuntime()) {
- method_stat = MethodCompilationStat::kNotCompiledVerifyAtRuntime;
- } else {
- method_stat = MethodCompilationStat::kNotCompiledVerificationError;
- }
- MaybeRecordStat(compilation_stats_.get(), method_stat);
}
if (kIsDebugBuild &&
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index 3d0815f1eb..24d01539df 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -58,8 +58,6 @@ enum class MethodCompilationStat {
kNotCompiledSpaceFilter,
kNotCompiledUnhandledInstruction,
kNotCompiledUnsupportedIsa,
- kNotCompiledVerificationError,
- kNotCompiledVerifyAtRuntime,
kNotCompiledIrreducibleLoopAndStringInit,
kNotCompiledPhiEquivalentInOsr,
kInlinedMonomorphicCall,
diff --git a/dex2oat/common_compiler_driver_test.cc b/dex2oat/common_compiler_driver_test.cc
index 1f62cd7da5..2007c5a970 100644
--- a/dex2oat/common_compiler_driver_test.cc
+++ b/dex2oat/common_compiler_driver_test.cc
@@ -41,8 +41,7 @@ void CommonCompilerDriverTest::CompileAll(jobject class_loader,
compiler_driver_->PreCompile(class_loader,
dex_files,
timings,
- &compiler_options_->image_classes_,
- verification_results_.get());
+ &compiler_options_->image_classes_);
// Verification results in the `callback_` should not be used during compilation.
down_cast<QuickCompilerCallbacks*>(callbacks_.get())->SetVerificationResults(
diff --git a/dex2oat/dex/quick_compiler_callbacks.cc b/dex2oat/dex/quick_compiler_callbacks.cc
index f6f82678c8..11223ff3c8 100644
--- a/dex2oat/dex/quick_compiler_callbacks.cc
+++ b/dex2oat/dex/quick_compiler_callbacks.cc
@@ -22,9 +22,9 @@
namespace art {
-void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) {
+void QuickCompilerCallbacks::AddUncompilableMethod(MethodReference ref) {
if (verification_results_ != nullptr) {
- verification_results_->ProcessVerifiedMethod(verifier);
+ verification_results_->AddUncompilableMethod(ref);
}
}
diff --git a/dex2oat/dex/quick_compiler_callbacks.h b/dex2oat/dex/quick_compiler_callbacks.h
index 578a1f56e7..4447e02ccb 100644
--- a/dex2oat/dex/quick_compiler_callbacks.h
+++ b/dex2oat/dex/quick_compiler_callbacks.h
@@ -33,8 +33,7 @@ class QuickCompilerCallbacks final : public CompilerCallbacks {
~QuickCompilerCallbacks() { }
- void MethodVerified(verifier::MethodVerifier* verifier)
- REQUIRES_SHARED(Locks::mutator_lock_) override;
+ void AddUncompilableMethod(MethodReference ref) override;
void ClassRejected(ClassReference ref) override;
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index a1f1945ff8..8a07539ef1 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1514,13 +1514,7 @@ class Dex2Oat final {
if (CompilerFilter::IsAnyCompilationEnabled(compiler_options_->GetCompilerFilter()) ||
IsImage()) {
// Only modes with compilation or image generation require verification results.
- // Do this here instead of when we
- // create the compilation callbacks since the compilation mode may have been changed by the
- // very large app logic.
- // Avoiding setting the verification results saves RAM by not adding the dex files later in
- // the function.
- // Note: When compiling boot image, this must be done before creating the Runtime.
- verification_results_.reset(new VerificationResults(compiler_options_.get()));
+ verification_results_.reset(new VerificationResults());
callbacks_->SetVerificationResults(verification_results_.get());
}
@@ -1731,16 +1725,6 @@ class Dex2Oat final {
}
}
- // Verification results are only required for modes that have any compilation. Avoid
- // adding the dex files if possible to prevent allocating large arrays.
- if (verification_results_ != nullptr) {
- for (const auto& dex_file : dex_files) {
- // Pre-register dex files so that we can access verification results without locks during
- // compilation and verification.
- verification_results_->AddDexFile(dex_file);
- }
- }
-
// Setup VerifierDeps for compilation and report if we fail to parse the data.
if (!DoEagerUnquickeningOfVdex() && input_vdex_file_ != nullptr) {
std::unique_ptr<verifier::VerifierDeps> verifier_deps(
@@ -1991,8 +1975,7 @@ class Dex2Oat final {
driver_->PreCompile(class_loader,
dex_files,
timings_,
- &compiler_options_->image_classes_,
- verification_results_.get());
+ &compiler_options_->image_classes_);
callbacks_->SetVerificationResults(nullptr); // Should not be needed anymore.
compiler_options_->verification_results_ = verification_results_.get();
driver_->CompileAll(class_loader, dex_files, timings_);
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index e1f51437ce..dabf82ce0d 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -53,7 +53,6 @@
#include "dex/dex_file_annotations.h"
#include "dex/dex_instruction-inl.h"
#include "dex/verification_results.h"
-#include "dex/verified_method.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
#include "gc/accounting/card_table-inl.h"
@@ -493,18 +492,13 @@ static void CompileMethodQuick(
const VerificationResults* results = compiler_options.GetVerificationResults();
DCHECK(results != nullptr);
MethodReference method_ref(&dex_file, method_idx);
- const VerifiedMethod* verified_method = results->GetVerifiedMethod(method_ref);
- bool compile =
- // Basic checks, e.g., not <clinit>.
- results->IsCandidateForCompilation(method_ref, access_flags) &&
- // Did not fail to create VerifiedMethod metadata.
- verified_method != nullptr &&
- // Do not have failures that should punt to the interpreter.
- !verified_method->HasRuntimeThrow() &&
- (verified_method->GetEncounteredVerificationFailures() &
- verifier::VERIFY_ERROR_LOCKING) == 0 &&
- // Is eligible for compilation by methods-to-compile filter.
- ShouldCompileBasedOnProfile(compiler_options, profile_index, method_ref);
+ // Don't compile class initializers unless kEverything.
+ bool compile = (compiler_options.GetCompilerFilter() == CompilerFilter::kEverything) ||
+ ((access_flags & kAccConstructor) == 0) || ((access_flags & kAccStatic) == 0);
+ // Check if it's an uncompilable method found by the verifier.
+ compile = compile && !results->IsUncompilableMethod(method_ref);
+ // Check if we should compile based on the profile.
+ compile = compile && ShouldCompileBasedOnProfile(compiler_options, profile_index, method_ref);
if (compile) {
// NOTE: if compiler declines to compile this method, it will return null.
@@ -812,8 +806,7 @@ class CreateConflictTablesVisitor : public ClassVisitor {
void CompilerDriver::PreCompile(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings,
- /*inout*/ HashSet<std::string>* image_classes,
- /*out*/ VerificationResults* verification_results) {
+ /*inout*/ HashSet<std::string>* image_classes) {
CheckThreadPools();
VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false);
@@ -848,7 +841,7 @@ void CompilerDriver::PreCompile(jobject class_loader,
VLOG(compiler) << "Verify none mode specified, skipping verification.";
SetVerified(class_loader, dex_files, timings);
} else if (compiler_options_->IsVerificationEnabled()) {
- Verify(class_loader, dex_files, timings, verification_results);
+ Verify(class_loader, dex_files, timings);
VLOG(compiler) << "Verify: " << GetMemoryUsageString(false);
if (GetCompilerOptions().IsForceDeterminism() &&
@@ -1678,8 +1671,7 @@ static void LoadAndUpdateStatus(const ClassAccessor& accessor,
bool CompilerDriver::FastVerify(jobject jclass_loader,
const std::vector<const DexFile*>& dex_files,
- TimingLogger* timings,
- /*out*/ VerificationResults* verification_results) {
+ TimingLogger* timings) {
verifier::VerifierDeps* verifier_deps =
Runtime::Current()->GetCompilerCallbacks()->GetVerifierDeps();
// If there exist VerifierDeps that aren't the ones we just created to output, use them to verify.
@@ -1730,15 +1722,6 @@ bool CompilerDriver::FastVerify(jobject jclass_loader,
// the class.
LoadAndUpdateStatus(
accessor, ClassStatus::kVerifiedNeedsAccessChecks, class_loader, soa.Self());
- // Create `VerifiedMethod`s for each methods, the compiler expects one for
- // quickening or compiling.
- // Note that this means:
- // - We're only going to compile methods that did verify.
- // - Quickening will not do checkcast ellision.
- // TODO(ngeoffray): Reconsider this once we refactor compiler filters.
- for (const ClassAccessor::Method& method : accessor.GetMethods()) {
- verification_results->CreateVerifiedMethodFor(method.GetReference());
- }
}
} else if (!compiler_only_verifies) {
// Make sure later compilation stages know they should not try to verify
@@ -1755,9 +1738,8 @@ bool CompilerDriver::FastVerify(jobject jclass_loader,
void CompilerDriver::Verify(jobject jclass_loader,
const std::vector<const DexFile*>& dex_files,
- TimingLogger* timings,
- /*out*/ VerificationResults* verification_results) {
- if (FastVerify(jclass_loader, dex_files, timings, verification_results)) {
+ TimingLogger* timings) {
+ if (FastVerify(jclass_loader, dex_files, timings)) {
return;
}
diff --git a/dex2oat/driver/compiler_driver.h b/dex2oat/driver/compiler_driver.h
index 18be20d0f0..3da8c3ae10 100644
--- a/dex2oat/driver/compiler_driver.h
+++ b/dex2oat/driver/compiler_driver.h
@@ -104,8 +104,7 @@ class CompilerDriver {
void PreCompile(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings,
- /*inout*/ HashSet<std::string>* image_classes,
- /*out*/ VerificationResults* verification_results)
+ /*inout*/ HashSet<std::string>* image_classes)
REQUIRES(!Locks::mutator_lock_);
void CompileAll(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
@@ -241,13 +240,11 @@ class CompilerDriver {
// verification was successful.
bool FastVerify(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
- TimingLogger* timings,
- /*out*/ VerificationResults* verification_results);
+ TimingLogger* timings);
void Verify(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
- TimingLogger* timings,
- /*out*/ VerificationResults* verification_results);
+ TimingLogger* timings);
void VerifyDexFile(jobject class_loader,
const DexFile& dex_file,
diff --git a/dex2oat/verifier_deps_test.cc b/dex2oat/verifier_deps_test.cc
index e480478c22..42909aec8a 100644
--- a/dex2oat/verifier_deps_test.cc
+++ b/dex2oat/verifier_deps_test.cc
@@ -27,7 +27,6 @@
#include "dex/dex_file-inl.h"
#include "dex/dex_file_types.h"
#include "dex/verification_results.h"
-#include "dex/verified_method.h"
#include "driver/compiler_driver-inl.h"
#include "driver/compiler_options.h"
#include "handle_scope-inl.h"
@@ -47,7 +46,7 @@ class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
: CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
deps_(nullptr) {}
- void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) override {}
+ void AddUncompilableMethod(MethodReference ref ATTRIBUTE_UNUSED) override {}
void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) override {}
verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; }
@@ -93,16 +92,8 @@ class VerifierDepsTest : public CommonCompilerDriverTest {
verifier_deps_.reset(verifier_deps);
}
callbacks_->SetVerifierDeps(verifier_deps);
- compiler_driver_->Verify(class_loader_, dex_files_, &timings, verification_results_.get());
+ compiler_driver_->Verify(class_loader_, dex_files_, &timings);
callbacks_->SetVerifierDeps(nullptr);
- // Clear entries in the verification results to avoid hitting a DCHECK that
- // we always succeed inserting a new entry after verifying.
- AtomicDexRefMap<MethodReference, const VerifiedMethod*>* map =
- &verification_results_->atomic_verified_methods_;
- map->Visit([](const DexFileReference& ref ATTRIBUTE_UNUSED, const VerifiedMethod* method) {
- delete method;
- });
- map->ClearEntries();
}
void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
@@ -125,9 +116,6 @@ class VerifierDepsTest : public CommonCompilerDriverTest {
for (const DexFile* dex_file : dex_files_) {
class_linker_->RegisterDexFile(*dex_file, loader.Get());
}
- for (const DexFile* dex_file : dex_files_) {
- verification_results_->AddDexFile(dex_file);
- }
SetDexFilesForOatFile(dex_files_);
}
diff --git a/runtime/compiler_callbacks.h b/runtime/compiler_callbacks.h
index 18632dc6c6..23379a9550 100644
--- a/runtime/compiler_callbacks.h
+++ b/runtime/compiler_callbacks.h
@@ -19,6 +19,7 @@
#include "base/locks.h"
#include "dex/class_reference.h"
+#include "dex/method_reference.h"
#include "class_status.h"
namespace art {
@@ -33,7 +34,6 @@ class Class;
namespace verifier {
-class MethodVerifier;
class VerifierDeps;
} // namespace verifier
@@ -47,8 +47,7 @@ class CompilerCallbacks {
virtual ~CompilerCallbacks() { }
- virtual void MethodVerified(verifier::MethodVerifier* verifier)
- REQUIRES_SHARED(Locks::mutator_lock_) = 0;
+ virtual void AddUncompilableMethod(MethodReference ref) = 0;
virtual void ClassRejected(ClassReference ref) = 0;
virtual verifier::VerifierDeps* GetVerifierDeps() const = 0;
diff --git a/runtime/noop_compiler_callbacks.h b/runtime/noop_compiler_callbacks.h
index 439f4856a6..f415831fee 100644
--- a/runtime/noop_compiler_callbacks.h
+++ b/runtime/noop_compiler_callbacks.h
@@ -26,9 +26,7 @@ class NoopCompilerCallbacks final : public CompilerCallbacks {
NoopCompilerCallbacks() : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp) {}
~NoopCompilerCallbacks() {}
- void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) override {
- }
-
+ void AddUncompilableMethod(MethodReference ref ATTRIBUTE_UNUSED) override {}
void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) override {}
verifier::VerifierDeps* GetVerifierDeps() const override { return nullptr; }
diff --git a/runtime/verifier/class_verifier.cc b/runtime/verifier/class_verifier.cc
index 1c8142b642..6a189a29c7 100644
--- a/runtime/verifier/class_verifier.cc
+++ b/runtime/verifier/class_verifier.cc
@@ -54,8 +54,13 @@ static bool gPrintedDxMonitorText = false;
static void UpdateMethodFlags(uint32_t method_index,
Handle<mirror::Class> klass,
Handle<mirror::DexCache> dex_cache,
+ CompilerCallbacks* callbacks,
int error_types)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (callbacks != nullptr && !CanCompilerHandleVerificationFailure(error_types)) {
+ MethodReference ref(dex_cache->GetDexFile(), method_index);
+ callbacks->AddUncompilableMethod(ref);
+ }
if (klass == nullptr) {
DCHECK(Runtime::Current()->IsAotCompiler());
// Flags will be set at runtime.
@@ -130,7 +135,6 @@ FailureKind ClassVerifier::VerifyClass(Thread* self,
class_def,
method.GetCodeItem(),
method.GetAccessFlags(),
- callbacks,
allow_soft_failures,
log_level,
/*need_precise_constants=*/ false,
@@ -150,7 +154,7 @@ FailureKind ClassVerifier::VerifyClass(Thread* self,
*error += " ";
*error += hard_failure_msg;
} else if (result.kind != FailureKind::kNoFailure) {
- UpdateMethodFlags(method.GetIndex(), klass, dex_cache, result.types);
+ UpdateMethodFlags(method.GetIndex(), klass, dex_cache, callbacks, result.types);
if ((result.types & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
// Print a warning about expected slow-down.
// Use a string temporary to print one contiguous warning.
@@ -174,6 +178,12 @@ FailureKind ClassVerifier::VerifyClass(Thread* self,
<< ", class: " << PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
GetMetrics()->ClassVerificationCount()->AddOne();
+
+ if (failure_data.kind == verifier::FailureKind::kHardFailure && callbacks != nullptr) {
+ ClassReference ref(dex_file, dex_file->GetIndexForClassDef(class_def));
+ callbacks->ClassRejected(ref);
+ }
+
return failure_data.kind;
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ced62bea1a..fea4d8a21a 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -35,7 +35,6 @@
#include "base/utils.h"
#include "class_linker.h"
#include "class_root-inl.h"
-#include "compiler_callbacks.h"
#include "dex/class_accessor-inl.h"
#include "dex/descriptors_names.h"
#include "dex/dex_file-inl.h"
@@ -5040,7 +5039,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
const dex::ClassDef& class_def,
const dex::CodeItem* code_item,
uint32_t method_access_flags,
- CompilerCallbacks* callbacks,
bool allow_soft_failures,
HardFailLogMode log_level,
bool need_precise_constants,
@@ -5059,7 +5057,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
class_def,
code_item,
method_access_flags,
- callbacks,
allow_soft_failures,
log_level,
need_precise_constants,
@@ -5078,7 +5075,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
class_def,
code_item,
method_access_flags,
- callbacks,
allow_soft_failures,
log_level,
need_precise_constants,
@@ -5117,7 +5113,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
const dex::ClassDef& class_def,
const dex::CodeItem* code_item,
uint32_t method_access_flags,
- CompilerCallbacks* callbacks,
bool allow_soft_failures,
HardFailLogMode log_level,
bool need_precise_constants,
@@ -5151,11 +5146,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
// to hard fail.
CHECK(!verifier.flags_.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 "
@@ -5209,11 +5199,6 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
}
result.kind = FailureKind::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 (kVerifierDebug || VLOG_IS_ON(verifier)) {
LOG(ERROR) << verifier.info_messages_.str();
verifier.Dump(LOG_STREAM(ERROR));
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 0e59251a15..858be17dbc 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -39,7 +39,6 @@
namespace art {
class ClassLinker;
-class CompilerCallbacks;
class DexFile;
class Instruction;
struct ReferenceMap2Visitor;
@@ -178,7 +177,6 @@ class MethodVerifier {
void VisitRoots(RootVisitor* visitor, const RootInfo& roots)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Accessors used by the compiler via CompilerCallback
const CodeItemDataAccessor& CodeItem() const {
return code_item_accessor_;
}
@@ -257,7 +255,6 @@ class MethodVerifier {
const dex::ClassDef& class_def_idx,
const dex::CodeItem* code_item,
uint32_t method_access_flags,
- CompilerCallbacks* callbacks,
bool allow_soft_failures,
HardFailLogMode log_level,
bool need_precise_constants,
@@ -278,7 +275,6 @@ class MethodVerifier {
const dex::ClassDef& class_def_idx,
const dex::CodeItem* code_item,
uint32_t method_access_flags,
- CompilerCallbacks* callbacks,
bool allow_soft_failures,
HardFailLogMode log_level,
bool need_precise_constants,