diff options
author | Jeff Hao <jeffhao@google.com> | 2013-10-23 16:24:40 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2013-10-29 12:01:28 -0700 |
commit | 88474b416eb257078e590bf9bc7957cee604a186 (patch) | |
tree | 7c59aa370bec9b0f2d37cb7a96d3b2effb3d92ce /runtime/entrypoints/entrypoint_utils.h | |
parent | 9780099e445884d8bc9444c8c1261b02d80a26c7 (diff) | |
download | art-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.h | 38 |
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); |