summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints/entrypoint_utils.h
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2013-10-23 16:24:40 -0700
committerJeff Hao <jeffhao@google.com>2013-10-29 12:01:28 -0700
commit88474b416eb257078e590bf9bc7957cee604a186 (patch)
tree7c59aa370bec9b0f2d37cb7a96d3b2effb3d92ce /runtime/entrypoints/entrypoint_utils.h
parent9780099e445884d8bc9444c8c1261b02d80a26c7 (diff)
downloadart-88474b416eb257078e590bf9bc7957cee604a186.zip
art-88474b416eb257078e590bf9bc7957cee604a186.tar.gz
art-88474b416eb257078e590bf9bc7957cee604a186.tar.bz2
Implement Interface Method Tables (IMT).
Change-Id: Idf7fe85e1293453a8ad862ff2380dcd5db4e3a39
Diffstat (limited to 'runtime/entrypoints/entrypoint_utils.h')
-rw-r--r--runtime/entrypoints/entrypoint_utils.h38
1 files changed, 31 insertions, 7 deletions
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 2008604..7ce50c5 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -372,14 +372,21 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror:
return vtable->GetWithoutChecks(vtable_index);
}
case kInterface: {
- mirror::ArtMethod* interface_method =
- this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
- if (UNLIKELY(interface_method == nullptr)) {
- ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
- referrer);
- return nullptr; // Failure.
+ uint32_t imt_index = resolved_method->GetDexMethodIndex() % ClassLinker::kImtSize;
+ mirror::ObjectArray<mirror::ArtMethod>* imt_table = this_object->GetClass()->GetImTable();
+ mirror::ArtMethod* imt_method = imt_table->Get(imt_index);
+ if (!imt_method->IsImtConflictMethod()) {
+ return imt_method;
} else {
- return interface_method;
+ mirror::ArtMethod* interface_method =
+ this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
+ if (UNLIKELY(interface_method == nullptr)) {
+ ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
+ referrer);
+ return nullptr; // Failure.
+ } else {
+ return interface_method;
+ }
}
}
default:
@@ -665,6 +672,23 @@ static inline const void* GetResolutionTrampoline(ClassLinker* class_linker) {
#endif
}
+static inline const void* GetPortableImtConflictTrampoline(ClassLinker* class_linker) {
+ return class_linker->GetPortableImtConflictTrampoline();
+}
+
+static inline const void* GetQuickImtConflictTrampoline(ClassLinker* class_linker) {
+ return class_linker->GetQuickImtConflictTrampoline();
+}
+
+// Return address of imt conflict trampoline stub for defined compiler.
+static inline const void* GetImtConflictTrampoline(ClassLinker* class_linker) {
+#if defined(ART_USE_PORTABLE_COMPILER)
+ return GetPortableImtConflictTrampoline(class_linker);
+#else
+ return GetQuickImtConflictTrampoline(class_linker);
+#endif
+}
+
extern "C" void art_portable_proxy_invoke_handler();
static inline const void* GetPortableProxyInvokeHandler() {
return reinterpret_cast<void*>(art_portable_proxy_invoke_handler);