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 | |
| parent | 9780099e445884d8bc9444c8c1261b02d80a26c7 (diff) | |
| download | art-88474b416eb257078e590bf9bc7957cee604a186.tar.gz art-88474b416eb257078e590bf9bc7957cee604a186.tar.bz2 art-88474b416eb257078e590bf9bc7957cee604a186.zip | |
Implement Interface Method Tables (IMT).
Change-Id: Idf7fe85e1293453a8ad862ff2380dcd5db4e3a39
Diffstat (limited to 'runtime/entrypoints')
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 38 | ||||
| -rw-r--r-- | runtime/entrypoints/portable/portable_entrypoints.h | 1 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_entrypoints.h | 2 |
3 files changed, 33 insertions, 8 deletions
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 200860470d..7ce50c5dfb 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); diff --git a/runtime/entrypoints/portable/portable_entrypoints.h b/runtime/entrypoints/portable/portable_entrypoints.h index d4564471ac..dbea70735f 100644 --- a/runtime/entrypoints/portable/portable_entrypoints.h +++ b/runtime/entrypoints/portable/portable_entrypoints.h @@ -35,6 +35,7 @@ class Thread; // compiler ABI. struct PACKED(4) PortableEntryPoints { // Invocation + void (*pPortableImtConflictTrampoline)(mirror::ArtMethod*); void (*pPortableResolutionTrampoline)(mirror::ArtMethod*); void (*pPortableToInterpreterBridge)(mirror::ArtMethod*); }; diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h index c8a85a0fe3..1ba206629e 100644 --- a/runtime/entrypoints/quick/quick_entrypoints.h +++ b/runtime/entrypoints/quick/quick_entrypoints.h @@ -118,10 +118,10 @@ struct PACKED(4) QuickEntryPoints { void* (*pMemcpy)(void*, const void*, size_t); // Invocation + void (*pQuickImtConflictTrampoline)(mirror::ArtMethod*); void (*pQuickResolutionTrampoline)(mirror::ArtMethod*); void (*pQuickToInterpreterBridge)(mirror::ArtMethod*); void (*pInvokeDirectTrampolineWithAccessCheck)(uint32_t, void*); - void (*pInvokeInterfaceTrampoline)(uint32_t, void*); void (*pInvokeInterfaceTrampolineWithAccessCheck)(uint32_t, void*); void (*pInvokeStaticTrampolineWithAccessCheck)(uint32_t, void*); void (*pInvokeSuperTrampolineWithAccessCheck)(uint32_t, void*); |
