summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interpreter/interpreter.cc5
-rw-r--r--src/oat/runtime/support_invoke.cc4
-rw-r--r--src/runtime_support.cc7
-rw-r--r--src/runtime_support.h2
4 files changed, 7 insertions, 11 deletions
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index f4091bed04..636bb85568 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -378,11 +378,6 @@ static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
receiver = NULL;
} else {
receiver = shadow_frame.GetVRegReference(dec_insn.vC);
- if (UNLIKELY(receiver == NULL)) {
- ThrowNullPointerExceptionForMethodAccess(shadow_frame.GetMethod(), dec_insn.vB, type);
- result->SetJ(0);
- return;
- }
}
uint32_t method_idx = dec_insn.vB;
AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
diff --git a/src/oat/runtime/support_invoke.cc b/src/oat/runtime/support_invoke.cc
index 4f16afee4e..7a49489f8d 100644
--- a/src/oat/runtime/support_invoke.cc
+++ b/src/oat/runtime/support_invoke.cc
@@ -137,10 +137,6 @@ static uint64_t artInvokeCommon(uint32_t method_idx, Object* this_object, Abstra
AbstractMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
if (UNLIKELY(method == NULL)) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
- if (UNLIKELY(this_object == NULL && type != kDirect && type != kStatic)) {
- ThrowNullPointerExceptionForMethodAccess(caller_method, method_idx, type);
- return 0; // failure
- }
method = FindMethodFromCode(method_idx, this_object, caller_method, self, access_check, type);
if (UNLIKELY(method == NULL)) {
CHECK(self->IsExceptionPending());
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 92c5e3ae53..856e877979 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -208,7 +208,7 @@ Field* FindFieldFromCode(uint32_t field_idx, const AbstractMethod* referrer, Thr
}
// Slow path method resolution
-AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, const AbstractMethod* referrer,
+AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, AbstractMethod* referrer,
Thread* self, bool access_check, InvokeType type) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
bool is_direct = type == kStatic || type == kDirect;
@@ -216,6 +216,11 @@ AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, con
if (UNLIKELY(resolved_method == NULL)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return NULL; // Failure.
+ } else if (UNLIKELY(this_object == NULL && type != kStatic)) {
+ // Maintain interpreter-like semantics where NullPointerException is thrown
+ // after potential NoSuchMethodError from class linker.
+ ThrowNullPointerExceptionForMethodAccess(referrer, method_idx, type);
+ return NULL; // Failure.
} else {
if (!access_check) {
if (is_direct) {
diff --git a/src/runtime_support.h b/src/runtime_support.h
index d0a6209ca7..adeedb7439 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -223,7 +223,7 @@ static inline AbstractMethod* FindMethodFast(uint32_t method_idx, Object* this_o
}
}
-extern AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, const AbstractMethod* referrer,
+extern AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, AbstractMethod* referrer,
Thread* self, bool access_check, InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);