summaryrefslogtreecommitdiff
path: root/runtime/class_linker-inl.h
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2016-01-07 14:49:16 -0800
committer Alex Light <allight@google.com> 2016-01-28 15:46:55 -0800
commitfedd91d50930e160c021d65b3740264f6ffec260 (patch)
tree5f356423e51f3bd71020ba0a5f024c54adc959e7 /runtime/class_linker-inl.h
parent97f4bc04b61d5cf78b0820dbf18e999b20d7a108 (diff)
Optimizing compiler support for directly calling interface methods
This teaches the optimizing compiler how to perform invoke-super on interfaces. This should make the invokes generally faster. Bug: 24618811 Change-Id: I7f9b0fb1209775c1c8837ab5d21f8acba3cc72a5
Diffstat (limited to 'runtime/class_linker-inl.h')
-rw-r--r--runtime/class_linker-inl.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index ea1afa8203..7e8a4a4fcd 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -116,6 +116,30 @@ inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod*
return resolved_method;
}
+inline mirror::Class* ClassLinker::ResolveReferencedClassOfMethod(Thread* self,
+ uint32_t method_idx,
+ ArtMethod* referrer) {
+ // NB: We cannot simply use `GetResolvedMethod(method_idx, ...)->GetDeclaringClass()`. This is
+ // because if we did so than an invoke-super could be incorrectly dispatched in cases where
+ // GetMethodId(method_idx).class_idx_ refers to a non-interface, non-direct-superclass
+ // (super*-class?) of the referrer and the direct superclass of the referrer contains a concrete
+ // implementation of the method. If this class's implementation of the method is copied from an
+ // interface (either miranda, default or conflict) we would incorrectly assume that is what we
+ // want to invoke on, instead of the 'concrete' implementation that the direct superclass
+ // contains.
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+ const DexFile* dex_file = h_dex_cache->GetDexFile();
+ const DexFile::MethodId& method = dex_file->GetMethodId(method_idx);
+ mirror::Class* resolved_type = h_dex_cache->GetResolvedType(method.class_idx_);
+ if (UNLIKELY(resolved_type == nullptr)) {
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ resolved_type = ResolveType(*dex_file, method.class_idx_, h_dex_cache, class_loader);
+ }
+ return resolved_type;
+}
+
template <ClassLinker::ResolveMode kResolveMode>
inline ArtMethod* ClassLinker::ResolveMethod(Thread* self,
uint32_t method_idx,