summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/instruction_builder.cc5
-rw-r--r--runtime/verifier/method_verifier.cc6
-rw-r--r--runtime/verifier/verifier_compiler_binding.h1
3 files changed, 9 insertions, 3 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index cd03e054b5..76ee456b55 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -957,6 +957,11 @@ static ArtMethod* ResolveMethod(uint16_t method_idx,
resolved_method, class_linker->GetImagePointerSize());
} else {
uint16_t vtable_index = resolved_method->GetMethodIndex();
+ if (vtable_index >= static_cast<uint32_t>(
+ compiling_class->GetSuperClass()->GetVTableLength())) {
+ // No super method. The runtime will throw a NoSuchMethodError.
+ return nullptr;
+ }
actual_method = compiling_class->GetSuperClass()->GetVTableEntry(
vtable_index, class_linker->GetImagePointerSize());
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 1ea2c8c22e..4bebbcc24a 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -5169,15 +5169,14 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
}
// Return whether the runtime knows how to execute a method without needing to
-// re-verify it at runtime (and therefore save on first use of the class). We
-// currently only support it for access checks, where the runtime will mark the
-// methods as needing access checks and have the interpreter execute with them.
+// re-verify it at runtime (and therefore save on first use of the class).
// The AOT/JIT compiled code is not affected.
static inline bool CanRuntimeHandleVerificationFailure(uint32_t encountered_failure_types) {
constexpr uint32_t unresolved_mask =
verifier::VerifyError::VERIFY_ERROR_CLASS_CHANGE |
verifier::VerifyError::VERIFY_ERROR_ACCESS_CLASS |
verifier::VerifyError::VERIFY_ERROR_ACCESS_FIELD |
+ verifier::VerifyError::VERIFY_ERROR_NO_METHOD |
verifier::VerifyError::VERIFY_ERROR_ACCESS_METHOD;
return (encountered_failure_types & (~unresolved_mask)) == 0;
}
@@ -5542,6 +5541,7 @@ std::ostream& MethodVerifier::Fail(VerifyError error, bool pending_exc) {
if (IsAotMode() || !can_load_classes_) {
if (error != VERIFY_ERROR_ACCESS_CLASS &&
error != VERIFY_ERROR_ACCESS_FIELD &&
+ error != VERIFY_ERROR_NO_METHOD &&
error != VERIFY_ERROR_ACCESS_METHOD) {
// If we're optimistically running verification at compile time, turn NO_xxx,
// class change and instantiation errors into soft verification errors so that we
diff --git a/runtime/verifier/verifier_compiler_binding.h b/runtime/verifier/verifier_compiler_binding.h
index d39f98ddde..a92a063fe6 100644
--- a/runtime/verifier/verifier_compiler_binding.h
+++ b/runtime/verifier/verifier_compiler_binding.h
@@ -29,6 +29,7 @@ ALWAYS_INLINE
static inline bool CanCompilerHandleVerificationFailure(uint32_t encountered_failure_types) {
constexpr uint32_t unresolved_mask = verifier::VerifyError::VERIFY_ERROR_NO_CLASS
| verifier::VerifyError::VERIFY_ERROR_CLASS_CHANGE
+ | verifier::VerifyError::VERIFY_ERROR_NO_METHOD
| verifier::VerifyError::VERIFY_ERROR_ACCESS_CLASS
| verifier::VerifyError::VERIFY_ERROR_ACCESS_FIELD
| verifier::VerifyError::VERIFY_ERROR_ACCESS_METHOD;