diff options
| author | 2016-07-07 08:28:47 +0000 | |
|---|---|---|
| committer | 2016-07-07 08:28:47 +0000 | |
| commit | f731706af1ce91e9d77f85c36b4dcacce17b7f9b (patch) | |
| tree | c8d6df8d62ea03664199420d2866cb66c3fdf945 /compiler/optimizing/inliner.cc | |
| parent | 05801f4b2b2dba7d97295d93e176d43d4003bee7 (diff) | |
| parent | 5bf7bacc0993a2efd9b0765813928ff72ea4bb9f (diff) | |
Merge "Revert "Revert "Inline and optimize interface calls."""
Diffstat (limited to 'compiler/optimizing/inliner.cc')
| -rw-r--r-- | compiler/optimizing/inliner.cc | 47 | 
1 files changed, 36 insertions, 11 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index c67b2d5fe9..f9e78b0a8f 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -187,12 +187,12 @@ static ArtMethod* FindVirtualOrInterfaceTarget(HInvoke* invoke, ArtMethod* resol  static uint32_t FindMethodIndexIn(ArtMethod* method,                                    const DexFile& dex_file, -                                  uint32_t referrer_index) +                                  uint32_t name_and_signature_index)      SHARED_REQUIRES(Locks::mutator_lock_) {    if (IsSameDexFile(*method->GetDexFile(), dex_file)) {      return method->GetDexMethodIndex();    } else { -    return method->FindDexMethodIndexInOtherDexFile(dex_file, referrer_index); +    return method->FindDexMethodIndexInOtherDexFile(dex_file, name_and_signature_index);    }  } @@ -750,7 +750,40 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction,  bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* method, bool do_rtp) {    HInstruction* return_replacement = nullptr;    if (!TryBuildAndInline(invoke_instruction, method, &return_replacement)) { -    return false; +    if (invoke_instruction->IsInvokeInterface()) { +      // Turn an invoke-interface into an invoke-virtual. An invoke-virtual is always +      // better than an invoke-interface because: +      // 1) In the best case, the interface call has one more indirection (to fetch the IMT). +      // 2) We will not go to the conflict trampoline with an invoke-virtual. +      // TODO: Consider sharpening once it is not dependent on the compiler driver. +      const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); +      uint32_t method_index = FindMethodIndexIn( +          method, caller_dex_file, invoke_instruction->GetDexMethodIndex()); +      if (method_index == DexFile::kDexNoIndex) { +        return false; +      } +      HInvokeVirtual* new_invoke = new (graph_->GetArena()) HInvokeVirtual( +          graph_->GetArena(), +          invoke_instruction->GetNumberOfArguments(), +          invoke_instruction->GetType(), +          invoke_instruction->GetDexPc(), +          method_index, +          method->GetMethodIndex()); +      HInputsRef inputs = invoke_instruction->GetInputs(); +      for (size_t index = 0; index != inputs.size(); ++index) { +        new_invoke->SetArgumentAt(index, inputs[index]); +      } +      invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction); +      new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment()); +      if (invoke_instruction->GetType() == Primitive::kPrimNot) { +        new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo()); +      } +      return_replacement = new_invoke; +    } else { +      // TODO: Consider sharpening an invoke virtual once it is not dependent on the +      // compiler driver. +      return false; +    }    }    if (return_replacement != nullptr) {      invoke_instruction->ReplaceWith(return_replacement); @@ -1239,14 +1272,6 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction,          return false;        } -      if (current->IsInvokeInterface()) { -        // Disable inlining of interface calls. The cost in case of entering the -        // resolution conflict is currently too high. -        VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) -                       << " could not be inlined because it has an interface call."; -        return false; -      } -        if (!same_dex_file && current->NeedsEnvironment()) {          VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)                         << " could not be inlined because " << current->DebugName()  |