summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints/quick
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-02-27 10:24:50 -0800
committerMathieu Chartier <mathieuc@google.com>2014-02-27 10:34:48 -0800
commit55871bf5277f8e8041f1303a416be2cd9215aa07 (patch)
tree3c8699c8910738552d9a5ee14a2e856747c30a87 /runtime/entrypoints/quick
parent4f2573b38f7b0bca027d8540c9b22abe8ba7b7bc (diff)
downloadart-55871bf5277f8e8041f1303a416be2cd9215aa07.zip
art-55871bf5277f8e8041f1303a416be2cd9215aa07.tar.gz
art-55871bf5277f8e8041f1303a416be2cd9215aa07.tar.bz2
Add null check in artQuickResolutionTrampoline
Also fix possible compaction bug around ResolveMethod. Bug: 13221223 Change-Id: I0495eaee8d5f9ae5da0a87c4800a66cd04dc4aa7
Diffstat (limited to 'runtime/entrypoints/quick')
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc18
1 files changed, 11 insertions, 7 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 7cbeb29..5339b5e 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -756,21 +756,25 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
RememberForGcArgumentVisitor visitor(sp, invoke_type == kStatic, shorty, shorty_len, &soa);
visitor.VisitArguments();
thread->EndAssertNoThreadSuspension(old_cause);
+ bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface;
// Resolve method filling in dex cache.
if (called->IsRuntimeMethod()) {
+ SirtRef<mirror::Object> sirt_receiver(soa.Self(), virtual_or_interface ? receiver : nullptr);
called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
+ receiver = sirt_receiver.get();
}
const void* code = NULL;
if (LIKELY(!thread->IsExceptionPending())) {
// Incompatible class change should have been handled in resolve method.
CHECK(!called->CheckIncompatibleClassChange(invoke_type));
- // Refine called method based on receiver.
- if (invoke_type == kVirtual) {
- called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
- } else if (invoke_type == kInterface) {
- called = receiver->GetClass()->FindVirtualMethodForInterface(called);
- }
- if ((invoke_type == kVirtual) || (invoke_type == kInterface)) {
+ if (virtual_or_interface) {
+ // Refine called method based on receiver.
+ CHECK(receiver != nullptr) << invoke_type;
+ if (invoke_type == kVirtual) {
+ called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
+ } else {
+ called = receiver->GetClass()->FindVirtualMethodForInterface(called);
+ }
// We came here because of sharpening. Ensure the dex cache is up-to-date on the method index
// of the sharpened method.
if (called->GetDexCacheResolvedMethods() == caller->GetDexCacheResolvedMethods()) {