diff options
| author | 2016-02-29 14:30:00 +0000 | |
|---|---|---|
| committer | 2016-02-29 14:30:00 +0000 | |
| commit | fb734b416d20e5c3d1c29576f5cf16a003960b55 (patch) | |
| tree | ed2f46d965cb5f5e87b93836f0d94e72ab2cfd71 /compiler/optimizing | |
| parent | eebfed8b2fc4d6efa614f98001a0dc918bd225c0 (diff) | |
| parent | 4f97a212b6ff801eb9f7f88a87f44e0584339cca (diff) | |
Merge "Cleanup polymorphic inlining to the same target."
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/inliner.cc | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index d55009554f..494a6ee9c3 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -603,6 +603,10 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, DCHECK(resolved_method != nullptr); ArtMethod* actual_method = nullptr; + size_t method_index = invoke_instruction->IsInvokeVirtual() + ? invoke_instruction->AsInvokeVirtual()->GetVTableIndex() + : invoke_instruction->AsInvokeInterface()->GetImtIndex(); + // Check whether we are actually calling the same method among // the different types seen. for (size_t i = 0; i < InlineCache::kIndividualCacheSize; ++i) { @@ -611,13 +615,18 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, } ArtMethod* new_method = nullptr; if (invoke_instruction->IsInvokeInterface()) { - new_method = ic.GetTypeAt(i)->FindVirtualMethodForInterface( - resolved_method, pointer_size); + new_method = ic.GetTypeAt(i)->GetEmbeddedImTableEntry( + method_index % mirror::Class::kImtSize, pointer_size); + if (new_method->IsRuntimeMethod()) { + // Bail out as soon as we see a conflict trampoline in one of the target's + // interface table. + return false; + } } else { DCHECK(invoke_instruction->IsInvokeVirtual()); - new_method = ic.GetTypeAt(i)->FindVirtualMethodForVirtual( - resolved_method, pointer_size); + new_method = ic.GetTypeAt(i)->GetEmbeddedVTableEntry(method_index, pointer_size); } + DCHECK(new_method != nullptr); if (actual_method == nullptr) { actual_method = new_method; } else if (actual_method != new_method) { @@ -641,10 +650,6 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, HInstanceFieldGet* receiver_class = BuildGetReceiverClass( class_linker, receiver, invoke_instruction->GetDexPc()); - size_t method_offset = invoke_instruction->IsInvokeVirtual() - ? actual_method->GetVtableIndex() - : invoke_instruction->AsInvokeInterface()->GetImtIndex(); - Primitive::Type type = Is64BitInstructionSet(graph_->GetInstructionSet()) ? Primitive::kPrimLong : Primitive::kPrimInt; @@ -653,7 +658,7 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, type, invoke_instruction->IsInvokeVirtual() ? HClassTableGet::TableKind::kVTable : HClassTableGet::TableKind::kIMTable, - method_offset, + method_index, invoke_instruction->GetDexPc()); HConstant* constant; |