summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints/quick
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-10-21 21:07:24 -0700
committerIan Rogers <irogers@google.com>2013-10-25 14:22:26 -0700
commit83883d7fddf30fdb8b6903560fa1337ab991e74c (patch)
treed08809deef3a4ab19a57dd4e2ed629a79b60ce74 /runtime/entrypoints/quick
parent8584a68279efc0f9a409a3555ae5ebf3ec2cc4ac (diff)
downloadart-83883d7fddf30fdb8b6903560fa1337ab991e74c.zip
art-83883d7fddf30fdb8b6903560fa1337ab991e74c.tar.gz
art-83883d7fddf30fdb8b6903560fa1337ab991e74c.tar.bz2
Populate dex cache for sharpened calls.
We ensured the resolved method was in the dex cache, but for a sharpened call this is abstract. Ensure that the concrete method is also resolved. Limit the use of direct dex cache based dispatch to cases where we know how to patch the dex cache. Bug 11389002 Change-Id: I08252686a53b5948650632837c74bcd5cbf8a862
Diffstat (limited to 'runtime/entrypoints/quick')
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc16
1 files changed, 16 insertions, 0 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 12291c3..01d3549 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -19,6 +19,7 @@
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
#include "entrypoints/entrypoint_utils.h"
+#include "gc/accounting/card_table-inl.h"
#include "interpreter/interpreter.h"
#include "invoke_arg_array_builder.h"
#include "mirror/art_method-inl.h"
@@ -547,6 +548,21 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
} else if (invoke_type == kInterface) {
called = receiver->GetClass()->FindVirtualMethodForInterface(called);
}
+ if ((invoke_type == kVirtual) || (invoke_type == kInterface)) {
+ // 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()) {
+ caller->GetDexCacheResolvedMethods()->Set(called->GetDexMethodIndex(), called);
+ } else {
+ // Calling from one dex file to another, need to compute the method index appropriate to
+ // the caller's dex file.
+ uint32_t method_index =
+ MethodHelper(called).FindDexMethodIndexInOtherDexFile(MethodHelper(caller).GetDexFile());
+ if (method_index != DexFile::kDexNoIndex) {
+ caller->GetDexCacheResolvedMethods()->Set(method_index, called);
+ }
+ }
+ }
// Ensure that the called method's class is initialized.
mirror::Class* called_class = called->GetDeclaringClass();
linker->EnsureInitialized(called_class, true, true);