Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "inliner.h"
     18 
     19 #include "art_method-inl.h"
     20 #include "builder.h"
     21 #include "class_linker.h"
     22 #include "constant_folding.h"
     23 #include "dead_code_elimination.h"
     24 #include "dex/verified_method.h"
     25 #include "dex/verification_results.h"
     26 #include "driver/compiler_driver-inl.h"
     27 #include "driver/compiler_options.h"
     28 #include "driver/dex_compilation_unit.h"
     29 #include "instruction_simplifier.h"
     30 #include "intrinsics.h"
     31 #include "jit/jit.h"
     32 #include "jit/jit_code_cache.h"
     33 #include "mirror/class_loader.h"
     34 #include "mirror/dex_cache.h"
     35 #include "nodes.h"
     36 #include "optimizing_compiler.h"
     37 #include "reference_type_propagation.h"
     38 #include "register_allocator.h"
     39 #include "quick/inline_method_analyser.h"
     40 #include "sharpening.h"
     41 #include "ssa_builder.h"
     42 #include "ssa_phi_elimination.h"
     43 #include "scoped_thread_state_change.h"
     44 #include "thread.h"
     45 
     46 namespace art {
     47 
     48 static constexpr size_t kMaximumNumberOfHInstructions = 32;
     49 
     50 // Limit the number of dex registers that we accumulate while inlining
     51 // to avoid creating large amount of nested environments.
     52 static constexpr size_t kMaximumNumberOfCumulatedDexRegisters = 64;
     53 
     54 // Avoid inlining within a huge method due to memory pressure.
     55 static constexpr size_t kMaximumCodeUnitSize = 4096;
     56 
     57 void HInliner::Run() {
     58   const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
     59   if ((compiler_options.GetInlineDepthLimit() == 0)
     60       || (compiler_options.GetInlineMaxCodeUnits() == 0)) {
     61     return;
     62   }
     63   if (caller_compilation_unit_.GetCodeItem()->insns_size_in_code_units_ > kMaximumCodeUnitSize) {
     64     return;
     65   }
     66   if (graph_->IsDebuggable()) {
     67     // For simplicity, we currently never inline when the graph is debuggable. This avoids
     68     // doing some logic in the runtime to discover if a method could have been inlined.
     69     return;
     70   }
     71   const ArenaVector<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
     72   DCHECK(!blocks.empty());
     73   HBasicBlock* next_block = blocks[0];
     74   for (size_t i = 0; i < blocks.size(); ++i) {
     75     // Because we are changing the graph when inlining, we need to remember the next block.
     76     // This avoids doing the inlining work again on the inlined blocks.
     77     if (blocks[i] != next_block) {
     78       continue;
     79     }
     80     HBasicBlock* block = next_block;
     81     next_block = (i == blocks.size() - 1) ? nullptr : blocks[i + 1];
     82     for (HInstruction* instruction = block->GetFirstInstruction(); instruction != nullptr;) {
     83       HInstruction* next = instruction->GetNext();
     84       HInvoke* call = instruction->AsInvoke();
     85       // As long as the call is not intrinsified, it is worth trying to inline.
     86       if (call != nullptr && call->GetIntrinsic() == Intrinsics::kNone) {
     87         // We use the original invoke type to ensure the resolution of the called method
     88         // works properly.
     89         if (!TryInline(call)) {
     90           if (kIsDebugBuild && IsCompilingWithCoreImage()) {
     91             std::string callee_name =
     92                 PrettyMethod(call->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile());
     93             bool should_inline = callee_name.find("$inline$") != std::string::npos;
     94             CHECK(!should_inline) << "Could not inline " << callee_name;
     95           }
     96         } else {
     97           if (kIsDebugBuild && IsCompilingWithCoreImage()) {
     98             std::string callee_name =
     99                 PrettyMethod(call->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile());
    100             bool must_not_inline = callee_name.find("$noinline$") != std::string::npos;
    101             CHECK(!must_not_inline) << "Should not have inlined " << callee_name;
    102           }
    103         }
    104       }
    105       instruction = next;
    106     }
    107   }
    108 }
    109 
    110 static bool IsMethodOrDeclaringClassFinal(ArtMethod* method)
    111     SHARED_REQUIRES(Locks::mutator_lock_) {
    112   return method->IsFinal() || method->GetDeclaringClass()->IsFinal();
    113 }
    114 
    115 /**
    116  * Given the `resolved_method` looked up in the dex cache, try to find
    117  * the actual runtime target of an interface or virtual call.
    118  * Return nullptr if the runtime target cannot be proven.
    119  */
    120 static ArtMethod* FindVirtualOrInterfaceTarget(HInvoke* invoke, ArtMethod* resolved_method)
    121     SHARED_REQUIRES(Locks::mutator_lock_) {
    122   if (IsMethodOrDeclaringClassFinal(resolved_method)) {
    123     // No need to lookup further, the resolved method will be the target.
    124     return resolved_method;
    125   }
    126 
    127   HInstruction* receiver = invoke->InputAt(0);
    128   if (receiver->IsNullCheck()) {
    129     // Due to multiple levels of inlining within the same pass, it might be that
    130     // null check does not have the reference type of the actual receiver.
    131     receiver = receiver->InputAt(0);
    132   }
    133   ReferenceTypeInfo info = receiver->GetReferenceTypeInfo();
    134   DCHECK(info.IsValid()) << "Invalid RTI for " << receiver->DebugName();
    135   if (!info.IsExact()) {
    136     // We currently only support inlining with known receivers.
    137     // TODO: Remove this check, we should be able to inline final methods
    138     // on unknown receivers.
    139     return nullptr;
    140   } else if (info.GetTypeHandle()->IsInterface()) {
    141     // Statically knowing that the receiver has an interface type cannot
    142     // help us find what is the target method.
    143     return nullptr;
    144   } else if (!resolved_method->GetDeclaringClass()->IsAssignableFrom(info.GetTypeHandle().Get())) {
    145     // The method that we're trying to call is not in the receiver's class or super classes.
    146     return nullptr;
    147   } else if (info.GetTypeHandle()->IsErroneous()) {
    148     // If the type is erroneous, do not go further, as we are going to query the vtable or
    149     // imt table, that we can only safely do on non-erroneous classes.
    150     return nullptr;
    151   }
    152 
    153   ClassLinker* cl = Runtime::Current()->GetClassLinker();
    154   size_t pointer_size = cl->GetImagePointerSize();
    155   if (invoke->IsInvokeInterface()) {
    156     resolved_method = info.GetTypeHandle()->FindVirtualMethodForInterface(
    157         resolved_method, pointer_size);
    158   } else {
    159     DCHECK(invoke->IsInvokeVirtual());
    160     resolved_method = info.GetTypeHandle()->FindVirtualMethodForVirtual(
    161         resolved_method, pointer_size);
    162   }
    163 
    164   if (resolved_method == nullptr) {
    165     // The information we had on the receiver was not enough to find
    166     // the target method. Since we check above the exact type of the receiver,
    167     // the only reason this can happen is an IncompatibleClassChangeError.
    168     return nullptr;
    169   } else if (!resolved_method->IsInvokable()) {
    170     // The information we had on the receiver was not enough to find
    171     // the target method. Since we check above the exact type of the receiver,
    172     // the only reason this can happen is an IncompatibleClassChangeError.
    173     return nullptr;
    174   } else if (IsMethodOrDeclaringClassFinal(resolved_method)) {
    175     // A final method has to be the target method.
    176     return resolved_method;
    177   } else if (info.IsExact()) {
    178     // If we found a method and the receiver's concrete type is statically
    179     // known, we know for sure the target.
    180     return resolved_method;
    181   } else {
    182     // Even if we did find a method, the receiver type was not enough to
    183     // statically find the runtime target.
    184     return nullptr;
    185   }
    186 }
    187 
    188 static uint32_t FindClassIndexIn(mirror::Class* cls,
    189                                  const DexFile& dex_file,
    190                                  Handle<mirror::DexCache> dex_cache)
    191     SHARED_REQUIRES(Locks::mutator_lock_) {
    192   uint32_t index = DexFile::kDexNoIndex;
    193   if (cls->GetDexCache() == nullptr) {
    194     DCHECK(cls->IsArrayClass()) << PrettyClass(cls);
    195     index = cls->FindTypeIndexInOtherDexFile(dex_file);
    196   } else if (cls->GetDexTypeIndex() == DexFile::kDexNoIndex16) {
    197     DCHECK(cls->IsProxyClass()) << PrettyClass(cls);
    198     // TODO: deal with proxy classes.
    199   } else if (IsSameDexFile(cls->GetDexFile(), dex_file)) {
    200     DCHECK_EQ(cls->GetDexCache(), dex_cache.Get());
    201     index = cls->GetDexTypeIndex();
    202     // Update the dex cache to ensure the class is in. The generated code will
    203     // consider it is. We make it safe by updating the dex cache, as other
    204     // dex files might also load the class, and there is no guarantee the dex
    205     // cache of the dex file of the class will be updated.
    206     if (dex_cache->GetResolvedType(index) == nullptr) {
    207       dex_cache->SetResolvedType(index, cls);
    208     }
    209   } else {
    210     index = cls->FindTypeIndexInOtherDexFile(dex_file);
    211     // We cannot guarantee the entry in the dex cache will resolve to the same class,
    212     // as there may be different class loaders. So only return the index if it's
    213     // the right class in the dex cache already.
    214     if (index != DexFile::kDexNoIndex && dex_cache->GetResolvedType(index) != cls) {
    215       index = DexFile::kDexNoIndex;
    216     }
    217   }
    218 
    219   return index;
    220 }
    221 
    222 class ScopedProfilingInfoInlineUse {
    223  public:
    224   explicit ScopedProfilingInfoInlineUse(ArtMethod* method, Thread* self)
    225       : method_(method),
    226         self_(self),
    227         // Fetch the profiling info ahead of using it. If it's null when fetching,
    228         // we should not call JitCodeCache::DoneInlining.
    229         profiling_info_(
    230             Runtime::Current()->GetJit()->GetCodeCache()->NotifyCompilerUse(method, self)) {
    231   }
    232 
    233   ~ScopedProfilingInfoInlineUse() {
    234     if (profiling_info_ != nullptr) {
    235       size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    236       DCHECK_EQ(profiling_info_, method_->GetProfilingInfo(pointer_size));
    237       Runtime::Current()->GetJit()->GetCodeCache()->DoneCompilerUse(method_, self_);
    238     }
    239   }
    240 
    241   ProfilingInfo* GetProfilingInfo() const { return profiling_info_; }
    242 
    243  private:
    244   ArtMethod* const method_;
    245   Thread* const self_;
    246   ProfilingInfo* const profiling_info_;
    247 };
    248 
    249 bool HInliner::TryInline(HInvoke* invoke_instruction) {
    250   if (invoke_instruction->IsInvokeUnresolved()) {
    251     return false;  // Don't bother to move further if we know the method is unresolved.
    252   }
    253 
    254   uint32_t method_index = invoke_instruction->GetDexMethodIndex();
    255   ScopedObjectAccess soa(Thread::Current());
    256   const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
    257   VLOG(compiler) << "Try inlining " << PrettyMethod(method_index, caller_dex_file);
    258 
    259   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
    260   // We can query the dex cache directly. The verifier has populated it already.
    261   ArtMethod* resolved_method;
    262   ArtMethod* actual_method = nullptr;
    263   if (invoke_instruction->IsInvokeStaticOrDirect()) {
    264     if (invoke_instruction->AsInvokeStaticOrDirect()->IsStringInit()) {
    265       VLOG(compiler) << "Not inlining a String.<init> method";
    266       return false;
    267     }
    268     MethodReference ref = invoke_instruction->AsInvokeStaticOrDirect()->GetTargetMethod();
    269     mirror::DexCache* const dex_cache = IsSameDexFile(caller_dex_file, *ref.dex_file)
    270         ? caller_compilation_unit_.GetDexCache().Get()
    271         : class_linker->FindDexCache(soa.Self(), *ref.dex_file);
    272     resolved_method = dex_cache->GetResolvedMethod(
    273         ref.dex_method_index, class_linker->GetImagePointerSize());
    274     // actual_method == resolved_method for direct or static calls.
    275     actual_method = resolved_method;
    276   } else {
    277     resolved_method = caller_compilation_unit_.GetDexCache().Get()->GetResolvedMethod(
    278         method_index, class_linker->GetImagePointerSize());
    279     if (resolved_method != nullptr) {
    280       // Check if we can statically find the method.
    281       actual_method = FindVirtualOrInterfaceTarget(invoke_instruction, resolved_method);
    282     }
    283   }
    284 
    285   if (resolved_method == nullptr) {
    286     // TODO: Can this still happen?
    287     // Method cannot be resolved if it is in another dex file we do not have access to.
    288     VLOG(compiler) << "Method cannot be resolved " << PrettyMethod(method_index, caller_dex_file);
    289     return false;
    290   }
    291 
    292   if (actual_method != nullptr) {
    293     bool result = TryInlineAndReplace(invoke_instruction, actual_method, /* do_rtp */ true);
    294     if (result && !invoke_instruction->IsInvokeStaticOrDirect()) {
    295       MaybeRecordStat(kInlinedInvokeVirtualOrInterface);
    296     }
    297     return result;
    298   }
    299 
    300   DCHECK(!invoke_instruction->IsInvokeStaticOrDirect());
    301 
    302   // Check if we can use an inline cache.
    303   ArtMethod* caller = graph_->GetArtMethod();
    304   if (Runtime::Current()->UseJitCompilation()) {
    305     // Under JIT, we should always know the caller.
    306     DCHECK(caller != nullptr);
    307     ScopedProfilingInfoInlineUse spiis(caller, soa.Self());
    308     ProfilingInfo* profiling_info = spiis.GetProfilingInfo();
    309     if (profiling_info != nullptr) {
    310       const InlineCache& ic = *profiling_info->GetInlineCache(invoke_instruction->GetDexPc());
    311       if (ic.IsUninitialized()) {
    312         VLOG(compiler) << "Interface or virtual call to "
    313                        << PrettyMethod(method_index, caller_dex_file)
    314                        << " is not hit and not inlined";
    315         return false;
    316       } else if (ic.IsMonomorphic()) {
    317         MaybeRecordStat(kMonomorphicCall);
    318         if (outermost_graph_->IsCompilingOsr()) {
    319           // If we are compiling OSR, we pretend this call is polymorphic, as we may come from the
    320           // interpreter and it may have seen different receiver types.
    321           return TryInlinePolymorphicCall(invoke_instruction, resolved_method, ic);
    322         } else {
    323           return TryInlineMonomorphicCall(invoke_instruction, resolved_method, ic);
    324         }
    325       } else if (ic.IsPolymorphic()) {
    326         MaybeRecordStat(kPolymorphicCall);
    327         return TryInlinePolymorphicCall(invoke_instruction, resolved_method, ic);
    328       } else {
    329         DCHECK(ic.IsMegamorphic());
    330         VLOG(compiler) << "Interface or virtual call to "
    331                        << PrettyMethod(method_index, caller_dex_file)
    332                        << " is megamorphic and not inlined";
    333         MaybeRecordStat(kMegamorphicCall);
    334         return false;
    335       }
    336     }
    337   }
    338 
    339   VLOG(compiler) << "Interface or virtual call to "
    340                  << PrettyMethod(method_index, caller_dex_file)
    341                  << " could not be statically determined";
    342   return false;
    343 }
    344 
    345 HInstanceFieldGet* HInliner::BuildGetReceiverClass(ClassLinker* class_linker,
    346                                                    HInstruction* receiver,
    347                                                    uint32_t dex_pc) const {
    348   ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0);
    349   DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_");
    350   HInstanceFieldGet* result = new (graph_->GetArena()) HInstanceFieldGet(
    351       receiver,
    352       Primitive::kPrimNot,
    353       field->GetOffset(),
    354       field->IsVolatile(),
    355       field->GetDexFieldIndex(),
    356       field->GetDeclaringClass()->GetDexClassDefIndex(),
    357       *field->GetDexFile(),
    358       handles_->NewHandle(field->GetDexCache()),
    359       dex_pc);
    360   // The class of a field is effectively final, and does not have any memory dependencies.
    361   result->SetSideEffects(SideEffects::None());
    362   return result;
    363 }
    364 
    365 bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction,
    366                                         ArtMethod* resolved_method,
    367                                         const InlineCache& ic) {
    368   DCHECK(invoke_instruction->IsInvokeVirtual() || invoke_instruction->IsInvokeInterface())
    369       << invoke_instruction->DebugName();
    370 
    371   const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
    372   uint32_t class_index = FindClassIndexIn(
    373       ic.GetMonomorphicType(), caller_dex_file, caller_compilation_unit_.GetDexCache());
    374   if (class_index == DexFile::kDexNoIndex) {
    375     VLOG(compiler) << "Call to " << PrettyMethod(resolved_method)
    376                    << " from inline cache is not inlined because its class is not"
    377                    << " accessible to the caller";
    378     return false;
    379   }
    380 
    381   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
    382   size_t pointer_size = class_linker->GetImagePointerSize();
    383   if (invoke_instruction->IsInvokeInterface()) {
    384     resolved_method = ic.GetMonomorphicType()->FindVirtualMethodForInterface(
    385         resolved_method, pointer_size);
    386   } else {
    387     DCHECK(invoke_instruction->IsInvokeVirtual());
    388     resolved_method = ic.GetMonomorphicType()->FindVirtualMethodForVirtual(
    389         resolved_method, pointer_size);
    390   }
    391   DCHECK(resolved_method != nullptr);
    392   HInstruction* receiver = invoke_instruction->InputAt(0);
    393   HInstruction* cursor = invoke_instruction->GetPrevious();
    394   HBasicBlock* bb_cursor = invoke_instruction->GetBlock();
    395 
    396   if (!TryInlineAndReplace(invoke_instruction, resolved_method, /* do_rtp */ false)) {
    397     return false;
    398   }
    399 
    400   // We successfully inlined, now add a guard.
    401   bool is_referrer =
    402       (ic.GetMonomorphicType() == outermost_graph_->GetArtMethod()->GetDeclaringClass());
    403   AddTypeGuard(receiver,
    404                cursor,
    405                bb_cursor,
    406                class_index,
    407                is_referrer,
    408                invoke_instruction,
    409                /* with_deoptimization */ true);
    410 
    411   // Run type propagation to get the guard typed, and eventually propagate the
    412   // type of the receiver.
    413   ReferenceTypePropagation rtp_fixup(graph_,
    414                                      outer_compilation_unit_.GetDexCache(),
    415                                      handles_,
    416                                      /* is_first_run */ false);
    417   rtp_fixup.Run();
    418 
    419   MaybeRecordStat(kInlinedMonomorphicCall);
    420   return true;
    421 }
    422 
    423 HInstruction* HInliner::AddTypeGuard(HInstruction* receiver,
    424                                      HInstruction* cursor,
    425                                      HBasicBlock* bb_cursor,
    426                                      uint32_t class_index,
    427                                      bool is_referrer,
    428                                      HInstruction* invoke_instruction,
    429                                      bool with_deoptimization) {
    430   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
    431   HInstanceFieldGet* receiver_class = BuildGetReceiverClass(
    432       class_linker, receiver, invoke_instruction->GetDexPc());
    433 
    434   const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
    435   // Note that we will just compare the classes, so we don't need Java semantics access checks.
    436   // Also, the caller of `AddTypeGuard` must have guaranteed that the class is in the dex cache.
    437   HLoadClass* load_class = new (graph_->GetArena()) HLoadClass(graph_->GetCurrentMethod(),
    438                                                                class_index,
    439                                                                caller_dex_file,
    440                                                                is_referrer,
    441                                                                invoke_instruction->GetDexPc(),
    442                                                                /* needs_access_check */ false,
    443                                                                /* is_in_dex_cache */ true);
    444 
    445   HNotEqual* compare = new (graph_->GetArena()) HNotEqual(load_class, receiver_class);
    446   // TODO: Extend reference type propagation to understand the guard.
    447   if (cursor != nullptr) {
    448     bb_cursor->InsertInstructionAfter(receiver_class, cursor);
    449   } else {
    450     bb_cursor->InsertInstructionBefore(receiver_class, bb_cursor->GetFirstInstruction());
    451   }
    452   bb_cursor->InsertInstructionAfter(load_class, receiver_class);
    453   bb_cursor->InsertInstructionAfter(compare, load_class);
    454   if (with_deoptimization) {
    455     HDeoptimize* deoptimize = new (graph_->GetArena()) HDeoptimize(
    456         compare, invoke_instruction->GetDexPc());
    457     bb_cursor->InsertInstructionAfter(deoptimize, compare);
    458     deoptimize->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
    459   }
    460   return compare;
    461 }
    462 
    463 bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction,
    464                                         ArtMethod* resolved_method,
    465                                         const InlineCache& ic) {
    466   DCHECK(invoke_instruction->IsInvokeVirtual() || invoke_instruction->IsInvokeInterface())
    467       << invoke_instruction->DebugName();
    468 
    469   if (TryInlinePolymorphicCallToSameTarget(invoke_instruction, resolved_method, ic)) {
    470     return true;
    471   }
    472 
    473   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
    474   size_t pointer_size = class_linker->GetImagePointerSize();
    475   const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
    476 
    477   bool all_targets_inlined = true;
    478   bool one_target_inlined = false;
    479   for (size_t i = 0; i < InlineCache::kIndividualCacheSize; ++i) {
    480     if (ic.GetTypeAt(i) == nullptr) {
    481       break;
    482     }
    483     ArtMethod* method = nullptr;
    484     if (invoke_instruction->IsInvokeInterface()) {
    485       method = ic.GetTypeAt(i)->FindVirtualMethodForInterface(
    486           resolved_method, pointer_size);
    487     } else {
    488       DCHECK(invoke_instruction->IsInvokeVirtual());
    489       method = ic.GetTypeAt(i)->FindVirtualMethodForVirtual(
    490           resolved_method, pointer_size);
    491     }
    492 
    493     HInstruction* receiver = invoke_instruction->InputAt(0);
    494     HInstruction* cursor = invoke_instruction->GetPrevious();
    495     HBasicBlock* bb_cursor = invoke_instruction->GetBlock();
    496 
    497     uint32_t class_index = FindClassIndexIn(
    498         ic.GetTypeAt(i), caller_dex_file, caller_compilation_unit_.GetDexCache());
    499     HInstruction* return_replacement = nullptr;
    500     if (class_index == DexFile::kDexNoIndex ||
    501         !TryBuildAndInline(invoke_instruction, method, &return_replacement)) {
    502       all_targets_inlined = false;
    503     } else {
    504       one_target_inlined = true;
    505       bool is_referrer = (ic.GetTypeAt(i) == outermost_graph_->GetArtMethod()->GetDeclaringClass());
    506 
    507       // If we have inlined all targets before, and this receiver is the last seen,
    508       // we deoptimize instead of keeping the original invoke instruction.
    509       bool deoptimize = all_targets_inlined &&
    510           (i != InlineCache::kIndividualCacheSize - 1) &&
    511           (ic.GetTypeAt(i + 1) == nullptr);
    512 
    513       if (outermost_graph_->IsCompilingOsr()) {
    514         // We do not support HDeoptimize in OSR methods.
    515         deoptimize = false;
    516       }
    517       HInstruction* compare = AddTypeGuard(
    518           receiver, cursor, bb_cursor, class_index, is_referrer, invoke_instruction, deoptimize);
    519       if (deoptimize) {
    520         if (return_replacement != nullptr) {
    521           invoke_instruction->ReplaceWith(return_replacement);
    522         }
    523         invoke_instruction->GetBlock()->RemoveInstruction(invoke_instruction);
    524         // Because the inline cache data can be populated concurrently, we force the end of the
    525         // iteration. Otherhwise, we could see a new receiver type.
    526         break;
    527       } else {
    528         CreateDiamondPatternForPolymorphicInline(compare, return_replacement, invoke_instruction);
    529       }
    530     }
    531   }
    532 
    533   if (!one_target_inlined) {
    534     VLOG(compiler) << "Call to " << PrettyMethod(resolved_method)
    535                    << " from inline cache is not inlined because none"
    536                    << " of its targets could be inlined";
    537     return false;
    538   }
    539   MaybeRecordStat(kInlinedPolymorphicCall);
    540 
    541   // Run type propagation to get the guards typed.
    542   ReferenceTypePropagation rtp_fixup(graph_,
    543                                      outer_compilation_unit_.GetDexCache(),
    544                                      handles_,
    545                                      /* is_first_run */ false);
    546   rtp_fixup.Run();
    547   return true;
    548 }
    549 
    550 void HInliner::CreateDiamondPatternForPolymorphicInline(HInstruction* compare,
    551                                                         HInstruction* return_replacement,
    552                                                         HInstruction* invoke_instruction) {
    553   uint32_t dex_pc = invoke_instruction->GetDexPc();
    554   HBasicBlock* cursor_block = compare->GetBlock();
    555   HBasicBlock* original_invoke_block = invoke_instruction->GetBlock();
    556   ArenaAllocator* allocator = graph_->GetArena();
    557 
    558   // Spit the block after the compare: `cursor_block` will now be the start of the diamond,
    559   // and the returned block is the start of the then branch (that could contain multiple blocks).
    560   HBasicBlock* then = cursor_block->SplitAfterForInlining(compare);
    561 
    562   // Split the block containing the invoke before and after the invoke. The returned block
    563   // of the split before will contain the invoke and will be the otherwise branch of
    564   // the diamond. The returned block of the split after will be the merge block
    565   // of the diamond.
    566   HBasicBlock* end_then = invoke_instruction->GetBlock();
    567   HBasicBlock* otherwise = end_then->SplitBeforeForInlining(invoke_instruction);
    568   HBasicBlock* merge = otherwise->SplitAfterForInlining(invoke_instruction);
    569 
    570   // If the methods we are inlining return a value, we create a phi in the merge block
    571   // that will have the `invoke_instruction and the `return_replacement` as inputs.
    572   if (return_replacement != nullptr) {
    573     HPhi* phi = new (allocator) HPhi(
    574         allocator, kNoRegNumber, 0, HPhi::ToPhiType(invoke_instruction->GetType()), dex_pc);
    575     merge->AddPhi(phi);
    576     invoke_instruction->ReplaceWith(phi);
    577     phi->AddInput(return_replacement);
    578     phi->AddInput(invoke_instruction);
    579   }
    580 
    581   // Add the control flow instructions.
    582   otherwise->AddInstruction(new (allocator) HGoto(dex_pc));
    583   end_then->AddInstruction(new (allocator) HGoto(dex_pc));
    584   cursor_block->AddInstruction(new (allocator) HIf(compare, dex_pc));
    585 
    586   // Add the newly created blocks to the graph.
    587   graph_->AddBlock(then);
    588   graph_->AddBlock(otherwise);
    589   graph_->AddBlock(merge);
    590 
    591   // Set up successor (and implictly predecessor) relations.
    592   cursor_block->AddSuccessor(otherwise);
    593   cursor_block->AddSuccessor(then);
    594   end_then->AddSuccessor(merge);
    595   otherwise->AddSuccessor(merge);
    596 
    597   // Set up dominance information.
    598   then->SetDominator(cursor_block);
    599   cursor_block->AddDominatedBlock(then);
    600   otherwise->SetDominator(cursor_block);
    601   cursor_block->AddDominatedBlock(otherwise);
    602   merge->SetDominator(cursor_block);
    603   cursor_block->AddDominatedBlock(merge);
    604 
    605   // Update the revert post order.
    606   size_t index = IndexOfElement(graph_->reverse_post_order_, cursor_block);
    607   MakeRoomFor(&graph_->reverse_post_order_, 1, index);
    608   graph_->reverse_post_order_[++index] = then;
    609   index = IndexOfElement(graph_->reverse_post_order_, end_then);
    610   MakeRoomFor(&graph_->reverse_post_order_, 2, index);
    611   graph_->reverse_post_order_[++index] = otherwise;
    612   graph_->reverse_post_order_[++index] = merge;
    613 
    614 
    615   graph_->UpdateLoopAndTryInformationOfNewBlock(
    616       then, original_invoke_block, /* replace_if_back_edge */ false);
    617   graph_->UpdateLoopAndTryInformationOfNewBlock(
    618       otherwise, original_invoke_block, /* replace_if_back_edge */ false);
    619 
    620   // In case the original invoke location was a back edge, we need to update
    621   // the loop to now have the merge block as a back edge.
    622   graph_->UpdateLoopAndTryInformationOfNewBlock(
    623       merge, original_invoke_block, /* replace_if_back_edge */ true);
    624 }
    625 
    626 bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction,
    627                                                     ArtMethod* resolved_method,
    628                                                     const InlineCache& ic) {
    629   // This optimization only works under JIT for now.
    630   DCHECK(Runtime::Current()->UseJitCompilation());
    631   if (graph_->GetInstructionSet() == kMips64) {
    632     // TODO: Support HClassTableGet for mips64.
    633     return false;
    634   }
    635   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
    636   size_t pointer_size = class_linker->GetImagePointerSize();
    637 
    638   DCHECK(resolved_method != nullptr);
    639   ArtMethod* actual_method = nullptr;
    640   size_t method_index = invoke_instruction->IsInvokeVirtual()
    641       ? invoke_instruction->AsInvokeVirtual()->GetVTableIndex()
    642       : invoke_instruction->AsInvokeInterface()->GetImtIndex();
    643 
    644   // Check whether we are actually calling the same method among
    645   // the different types seen.
    646   for (size_t i = 0; i < InlineCache::kIndividualCacheSize; ++i) {
    647     if (ic.GetTypeAt(i) == nullptr) {
    648       break;
    649     }
    650     ArtMethod* new_method = nullptr;
    651     if (invoke_instruction->IsInvokeInterface()) {
    652       new_method = ic.GetTypeAt(i)->GetImt(pointer_size)->Get(
    653           method_index % ImTable::kSize, pointer_size);
    654       if (new_method->IsRuntimeMethod()) {
    655         // Bail out as soon as we see a conflict trampoline in one of the target's
    656         // interface table.
    657         return false;
    658       }
    659     } else {
    660       DCHECK(invoke_instruction->IsInvokeVirtual());
    661       new_method = ic.GetTypeAt(i)->GetEmbeddedVTableEntry(method_index, pointer_size);
    662     }
    663     DCHECK(new_method != nullptr);
    664     if (actual_method == nullptr) {
    665       actual_method = new_method;
    666     } else if (actual_method != new_method) {
    667       // Different methods, bailout.
    668       VLOG(compiler) << "Call to " << PrettyMethod(resolved_method)
    669                      << " from inline cache is not inlined because it resolves"
    670                      << " to different methods";
    671       return false;
    672     }
    673   }
    674 
    675   HInstruction* receiver = invoke_instruction->InputAt(0);
    676   HInstruction* cursor = invoke_instruction->GetPrevious();
    677   HBasicBlock* bb_cursor = invoke_instruction->GetBlock();
    678 
    679   HInstruction* return_replacement = nullptr;
    680   if (!TryBuildAndInline(invoke_instruction, actual_method, &return_replacement)) {
    681     return false;
    682   }
    683 
    684   // We successfully inlined, now add a guard.
    685   HInstanceFieldGet* receiver_class = BuildGetReceiverClass(
    686       class_linker, receiver, invoke_instruction->GetDexPc());
    687 
    688   Primitive::Type type = Is64BitInstructionSet(graph_->GetInstructionSet())
    689       ? Primitive::kPrimLong
    690       : Primitive::kPrimInt;
    691   HClassTableGet* class_table_get = new (graph_->GetArena()) HClassTableGet(
    692       receiver_class,
    693       type,
    694       invoke_instruction->IsInvokeVirtual() ? HClassTableGet::TableKind::kVTable
    695                                             : HClassTableGet::TableKind::kIMTable,
    696       method_index,
    697       invoke_instruction->GetDexPc());
    698 
    699   HConstant* constant;
    700   if (type == Primitive::kPrimLong) {
    701     constant = graph_->GetLongConstant(
    702         reinterpret_cast<intptr_t>(actual_method), invoke_instruction->GetDexPc());
    703   } else {
    704     constant = graph_->GetIntConstant(
    705         reinterpret_cast<intptr_t>(actual_method), invoke_instruction->GetDexPc());
    706   }
    707 
    708   HNotEqual* compare = new (graph_->GetArena()) HNotEqual(class_table_get, constant);
    709   if (cursor != nullptr) {
    710     bb_cursor->InsertInstructionAfter(receiver_class, cursor);
    711   } else {
    712     bb_cursor->InsertInstructionBefore(receiver_class, bb_cursor->GetFirstInstruction());
    713   }
    714   bb_cursor->InsertInstructionAfter(class_table_get, receiver_class);
    715   bb_cursor->InsertInstructionAfter(compare, class_table_get);
    716 
    717   if (outermost_graph_->IsCompilingOsr()) {
    718     CreateDiamondPatternForPolymorphicInline(compare, return_replacement, invoke_instruction);
    719   } else {
    720     // TODO: Extend reference type propagation to understand the guard.
    721     HDeoptimize* deoptimize = new (graph_->GetArena()) HDeoptimize(
    722         compare, invoke_instruction->GetDexPc());
    723     bb_cursor->InsertInstructionAfter(deoptimize, compare);
    724     deoptimize->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
    725     if (return_replacement != nullptr) {
    726       invoke_instruction->ReplaceWith(return_replacement);
    727     }
    728     invoke_instruction->GetBlock()->RemoveInstruction(invoke_instruction);
    729   }
    730 
    731   // Run type propagation to get the guard typed.
    732   ReferenceTypePropagation rtp_fixup(graph_,
    733                                      outer_compilation_unit_.GetDexCache(),
    734                                      handles_,
    735                                      /* is_first_run */ false);
    736   rtp_fixup.Run();
    737 
    738   MaybeRecordStat(kInlinedPolymorphicCall);
    739 
    740   return true;
    741 }
    742 
    743 bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* method, bool do_rtp) {
    744   HInstruction* return_replacement = nullptr;
    745   if (!TryBuildAndInline(invoke_instruction, method, &return_replacement)) {
    746     return false;
    747   }
    748   if (return_replacement != nullptr) {
    749     invoke_instruction->ReplaceWith(return_replacement);
    750   }
    751   invoke_instruction->GetBlock()->RemoveInstruction(invoke_instruction);
    752   FixUpReturnReferenceType(invoke_instruction, method, return_replacement, do_rtp);
    753   return true;
    754 }
    755 
    756 bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction,
    757                                  ArtMethod* method,
    758                                  HInstruction** return_replacement) {
    759   if (method->IsProxyMethod()) {
    760     VLOG(compiler) << "Method " << PrettyMethod(method)
    761                    << " is not inlined because of unimplemented inline support for proxy methods.";
    762     return false;
    763   }
    764 
    765   // Check whether we're allowed to inline. The outermost compilation unit is the relevant
    766   // dex file here (though the transitivity of an inline chain would allow checking the calller).
    767   if (!compiler_driver_->MayInline(method->GetDexFile(),
    768                                    outer_compilation_unit_.GetDexFile())) {
    769     if (TryPatternSubstitution(invoke_instruction, method, return_replacement)) {
    770       VLOG(compiler) << "Successfully replaced pattern of invoke " << PrettyMethod(method);
    771       MaybeRecordStat(kReplacedInvokeWithSimplePattern);
    772       return true;
    773     }
    774     VLOG(compiler) << "Won't inline " << PrettyMethod(method) << " in "
    775                    << outer_compilation_unit_.GetDexFile()->GetLocation() << " ("
    776                    << caller_compilation_unit_.GetDexFile()->GetLocation() << ") from "
    777                    << method->GetDexFile()->GetLocation();
    778     return false;
    779   }
    780 
    781   bool same_dex_file = IsSameDexFile(*outer_compilation_unit_.GetDexFile(), *method->GetDexFile());
    782 
    783   const DexFile::CodeItem* code_item = method->GetCodeItem();
    784 
    785   if (code_item == nullptr) {
    786     VLOG(compiler) << "Method " << PrettyMethod(method)
    787                    << " is not inlined because it is native";
    788     return false;
    789   }
    790 
    791   size_t inline_max_code_units = compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits();
    792   if (code_item->insns_size_in_code_units_ > inline_max_code_units) {
    793     VLOG(compiler) << "Method " << PrettyMethod(method)
    794                    << " is too big to inline: "
    795                    << code_item->insns_size_in_code_units_
    796                    << " > "
    797                    << inline_max_code_units;
    798     return false;
    799   }
    800 
    801   if (code_item->tries_size_ != 0) {
    802     VLOG(compiler) << "Method " << PrettyMethod(method)
    803                    << " is not inlined because of try block";
    804     return false;
    805   }
    806 
    807   if (!method->IsCompilable()) {
    808     VLOG(compiler) << "Method " << PrettyMethod(method)
    809                    << " has soft failures un-handled by the compiler, so it cannot be inlined";
    810   }
    811 
    812   if (!method->GetDeclaringClass()->IsVerified()) {
    813     uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex();
    814     if (Runtime::Current()->UseJitCompilation() ||
    815         !compiler_driver_->IsMethodVerifiedWithoutFailures(
    816             method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) {
    817       VLOG(compiler) << "Method " << PrettyMethod(method)
    818                      << " couldn't be verified, so it cannot be inlined";
    819       return false;
    820     }
    821   }
    822 
    823   if (invoke_instruction->IsInvokeStaticOrDirect() &&
    824       invoke_instruction->AsInvokeStaticOrDirect()->IsStaticWithImplicitClinitCheck()) {
    825     // Case of a static method that cannot be inlined because it implicitly
    826     // requires an initialization check of its declaring class.
    827     VLOG(compiler) << "Method " << PrettyMethod(method)
    828                    << " is not inlined because it is static and requires a clinit"
    829                    << " check that cannot be emitted due to Dex cache limitations";
    830     return false;
    831   }
    832 
    833   if (!TryBuildAndInlineHelper(invoke_instruction, method, same_dex_file, return_replacement)) {
    834     return false;
    835   }
    836 
    837   VLOG(compiler) << "Successfully inlined " << PrettyMethod(method);
    838   MaybeRecordStat(kInlinedInvoke);
    839   return true;
    840 }
    841 
    842 static HInstruction* GetInvokeInputForArgVRegIndex(HInvoke* invoke_instruction,
    843                                                    size_t arg_vreg_index)
    844     SHARED_REQUIRES(Locks::mutator_lock_) {
    845   size_t input_index = 0;
    846   for (size_t i = 0; i < arg_vreg_index; ++i, ++input_index) {
    847     DCHECK_LT(input_index, invoke_instruction->GetNumberOfArguments());
    848     if (Primitive::Is64BitType(invoke_instruction->InputAt(input_index)->GetType())) {
    849       ++i;
    850       DCHECK_NE(i, arg_vreg_index);
    851     }
    852   }
    853   DCHECK_LT(input_index, invoke_instruction->GetNumberOfArguments());
    854   return invoke_instruction->InputAt(input_index);
    855 }
    856 
    857 // Try to recognize known simple patterns and replace invoke call with appropriate instructions.
    858 bool HInliner::TryPatternSubstitution(HInvoke* invoke_instruction,
    859                                       ArtMethod* resolved_method,
    860                                       HInstruction** return_replacement) {
    861   InlineMethod inline_method;
    862   if (!InlineMethodAnalyser::AnalyseMethodCode(resolved_method, &inline_method)) {
    863     return false;
    864   }
    865 
    866   switch (inline_method.opcode) {
    867     case kInlineOpNop:
    868       DCHECK_EQ(invoke_instruction->GetType(), Primitive::kPrimVoid);
    869       *return_replacement = nullptr;
    870       break;
    871     case kInlineOpReturnArg:
    872       *return_replacement = GetInvokeInputForArgVRegIndex(invoke_instruction,
    873                                                           inline_method.d.return_data.arg);
    874       break;
    875     case kInlineOpNonWideConst:
    876       if (resolved_method->GetShorty()[0] == 'L') {
    877         DCHECK_EQ(inline_method.d.data, 0u);
    878         *return_replacement = graph_->GetNullConstant();
    879       } else {
    880         *return_replacement = graph_->GetIntConstant(static_cast<int32_t>(inline_method.d.data));
    881       }
    882       break;
    883     case kInlineOpIGet: {
    884       const InlineIGetIPutData& data = inline_method.d.ifield_data;
    885       if (data.method_is_static || data.object_arg != 0u) {
    886         // TODO: Needs null check.
    887         return false;
    888       }
    889       Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache()));
    890       HInstruction* obj = GetInvokeInputForArgVRegIndex(invoke_instruction, data.object_arg);
    891       HInstanceFieldGet* iget = CreateInstanceFieldGet(dex_cache, data.field_idx, obj);
    892       DCHECK_EQ(iget->GetFieldOffset().Uint32Value(), data.field_offset);
    893       DCHECK_EQ(iget->IsVolatile() ? 1u : 0u, data.is_volatile);
    894       invoke_instruction->GetBlock()->InsertInstructionBefore(iget, invoke_instruction);
    895       *return_replacement = iget;
    896       break;
    897     }
    898     case kInlineOpIPut: {
    899       const InlineIGetIPutData& data = inline_method.d.ifield_data;
    900       if (data.method_is_static || data.object_arg != 0u) {
    901         // TODO: Needs null check.
    902         return false;
    903       }
    904       Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache()));
    905       HInstruction* obj = GetInvokeInputForArgVRegIndex(invoke_instruction, data.object_arg);
    906       HInstruction* value = GetInvokeInputForArgVRegIndex(invoke_instruction, data.src_arg);
    907       HInstanceFieldSet* iput = CreateInstanceFieldSet(dex_cache, data.field_idx, obj, value);
    908       DCHECK_EQ(iput->GetFieldOffset().Uint32Value(), data.field_offset);
    909       DCHECK_EQ(iput->IsVolatile() ? 1u : 0u, data.is_volatile);
    910       invoke_instruction->GetBlock()->InsertInstructionBefore(iput, invoke_instruction);
    911       if (data.return_arg_plus1 != 0u) {
    912         size_t return_arg = data.return_arg_plus1 - 1u;
    913         *return_replacement = GetInvokeInputForArgVRegIndex(invoke_instruction, return_arg);
    914       }
    915       break;
    916     }
    917     case kInlineOpConstructor: {
    918       const InlineConstructorData& data = inline_method.d.constructor_data;
    919       // Get the indexes to arrays for easier processing.
    920       uint16_t iput_field_indexes[] = {
    921           data.iput0_field_index, data.iput1_field_index, data.iput2_field_index
    922       };
    923       uint16_t iput_args[] = { data.iput0_arg, data.iput1_arg, data.iput2_arg };
    924       static_assert(arraysize(iput_args) == arraysize(iput_field_indexes), "Size mismatch");
    925       // Count valid field indexes.
    926       size_t number_of_iputs = 0u;
    927       while (number_of_iputs != arraysize(iput_field_indexes) &&
    928           iput_field_indexes[number_of_iputs] != DexFile::kDexNoIndex16) {
    929         // Check that there are no duplicate valid field indexes.
    930         DCHECK_EQ(0, std::count(iput_field_indexes + number_of_iputs + 1,
    931                                 iput_field_indexes + arraysize(iput_field_indexes),
    932                                 iput_field_indexes[number_of_iputs]));
    933         ++number_of_iputs;
    934       }
    935       // Check that there are no valid field indexes in the rest of the array.
    936       DCHECK_EQ(0, std::count_if(iput_field_indexes + number_of_iputs,
    937                                  iput_field_indexes + arraysize(iput_field_indexes),
    938                                  [](uint16_t index) { return index != DexFile::kDexNoIndex16; }));
    939 
    940       // Create HInstanceFieldSet for each IPUT that stores non-zero data.
    941       Handle<mirror::DexCache> dex_cache;
    942       HInstruction* obj = GetInvokeInputForArgVRegIndex(invoke_instruction, /* this */ 0u);
    943       bool needs_constructor_barrier = false;
    944       for (size_t i = 0; i != number_of_iputs; ++i) {
    945         HInstruction* value = GetInvokeInputForArgVRegIndex(invoke_instruction, iput_args[i]);
    946         if (!value->IsConstant() || !value->AsConstant()->IsZeroBitPattern()) {
    947           if (dex_cache.GetReference() == nullptr) {
    948             dex_cache = handles_->NewHandle(resolved_method->GetDexCache());
    949           }
    950           uint16_t field_index = iput_field_indexes[i];
    951           HInstanceFieldSet* iput = CreateInstanceFieldSet(dex_cache, field_index, obj, value);
    952           invoke_instruction->GetBlock()->InsertInstructionBefore(iput, invoke_instruction);
    953 
    954           // Check whether the field is final. If it is, we need to add a barrier.
    955           size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet());
    956           ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size);
    957           DCHECK(resolved_field != nullptr);
    958           if (resolved_field->IsFinal()) {
    959             needs_constructor_barrier = true;
    960           }
    961         }
    962       }
    963       if (needs_constructor_barrier) {
    964         HMemoryBarrier* barrier = new (graph_->GetArena()) HMemoryBarrier(kStoreStore, kNoDexPc);
    965         invoke_instruction->GetBlock()->InsertInstructionBefore(barrier, invoke_instruction);
    966       }
    967       *return_replacement = nullptr;
    968       break;
    969     }
    970     default:
    971       LOG(FATAL) << "UNREACHABLE";
    972       UNREACHABLE();
    973   }
    974   return true;
    975 }
    976 
    977 HInstanceFieldGet* HInliner::CreateInstanceFieldGet(Handle<mirror::DexCache> dex_cache,
    978                                                     uint32_t field_index,
    979                                                     HInstruction* obj)
    980     SHARED_REQUIRES(Locks::mutator_lock_) {
    981   size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet());
    982   ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size);
    983   DCHECK(resolved_field != nullptr);
    984   HInstanceFieldGet* iget = new (graph_->GetArena()) HInstanceFieldGet(
    985       obj,
    986       resolved_field->GetTypeAsPrimitiveType(),
    987       resolved_field->GetOffset(),
    988       resolved_field->IsVolatile(),
    989       field_index,
    990       resolved_field->GetDeclaringClass()->GetDexClassDefIndex(),
    991       *dex_cache->GetDexFile(),
    992       dex_cache,
    993       // Read barrier generates a runtime call in slow path and we need a valid
    994       // dex pc for the associated stack map. 0 is bogus but valid. Bug: 26854537.
    995       /* dex_pc */ 0);
    996   if (iget->GetType() == Primitive::kPrimNot) {
    997     // Use the same dex_cache that we used for field lookup as the hint_dex_cache.
    998     ReferenceTypePropagation rtp(graph_, dex_cache, handles_, /* is_first_run */ false);
    999     rtp.Visit(iget);
   1000   }
   1001   return iget;
   1002 }
   1003 
   1004 HInstanceFieldSet* HInliner::CreateInstanceFieldSet(Handle<mirror::DexCache> dex_cache,
   1005                                                     uint32_t field_index,
   1006                                                     HInstruction* obj,
   1007                                                     HInstruction* value)
   1008     SHARED_REQUIRES(Locks::mutator_lock_) {
   1009   size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet());
   1010   ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size);
   1011   DCHECK(resolved_field != nullptr);
   1012   HInstanceFieldSet* iput = new (graph_->GetArena()) HInstanceFieldSet(
   1013       obj,
   1014       value,
   1015       resolved_field->GetTypeAsPrimitiveType(),
   1016       resolved_field->GetOffset(),
   1017       resolved_field->IsVolatile(),
   1018       field_index,
   1019       resolved_field->GetDeclaringClass()->GetDexClassDefIndex(),
   1020       *dex_cache->GetDexFile(),
   1021       dex_cache,
   1022       // Read barrier generates a runtime call in slow path and we need a valid
   1023       // dex pc for the associated stack map. 0 is bogus but valid. Bug: 26854537.
   1024       /* dex_pc */ 0);
   1025   return iput;
   1026 }
   1027 
   1028 bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction,
   1029                                        ArtMethod* resolved_method,
   1030                                        bool same_dex_file,
   1031                                        HInstruction** return_replacement) {
   1032   ScopedObjectAccess soa(Thread::Current());
   1033   const DexFile::CodeItem* code_item = resolved_method->GetCodeItem();
   1034   const DexFile& callee_dex_file = *resolved_method->GetDexFile();
   1035   uint32_t method_index = resolved_method->GetDexMethodIndex();
   1036   ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
   1037   Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache()));
   1038   Handle<mirror::ClassLoader> class_loader(handles_->NewHandle(
   1039       resolved_method->GetDeclaringClass()->GetClassLoader()));
   1040 
   1041   DexCompilationUnit dex_compilation_unit(
   1042       class_loader.ToJObject(),
   1043       class_linker,
   1044       callee_dex_file,
   1045       code_item,
   1046       resolved_method->GetDeclaringClass()->GetDexClassDefIndex(),
   1047       method_index,
   1048       resolved_method->GetAccessFlags(),
   1049       /* verified_method */ nullptr,
   1050       dex_cache);
   1051 
   1052   bool requires_ctor_barrier = false;
   1053 
   1054   if (dex_compilation_unit.IsConstructor()) {
   1055     // If it's a super invocation and we already generate a barrier there's no need
   1056     // to generate another one.
   1057     // We identify super calls by looking at the "this" pointer. If its value is the
   1058     // same as the local "this" pointer then we must have a super invocation.
   1059     bool is_super_invocation = invoke_instruction->InputAt(0)->IsParameterValue()
   1060         && invoke_instruction->InputAt(0)->AsParameterValue()->IsThis();
   1061     if (is_super_invocation && graph_->ShouldGenerateConstructorBarrier()) {
   1062       requires_ctor_barrier = false;
   1063     } else {
   1064       Thread* self = Thread::Current();
   1065       requires_ctor_barrier = compiler_driver_->RequiresConstructorBarrier(self,
   1066           dex_compilation_unit.GetDexFile(),
   1067           dex_compilation_unit.GetClassDefIndex());
   1068     }
   1069   }
   1070 
   1071   InvokeType invoke_type = invoke_instruction->GetOriginalInvokeType();
   1072   if (invoke_type == kInterface) {
   1073     // We have statically resolved the dispatch. To please the class linker
   1074     // at runtime, we change this call as if it was a virtual call.
   1075     invoke_type = kVirtual;
   1076   }
   1077 
   1078   const int32_t caller_instruction_counter = graph_->GetCurrentInstructionId();
   1079   HGraph* callee_graph = new (graph_->GetArena()) HGraph(
   1080       graph_->GetArena(),
   1081       callee_dex_file,
   1082       method_index,
   1083       requires_ctor_barrier,
   1084       compiler_driver_->GetInstructionSet(),
   1085       invoke_type,
   1086       graph_->IsDebuggable(),
   1087       /* osr */ false,
   1088       caller_instruction_counter);
   1089   callee_graph->SetArtMethod(resolved_method);
   1090 
   1091   // When they are needed, allocate `inline_stats` on the heap instead
   1092   // of on the stack, as Clang might produce a stack frame too large
   1093   // for this function, that would not fit the requirements of the
   1094   // `-Wframe-larger-than` option.
   1095   std::unique_ptr<OptimizingCompilerStats> inline_stats =
   1096       (stats_ == nullptr) ? nullptr : MakeUnique<OptimizingCompilerStats>();
   1097   HGraphBuilder builder(callee_graph,
   1098                         &dex_compilation_unit,
   1099                         &outer_compilation_unit_,
   1100                         resolved_method->GetDexFile(),
   1101                         *code_item,
   1102                         compiler_driver_,
   1103                         inline_stats.get(),
   1104                         resolved_method->GetQuickenedInfo(),
   1105                         dex_cache,
   1106                         handles_);
   1107 
   1108   if (builder.BuildGraph() != kAnalysisSuccess) {
   1109     VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1110                    << " could not be built, so cannot be inlined";
   1111     return false;
   1112   }
   1113 
   1114   if (!RegisterAllocator::CanAllocateRegistersFor(*callee_graph,
   1115                                                   compiler_driver_->GetInstructionSet())) {
   1116     VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1117                    << " cannot be inlined because of the register allocator";
   1118     return false;
   1119   }
   1120 
   1121   size_t parameter_index = 0;
   1122   for (HInstructionIterator instructions(callee_graph->GetEntryBlock()->GetInstructions());
   1123        !instructions.Done();
   1124        instructions.Advance()) {
   1125     HInstruction* current = instructions.Current();
   1126     if (current->IsParameterValue()) {
   1127       HInstruction* argument = invoke_instruction->InputAt(parameter_index++);
   1128       if (argument->IsNullConstant()) {
   1129         current->ReplaceWith(callee_graph->GetNullConstant());
   1130       } else if (argument->IsIntConstant()) {
   1131         current->ReplaceWith(callee_graph->GetIntConstant(argument->AsIntConstant()->GetValue()));
   1132       } else if (argument->IsLongConstant()) {
   1133         current->ReplaceWith(callee_graph->GetLongConstant(argument->AsLongConstant()->GetValue()));
   1134       } else if (argument->IsFloatConstant()) {
   1135         current->ReplaceWith(
   1136             callee_graph->GetFloatConstant(argument->AsFloatConstant()->GetValue()));
   1137       } else if (argument->IsDoubleConstant()) {
   1138         current->ReplaceWith(
   1139             callee_graph->GetDoubleConstant(argument->AsDoubleConstant()->GetValue()));
   1140       } else if (argument->GetType() == Primitive::kPrimNot) {
   1141         current->SetReferenceTypeInfo(argument->GetReferenceTypeInfo());
   1142         current->AsParameterValue()->SetCanBeNull(argument->CanBeNull());
   1143       }
   1144     }
   1145   }
   1146 
   1147   size_t number_of_instructions_budget = kMaximumNumberOfHInstructions;
   1148   size_t number_of_inlined_instructions =
   1149       RunOptimizations(callee_graph, code_item, dex_compilation_unit);
   1150   number_of_instructions_budget += number_of_inlined_instructions;
   1151 
   1152   // TODO: We should abort only if all predecessors throw. However,
   1153   // HGraph::InlineInto currently does not handle an exit block with
   1154   // a throw predecessor.
   1155   HBasicBlock* exit_block = callee_graph->GetExitBlock();
   1156   if (exit_block == nullptr) {
   1157     VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1158                    << " could not be inlined because it has an infinite loop";
   1159     return false;
   1160   }
   1161 
   1162   bool has_throw_predecessor = false;
   1163   for (HBasicBlock* predecessor : exit_block->GetPredecessors()) {
   1164     if (predecessor->GetLastInstruction()->IsThrow()) {
   1165       has_throw_predecessor = true;
   1166       break;
   1167     }
   1168   }
   1169   if (has_throw_predecessor) {
   1170     VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1171                    << " could not be inlined because one branch always throws";
   1172     return false;
   1173   }
   1174 
   1175   HReversePostOrderIterator it(*callee_graph);
   1176   it.Advance();  // Past the entry block, it does not contain instructions that prevent inlining.
   1177   size_t number_of_instructions = 0;
   1178 
   1179   bool can_inline_environment =
   1180       total_number_of_dex_registers_ < kMaximumNumberOfCumulatedDexRegisters;
   1181 
   1182   for (; !it.Done(); it.Advance()) {
   1183     HBasicBlock* block = it.Current();
   1184 
   1185     if (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible()) {
   1186       // Don't inline methods with irreducible loops, they could prevent some
   1187       // optimizations to run.
   1188       VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1189                      << " could not be inlined because it contains an irreducible loop";
   1190       return false;
   1191     }
   1192 
   1193     for (HInstructionIterator instr_it(block->GetInstructions());
   1194          !instr_it.Done();
   1195          instr_it.Advance()) {
   1196       if (number_of_instructions++ == number_of_instructions_budget) {
   1197         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1198                        << " is not inlined because its caller has reached"
   1199                        << " its instruction budget limit.";
   1200         return false;
   1201       }
   1202       HInstruction* current = instr_it.Current();
   1203       if (!can_inline_environment && current->NeedsEnvironment()) {
   1204         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1205                        << " is not inlined because its caller has reached"
   1206                        << " its environment budget limit.";
   1207         return false;
   1208       }
   1209 
   1210       if (current->IsInvokeInterface()) {
   1211         // Disable inlining of interface calls. The cost in case of entering the
   1212         // resolution conflict is currently too high.
   1213         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1214                        << " could not be inlined because it has an interface call.";
   1215         return false;
   1216       }
   1217 
   1218       if (!same_dex_file && current->NeedsEnvironment()) {
   1219         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1220                        << " could not be inlined because " << current->DebugName()
   1221                        << " needs an environment and is in a different dex file";
   1222         return false;
   1223       }
   1224 
   1225       if (!same_dex_file && current->NeedsDexCacheOfDeclaringClass()) {
   1226         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1227                        << " could not be inlined because " << current->DebugName()
   1228                        << " it is in a different dex file and requires access to the dex cache";
   1229         return false;
   1230       }
   1231 
   1232       if (current->IsNewInstance() &&
   1233           (current->AsNewInstance()->GetEntrypoint() == kQuickAllocObjectWithAccessCheck)) {
   1234         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1235                        << " could not be inlined because it is using an entrypoint"
   1236                        << " with access checks";
   1237         // Allocation entrypoint does not handle inlined frames.
   1238         return false;
   1239       }
   1240 
   1241       if (current->IsNewArray() &&
   1242           (current->AsNewArray()->GetEntrypoint() == kQuickAllocArrayWithAccessCheck)) {
   1243         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1244                        << " could not be inlined because it is using an entrypoint"
   1245                        << " with access checks";
   1246         // Allocation entrypoint does not handle inlined frames.
   1247         return false;
   1248       }
   1249 
   1250       if (current->IsUnresolvedStaticFieldGet() ||
   1251           current->IsUnresolvedInstanceFieldGet() ||
   1252           current->IsUnresolvedStaticFieldSet() ||
   1253           current->IsUnresolvedInstanceFieldSet()) {
   1254         // Entrypoint for unresolved fields does not handle inlined frames.
   1255         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
   1256                        << " could not be inlined because it is using an unresolved"
   1257                        << " entrypoint";
   1258         return false;
   1259       }
   1260     }
   1261   }
   1262   number_of_inlined_instructions_ += number_of_instructions;
   1263 
   1264   DCHECK_EQ(caller_instruction_counter, graph_->GetCurrentInstructionId())
   1265       << "No instructions can be added to the outer graph while inner graph is being built";
   1266 
   1267   const int32_t callee_instruction_counter = callee_graph->GetCurrentInstructionId();
   1268   graph_->SetCurrentInstructionId(callee_instruction_counter);
   1269   *return_replacement = callee_graph->InlineInto(graph_, invoke_instruction);
   1270 
   1271   DCHECK_EQ(callee_instruction_counter, callee_graph->GetCurrentInstructionId())
   1272       << "No instructions can be added to the inner graph during inlining into the outer graph";
   1273 
   1274   return true;
   1275 }
   1276 
   1277 size_t HInliner::RunOptimizations(HGraph* callee_graph,
   1278                                   const DexFile::CodeItem* code_item,
   1279                                   const DexCompilationUnit& dex_compilation_unit) {
   1280   // Note: if the outermost_graph_ is being compiled OSR, we should not run any
   1281   // optimization that could lead to a HDeoptimize. The following optimizations do not.
   1282   HDeadCodeElimination dce(callee_graph, stats_);
   1283   HConstantFolding fold(callee_graph);
   1284   HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_);
   1285   InstructionSimplifier simplify(callee_graph, stats_);
   1286   IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_, stats_);
   1287 
   1288   HOptimization* optimizations[] = {
   1289     &intrinsics,
   1290     &sharpening,
   1291     &simplify,
   1292     &fold,
   1293     &dce,
   1294   };
   1295 
   1296   for (size_t i = 0; i < arraysize(optimizations); ++i) {
   1297     HOptimization* optimization = optimizations[i];
   1298     optimization->Run();
   1299   }
   1300 
   1301   size_t number_of_inlined_instructions = 0u;
   1302   if (depth_ + 1 < compiler_driver_->GetCompilerOptions().GetInlineDepthLimit()) {
   1303     HInliner inliner(callee_graph,
   1304                      outermost_graph_,
   1305                      codegen_,
   1306                      outer_compilation_unit_,
   1307                      dex_compilation_unit,
   1308                      compiler_driver_,
   1309                      handles_,
   1310                      stats_,
   1311                      total_number_of_dex_registers_ + code_item->registers_size_,
   1312                      depth_ + 1);
   1313     inliner.Run();
   1314     number_of_inlined_instructions += inliner.number_of_inlined_instructions_;
   1315   }
   1316 
   1317   return number_of_inlined_instructions;
   1318 }
   1319 
   1320 void HInliner::FixUpReturnReferenceType(HInvoke* invoke_instruction,
   1321                                         ArtMethod* resolved_method,
   1322                                         HInstruction* return_replacement,
   1323                                         bool do_rtp) {
   1324   // Check the integrity of reference types and run another type propagation if needed.
   1325   if (return_replacement != nullptr) {
   1326     if (return_replacement->GetType() == Primitive::kPrimNot) {
   1327       if (!return_replacement->GetReferenceTypeInfo().IsValid()) {
   1328         // Make sure that we have a valid type for the return. We may get an invalid one when
   1329         // we inline invokes with multiple branches and create a Phi for the result.
   1330         // TODO: we could be more precise by merging the phi inputs but that requires
   1331         // some functionality from the reference type propagation.
   1332         DCHECK(return_replacement->IsPhi());
   1333         size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
   1334         mirror::Class* cls = resolved_method->GetReturnType(false /* resolve */, pointer_size);
   1335         if (cls != nullptr && !cls->IsErroneous()) {
   1336           ReferenceTypeInfo::TypeHandle return_handle = handles_->NewHandle(cls);
   1337           return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create(
   1338               return_handle, return_handle->CannotBeAssignedFromOtherTypes() /* is_exact */));
   1339         } else {
   1340           // Return inexact object type on failures.
   1341           return_replacement->SetReferenceTypeInfo(graph_->GetInexactObjectRti());
   1342         }
   1343       }
   1344 
   1345       if (do_rtp) {
   1346         // If the return type is a refinement of the declared type run the type propagation again.
   1347         ReferenceTypeInfo return_rti = return_replacement->GetReferenceTypeInfo();
   1348         ReferenceTypeInfo invoke_rti = invoke_instruction->GetReferenceTypeInfo();
   1349         if (invoke_rti.IsStrictSupertypeOf(return_rti)
   1350             || (return_rti.IsExact() && !invoke_rti.IsExact())
   1351             || !return_replacement->CanBeNull()) {
   1352           ReferenceTypePropagation(graph_,
   1353                                    outer_compilation_unit_.GetDexCache(),
   1354                                    handles_,
   1355                                    /* is_first_run */ false).Run();
   1356         }
   1357       }
   1358     } else if (return_replacement->IsInstanceOf()) {
   1359       if (do_rtp) {
   1360         // Inlining InstanceOf into an If may put a tighter bound on reference types.
   1361         ReferenceTypePropagation(graph_,
   1362                                  outer_compilation_unit_.GetDexCache(),
   1363                                  handles_,
   1364                                  /* is_first_run */ false).Run();
   1365       }
   1366     }
   1367   }
   1368 }
   1369 
   1370 }  // namespace art
   1371