summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker.cc6
-rw-r--r--runtime/compiler_callbacks.h4
-rw-r--r--runtime/noop_compiler_callbacks.h3
-rw-r--r--runtime/verifier/method_verifier.cc50
-rw-r--r--runtime/verifier/method_verifier.h59
-rw-r--r--runtime/verifier/method_verifier_test.cc4
6 files changed, 88 insertions, 38 deletions
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)