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 "builder.h"
     18 
     19 #include "art_field-inl.h"
     20 #include "base/logging.h"
     21 #include "class_linker.h"
     22 #include "dex/verified_method.h"
     23 #include "dex_file-inl.h"
     24 #include "dex_instruction-inl.h"
     25 #include "dex/verified_method.h"
     26 #include "driver/compiler_driver-inl.h"
     27 #include "driver/compiler_options.h"
     28 #include "mirror/class_loader.h"
     29 #include "mirror/dex_cache.h"
     30 #include "nodes.h"
     31 #include "primitive.h"
     32 #include "scoped_thread_state_change.h"
     33 #include "thread.h"
     34 
     35 namespace art {
     36 
     37 /**
     38  * Helper class to add HTemporary instructions. This class is used when
     39  * converting a DEX instruction to multiple HInstruction, and where those
     40  * instructions do not die at the following instruction, but instead spans
     41  * multiple instructions.
     42  */
     43 class Temporaries : public ValueObject {
     44  public:
     45   explicit Temporaries(HGraph* graph) : graph_(graph), index_(0) {}
     46 
     47   void Add(HInstruction* instruction) {
     48     HInstruction* temp = new (graph_->GetArena()) HTemporary(index_);
     49     instruction->GetBlock()->AddInstruction(temp);
     50 
     51     DCHECK(temp->GetPrevious() == instruction);
     52 
     53     size_t offset;
     54     if (instruction->GetType() == Primitive::kPrimLong
     55         || instruction->GetType() == Primitive::kPrimDouble) {
     56       offset = 2;
     57     } else {
     58       offset = 1;
     59     }
     60     index_ += offset;
     61 
     62     graph_->UpdateTemporariesVRegSlots(index_);
     63   }
     64 
     65  private:
     66   HGraph* const graph_;
     67 
     68   // Current index in the temporary stack, updated by `Add`.
     69   size_t index_;
     70 };
     71 
     72 class SwitchTable : public ValueObject {
     73  public:
     74   SwitchTable(const Instruction& instruction, uint32_t dex_pc, bool sparse)
     75       : instruction_(instruction), dex_pc_(dex_pc), sparse_(sparse) {
     76     int32_t table_offset = instruction.VRegB_31t();
     77     const uint16_t* table = reinterpret_cast<const uint16_t*>(&instruction) + table_offset;
     78     if (sparse) {
     79       CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
     80     } else {
     81       CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
     82     }
     83     num_entries_ = table[1];
     84     values_ = reinterpret_cast<const int32_t*>(&table[2]);
     85   }
     86 
     87   uint16_t GetNumEntries() const {
     88     return num_entries_;
     89   }
     90 
     91   void CheckIndex(size_t index) const {
     92     if (sparse_) {
     93       // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order.
     94       DCHECK_LT(index, 2 * static_cast<size_t>(num_entries_));
     95     } else {
     96       // In a packed table, we have the starting key and num_entries_ values.
     97       DCHECK_LT(index, 1 + static_cast<size_t>(num_entries_));
     98     }
     99   }
    100 
    101   int32_t GetEntryAt(size_t index) const {
    102     CheckIndex(index);
    103     return values_[index];
    104   }
    105 
    106   uint32_t GetDexPcForIndex(size_t index) const {
    107     CheckIndex(index);
    108     return dex_pc_ +
    109         (reinterpret_cast<const int16_t*>(values_ + index) -
    110          reinterpret_cast<const int16_t*>(&instruction_));
    111   }
    112 
    113   // Index of the first value in the table.
    114   size_t GetFirstValueIndex() const {
    115     if (sparse_) {
    116       // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order.
    117       return num_entries_;
    118     } else {
    119       // In a packed table, we have the starting key and num_entries_ values.
    120       return 1;
    121     }
    122   }
    123 
    124  private:
    125   const Instruction& instruction_;
    126   const uint32_t dex_pc_;
    127 
    128   // Whether this is a sparse-switch table (or a packed-switch one).
    129   const bool sparse_;
    130 
    131   // This can't be const as it needs to be computed off of the given instruction, and complicated
    132   // expressions in the initializer list seemed very ugly.
    133   uint16_t num_entries_;
    134 
    135   const int32_t* values_;
    136 
    137   DISALLOW_COPY_AND_ASSIGN(SwitchTable);
    138 };
    139 
    140 void HGraphBuilder::InitializeLocals(uint16_t count) {
    141   graph_->SetNumberOfVRegs(count);
    142   locals_.SetSize(count);
    143   for (int i = 0; i < count; i++) {
    144     HLocal* local = new (arena_) HLocal(i);
    145     entry_block_->AddInstruction(local);
    146     locals_.Put(i, local);
    147   }
    148 }
    149 
    150 void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
    151   // dex_compilation_unit_ is null only when unit testing.
    152   if (dex_compilation_unit_ == nullptr) {
    153     return;
    154   }
    155 
    156   graph_->SetNumberOfInVRegs(number_of_parameters);
    157   const char* shorty = dex_compilation_unit_->GetShorty();
    158   int locals_index = locals_.Size() - number_of_parameters;
    159   int parameter_index = 0;
    160 
    161   if (!dex_compilation_unit_->IsStatic()) {
    162     // Add the implicit 'this' argument, not expressed in the signature.
    163     HParameterValue* parameter =
    164         new (arena_) HParameterValue(parameter_index++, Primitive::kPrimNot, true);
    165     entry_block_->AddInstruction(parameter);
    166     HLocal* local = GetLocalAt(locals_index++);
    167     entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter));
    168     number_of_parameters--;
    169   }
    170 
    171   uint32_t pos = 1;
    172   for (int i = 0; i < number_of_parameters; i++) {
    173     HParameterValue* parameter =
    174         new (arena_) HParameterValue(parameter_index++, Primitive::GetType(shorty[pos++]));
    175     entry_block_->AddInstruction(parameter);
    176     HLocal* local = GetLocalAt(locals_index++);
    177     // Store the parameter value in the local that the dex code will use
    178     // to reference that parameter.
    179     entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter));
    180     bool is_wide = (parameter->GetType() == Primitive::kPrimLong)
    181         || (parameter->GetType() == Primitive::kPrimDouble);
    182     if (is_wide) {
    183       i++;
    184       locals_index++;
    185       parameter_index++;
    186     }
    187   }
    188 }
    189 
    190 template<typename T>
    191 void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) {
    192   int32_t target_offset = instruction.GetTargetOffset();
    193   HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset);
    194   HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
    195   DCHECK(branch_target != nullptr);
    196   DCHECK(fallthrough_target != nullptr);
    197   PotentiallyAddSuspendCheck(branch_target, dex_pc);
    198   HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
    199   HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    200   T* comparison = new (arena_) T(first, second);
    201   current_block_->AddInstruction(comparison);
    202   HInstruction* ifinst = new (arena_) HIf(comparison);
    203   current_block_->AddInstruction(ifinst);
    204   current_block_->AddSuccessor(branch_target);
    205   current_block_->AddSuccessor(fallthrough_target);
    206   current_block_ = nullptr;
    207 }
    208 
    209 template<typename T>
    210 void HGraphBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) {
    211   int32_t target_offset = instruction.GetTargetOffset();
    212   HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset);
    213   HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
    214   DCHECK(branch_target != nullptr);
    215   DCHECK(fallthrough_target != nullptr);
    216   PotentiallyAddSuspendCheck(branch_target, dex_pc);
    217   HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
    218   T* comparison = new (arena_) T(value, graph_->GetIntConstant(0));
    219   current_block_->AddInstruction(comparison);
    220   HInstruction* ifinst = new (arena_) HIf(comparison);
    221   current_block_->AddInstruction(ifinst);
    222   current_block_->AddSuccessor(branch_target);
    223   current_block_->AddSuccessor(fallthrough_target);
    224   current_block_ = nullptr;
    225 }
    226 
    227 void HGraphBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) {
    228   if (compilation_stats_ != nullptr) {
    229     compilation_stats_->RecordStat(compilation_stat);
    230   }
    231 }
    232 
    233 bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item,
    234                                     size_t number_of_branches) {
    235   const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
    236   CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
    237   if (compiler_filter == CompilerOptions::kEverything) {
    238     return false;
    239   }
    240 
    241   if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) {
    242     VLOG(compiler) << "Skip compilation of huge method "
    243                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
    244                    << ": " << code_item.insns_size_in_code_units_ << " code units";
    245     MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod);
    246     return true;
    247   }
    248 
    249   // If it's large and contains no branches, it's likely to be machine generated initialization.
    250   if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_)
    251       && (number_of_branches == 0)) {
    252     VLOG(compiler) << "Skip compilation of large method with no branch "
    253                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
    254                    << ": " << code_item.insns_size_in_code_units_ << " code units";
    255     MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
    256     return true;
    257   }
    258 
    259   return false;
    260 }
    261 
    262 bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
    263   DCHECK(graph_->GetBlocks().IsEmpty());
    264 
    265   const uint16_t* code_ptr = code_item.insns_;
    266   const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
    267   code_start_ = code_ptr;
    268 
    269   // Setup the graph with the entry block and exit block.
    270   entry_block_ = new (arena_) HBasicBlock(graph_, 0);
    271   graph_->AddBlock(entry_block_);
    272   exit_block_ = new (arena_) HBasicBlock(graph_, kNoDexPc);
    273   graph_->SetEntryBlock(entry_block_);
    274   graph_->SetExitBlock(exit_block_);
    275 
    276   InitializeLocals(code_item.registers_size_);
    277   graph_->SetMaximumNumberOfOutVRegs(code_item.outs_size_);
    278 
    279   // Compute the number of dex instructions, blocks, and branches. We will
    280   // check these values against limits given to the compiler.
    281   size_t number_of_branches = 0;
    282 
    283   // To avoid splitting blocks, we compute ahead of time the instructions that
    284   // start a new block, and create these blocks.
    285   if (!ComputeBranchTargets(code_ptr, code_end, &number_of_branches)) {
    286     MaybeRecordStat(MethodCompilationStat::kNotCompiledBranchOutsideMethodCode);
    287     return false;
    288   }
    289 
    290   // Note that the compiler driver is null when unit testing.
    291   if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) {
    292     return false;
    293   }
    294 
    295   // Also create blocks for catch handlers.
    296   if (code_item.tries_size_ != 0) {
    297     const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0);
    298     uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
    299     for (uint32_t idx = 0; idx < handlers_size; ++idx) {
    300       CatchHandlerIterator iterator(handlers_ptr);
    301       for (; iterator.HasNext(); iterator.Next()) {
    302         uint32_t address = iterator.GetHandlerAddress();
    303         HBasicBlock* block = FindBlockStartingAt(address);
    304         if (block == nullptr) {
    305           block = new (arena_) HBasicBlock(graph_, address);
    306           branch_targets_.Put(address, block);
    307         }
    308         block->SetIsCatchBlock();
    309       }
    310       handlers_ptr = iterator.EndDataPointer();
    311     }
    312   }
    313 
    314   InitializeParameters(code_item.ins_size_);
    315 
    316   size_t dex_pc = 0;
    317   while (code_ptr < code_end) {
    318     // Update the current block if dex_pc starts a new block.
    319     MaybeUpdateCurrentBlock(dex_pc);
    320     const Instruction& instruction = *Instruction::At(code_ptr);
    321     if (!AnalyzeDexInstruction(instruction, dex_pc)) {
    322       return false;
    323     }
    324     dex_pc += instruction.SizeInCodeUnits();
    325     code_ptr += instruction.SizeInCodeUnits();
    326   }
    327 
    328   // Add the exit block at the end to give it the highest id.
    329   graph_->AddBlock(exit_block_);
    330   exit_block_->AddInstruction(new (arena_) HExit());
    331   // Add the suspend check to the entry block.
    332   entry_block_->AddInstruction(new (arena_) HSuspendCheck(0));
    333   entry_block_->AddInstruction(new (arena_) HGoto());
    334 
    335   return true;
    336 }
    337 
    338 void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
    339   HBasicBlock* block = FindBlockStartingAt(index);
    340   if (block == nullptr) {
    341     return;
    342   }
    343 
    344   if (current_block_ != nullptr) {
    345     // Branching instructions clear current_block, so we know
    346     // the last instruction of the current block is not a branching
    347     // instruction. We add an unconditional goto to the found block.
    348     current_block_->AddInstruction(new (arena_) HGoto());
    349     current_block_->AddSuccessor(block);
    350   }
    351   graph_->AddBlock(block);
    352   current_block_ = block;
    353 }
    354 
    355 bool HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
    356                                          const uint16_t* code_end,
    357                                          size_t* number_of_branches) {
    358   branch_targets_.SetSize(code_end - code_ptr);
    359 
    360   // Create the first block for the dex instructions, single successor of the entry block.
    361   HBasicBlock* block = new (arena_) HBasicBlock(graph_, 0);
    362   branch_targets_.Put(0, block);
    363   entry_block_->AddSuccessor(block);
    364 
    365   // Iterate over all instructions and find branching instructions. Create blocks for
    366   // the locations these instructions branch to.
    367   uint32_t dex_pc = 0;
    368   while (code_ptr < code_end) {
    369     const Instruction& instruction = *Instruction::At(code_ptr);
    370     if (instruction.IsBranch()) {
    371       (*number_of_branches)++;
    372       int32_t target = instruction.GetTargetOffset() + dex_pc;
    373       // Create a block for the target instruction.
    374       if (FindBlockStartingAt(target) == nullptr) {
    375         block = new (arena_) HBasicBlock(graph_, target);
    376         branch_targets_.Put(target, block);
    377       }
    378       dex_pc += instruction.SizeInCodeUnits();
    379       code_ptr += instruction.SizeInCodeUnits();
    380 
    381       if (code_ptr >= code_end) {
    382         if (instruction.CanFlowThrough()) {
    383           // In the normal case we should never hit this but someone can artificially forge a dex
    384           // file to fall-through out the method code. In this case we bail out compilation.
    385           return false;
    386         }
    387       } else if (FindBlockStartingAt(dex_pc) == nullptr) {
    388         block = new (arena_) HBasicBlock(graph_, dex_pc);
    389         branch_targets_.Put(dex_pc, block);
    390       }
    391     } else if (instruction.IsSwitch()) {
    392       SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
    393 
    394       uint16_t num_entries = table.GetNumEntries();
    395 
    396       // In a packed-switch, the entry at index 0 is the starting key. In a sparse-switch, the
    397       // entry at index 0 is the first key, and values are after *all* keys.
    398       size_t offset = table.GetFirstValueIndex();
    399 
    400       // Use a larger loop counter type to avoid overflow issues.
    401       for (size_t i = 0; i < num_entries; ++i) {
    402         // The target of the case.
    403         uint32_t target = dex_pc + table.GetEntryAt(i + offset);
    404         if (FindBlockStartingAt(target) == nullptr) {
    405           block = new (arena_) HBasicBlock(graph_, target);
    406           branch_targets_.Put(target, block);
    407         }
    408 
    409         // The next case gets its own block.
    410         if (i < num_entries) {
    411           block = new (arena_) HBasicBlock(graph_, target);
    412           branch_targets_.Put(table.GetDexPcForIndex(i), block);
    413         }
    414       }
    415 
    416       // Fall-through. Add a block if there is more code afterwards.
    417       dex_pc += instruction.SizeInCodeUnits();
    418       code_ptr += instruction.SizeInCodeUnits();
    419       if (code_ptr >= code_end) {
    420         // In the normal case we should never hit this but someone can artificially forge a dex
    421         // file to fall-through out the method code. In this case we bail out compilation.
    422         // (A switch can fall-through so we don't need to check CanFlowThrough().)
    423         return false;
    424       } else if (FindBlockStartingAt(dex_pc) == nullptr) {
    425         block = new (arena_) HBasicBlock(graph_, dex_pc);
    426         branch_targets_.Put(dex_pc, block);
    427       }
    428     } else {
    429       code_ptr += instruction.SizeInCodeUnits();
    430       dex_pc += instruction.SizeInCodeUnits();
    431     }
    432   }
    433   return true;
    434 }
    435 
    436 HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t index) const {
    437   DCHECK_GE(index, 0);
    438   return branch_targets_.Get(index);
    439 }
    440 
    441 template<typename T>
    442 void HGraphBuilder::Unop_12x(const Instruction& instruction, Primitive::Type type) {
    443   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    444   current_block_->AddInstruction(new (arena_) T(type, first));
    445   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    446 }
    447 
    448 void HGraphBuilder::Conversion_12x(const Instruction& instruction,
    449                                    Primitive::Type input_type,
    450                                    Primitive::Type result_type,
    451                                    uint32_t dex_pc) {
    452   HInstruction* first = LoadLocal(instruction.VRegB(), input_type);
    453   current_block_->AddInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc));
    454   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    455 }
    456 
    457 template<typename T>
    458 void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type) {
    459   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    460   HInstruction* second = LoadLocal(instruction.VRegC(), type);
    461   current_block_->AddInstruction(new (arena_) T(type, first, second));
    462   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    463 }
    464 
    465 template<typename T>
    466 void HGraphBuilder::Binop_23x(const Instruction& instruction,
    467                               Primitive::Type type,
    468                               uint32_t dex_pc) {
    469   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    470   HInstruction* second = LoadLocal(instruction.VRegC(), type);
    471   current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc));
    472   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    473 }
    474 
    475 template<typename T>
    476 void HGraphBuilder::Binop_23x_shift(const Instruction& instruction,
    477                                     Primitive::Type type) {
    478   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    479   HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt);
    480   current_block_->AddInstruction(new (arena_) T(type, first, second));
    481   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    482 }
    483 
    484 void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction,
    485                                   Primitive::Type type,
    486                                   HCompare::Bias bias,
    487                                   uint32_t dex_pc) {
    488   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    489   HInstruction* second = LoadLocal(instruction.VRegC(), type);
    490   current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc));
    491   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    492 }
    493 
    494 template<typename T>
    495 void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) {
    496   HInstruction* first = LoadLocal(instruction.VRegA(), type);
    497   HInstruction* second = LoadLocal(instruction.VRegB(), type);
    498   current_block_->AddInstruction(new (arena_) T(type, first, second));
    499   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    500 }
    501 
    502 template<typename T>
    503 void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type) {
    504   HInstruction* first = LoadLocal(instruction.VRegA(), type);
    505   HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    506   current_block_->AddInstruction(new (arena_) T(type, first, second));
    507   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    508 }
    509 
    510 template<typename T>
    511 void HGraphBuilder::Binop_12x(const Instruction& instruction,
    512                               Primitive::Type type,
    513                               uint32_t dex_pc) {
    514   HInstruction* first = LoadLocal(instruction.VRegA(), type);
    515   HInstruction* second = LoadLocal(instruction.VRegB(), type);
    516   current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc));
    517   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    518 }
    519 
    520 template<typename T>
    521 void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse) {
    522   HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    523   HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s());
    524   if (reverse) {
    525     std::swap(first, second);
    526   }
    527   current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second));
    528   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    529 }
    530 
    531 template<typename T>
    532 void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse) {
    533   HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    534   HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b());
    535   if (reverse) {
    536     std::swap(first, second);
    537   }
    538   current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second));
    539   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    540 }
    541 
    542 static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, const CompilerDriver& driver) {
    543   // dex compilation unit is null only when unit testing.
    544   if (cu == nullptr) {
    545     return false;
    546   }
    547 
    548   Thread* self = Thread::Current();
    549   return cu->IsConstructor()
    550       && driver.RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex());
    551 }
    552 
    553 void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) {
    554   if (type == Primitive::kPrimVoid) {
    555     // Note that we might insert redundant barriers when inlining `super` calls.
    556     // TODO: add a data flow analysis to get rid of duplicate barriers.
    557     if (RequiresConstructorBarrier(dex_compilation_unit_, *compiler_driver_)) {
    558       current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore));
    559     }
    560     current_block_->AddInstruction(new (arena_) HReturnVoid());
    561   } else {
    562     HInstruction* value = LoadLocal(instruction.VRegA(), type);
    563     current_block_->AddInstruction(new (arena_) HReturn(value));
    564   }
    565   current_block_->AddSuccessor(exit_block_);
    566   current_block_ = nullptr;
    567 }
    568 
    569 bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
    570                                 uint32_t dex_pc,
    571                                 uint32_t method_idx,
    572                                 uint32_t number_of_vreg_arguments,
    573                                 bool is_range,
    574                                 uint32_t* args,
    575                                 uint32_t register_index) {
    576   Instruction::Code opcode = instruction.Opcode();
    577   InvokeType invoke_type;
    578   switch (opcode) {
    579     case Instruction::INVOKE_STATIC:
    580     case Instruction::INVOKE_STATIC_RANGE:
    581       invoke_type = kStatic;
    582       break;
    583     case Instruction::INVOKE_DIRECT:
    584     case Instruction::INVOKE_DIRECT_RANGE:
    585       invoke_type = kDirect;
    586       break;
    587     case Instruction::INVOKE_VIRTUAL:
    588     case Instruction::INVOKE_VIRTUAL_RANGE:
    589       invoke_type = kVirtual;
    590       break;
    591     case Instruction::INVOKE_INTERFACE:
    592     case Instruction::INVOKE_INTERFACE_RANGE:
    593       invoke_type = kInterface;
    594       break;
    595     case Instruction::INVOKE_SUPER_RANGE:
    596     case Instruction::INVOKE_SUPER:
    597       invoke_type = kSuper;
    598       break;
    599     default:
    600       LOG(FATAL) << "Unexpected invoke op: " << opcode;
    601       return false;
    602   }
    603 
    604   const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
    605   const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(method_id.proto_idx_);
    606   const char* descriptor = dex_file_->StringDataByIdx(proto_id.shorty_idx_);
    607   Primitive::Type return_type = Primitive::GetType(descriptor[0]);
    608   bool is_instance_call = invoke_type != kStatic;
    609   // Remove the return type from the 'proto'.
    610   size_t number_of_arguments = strlen(descriptor) - 1;
    611   if (is_instance_call) {
    612     // One extra argument for 'this'.
    613     ++number_of_arguments;
    614   }
    615 
    616   MethodReference target_method(dex_file_, method_idx);
    617   uintptr_t direct_code;
    618   uintptr_t direct_method;
    619   int table_index;
    620   InvokeType optimized_invoke_type = invoke_type;
    621 
    622   if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, true, true,
    623                                            &optimized_invoke_type, &target_method, &table_index,
    624                                            &direct_code, &direct_method)) {
    625     VLOG(compiler) << "Did not compile "
    626                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
    627                    << " because a method call could not be resolved";
    628     MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod);
    629     return false;
    630   }
    631   DCHECK(optimized_invoke_type != kSuper);
    632 
    633   // By default, consider that the called method implicitly requires
    634   // an initialization check of its declaring method.
    635   HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement =
    636       HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit;
    637   // Potential class initialization check, in the case of a static method call.
    638   HClinitCheck* clinit_check = nullptr;
    639   // Replace calls to String.<init> with StringFactory.
    640   int32_t string_init_offset = 0;
    641   bool is_string_init = compiler_driver_->IsStringInit(method_idx, dex_file_, &string_init_offset);
    642   if (is_string_init) {
    643     return_type = Primitive::kPrimNot;
    644     is_instance_call = false;
    645     number_of_arguments--;
    646     invoke_type = kStatic;
    647     optimized_invoke_type = kStatic;
    648   }
    649 
    650   HInvoke* invoke = nullptr;
    651 
    652   if (optimized_invoke_type == kVirtual) {
    653     invoke = new (arena_) HInvokeVirtual(
    654         arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index);
    655   } else if (optimized_invoke_type == kInterface) {
    656     invoke = new (arena_) HInvokeInterface(
    657         arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index);
    658   } else {
    659     DCHECK(optimized_invoke_type == kDirect || optimized_invoke_type == kStatic);
    660     // Sharpening to kDirect only works if we compile PIC.
    661     DCHECK((optimized_invoke_type == invoke_type) || (optimized_invoke_type != kDirect)
    662            || compiler_driver_->GetCompilerOptions().GetCompilePic());
    663     bool is_recursive =
    664         (target_method.dex_method_index == dex_compilation_unit_->GetDexMethodIndex());
    665     DCHECK(!is_recursive || (target_method.dex_file == dex_compilation_unit_->GetDexFile()));
    666 
    667     if (optimized_invoke_type == kStatic && !is_string_init) {
    668       ScopedObjectAccess soa(Thread::Current());
    669       StackHandleScope<4> hs(soa.Self());
    670       Handle<mirror::DexCache> dex_cache(hs.NewHandle(
    671           dex_compilation_unit_->GetClassLinker()->FindDexCache(
    672               *dex_compilation_unit_->GetDexFile())));
    673       Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    674           soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
    675       ArtMethod* resolved_method = compiler_driver_->ResolveMethod(
    676           soa, dex_cache, class_loader, dex_compilation_unit_, method_idx, optimized_invoke_type);
    677 
    678       if (resolved_method == nullptr) {
    679         MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod);
    680         return false;
    681       }
    682 
    683       const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
    684       Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle(
    685           outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file)));
    686       Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
    687 
    688       // The index at which the method's class is stored in the DexCache's type array.
    689       uint32_t storage_index = DexFile::kDexNoIndex;
    690       bool is_outer_class = (resolved_method->GetDeclaringClass() == outer_class.Get());
    691       if (is_outer_class) {
    692         storage_index = outer_class->GetDexTypeIndex();
    693       } else if (outer_dex_cache.Get() == dex_cache.Get()) {
    694         // Get `storage_index` from IsClassOfStaticMethodAvailableToReferrer.
    695         compiler_driver_->IsClassOfStaticMethodAvailableToReferrer(outer_dex_cache.Get(),
    696                                                                    GetCompilingClass(),
    697                                                                    resolved_method,
    698                                                                    method_idx,
    699                                                                    &storage_index);
    700       }
    701 
    702       if (!outer_class->IsInterface()
    703           && outer_class->IsSubClass(resolved_method->GetDeclaringClass())) {
    704         // If the outer class is the declaring class or a subclass
    705         // of the declaring class, no class initialization is needed
    706         // before the static method call.
    707         // Note that in case of inlining, we do not need to add clinit checks
    708         // to calls that satisfy this subclass check with any inlined methods. This
    709         // will be detected by the optimization passes.
    710         clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone;
    711       } else if (storage_index != DexFile::kDexNoIndex) {
    712         // If the method's class type index is available, check
    713         // whether we should add an explicit class initialization
    714         // check for its declaring class before the static method call.
    715 
    716         // TODO: find out why this check is needed.
    717         bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache(
    718             *outer_compilation_unit_->GetDexFile(), storage_index);
    719         bool is_initialized =
    720             resolved_method->GetDeclaringClass()->IsInitialized() && is_in_dex_cache;
    721 
    722         if (is_initialized) {
    723           clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone;
    724         } else {
    725           clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit;
    726           HLoadClass* load_class =
    727               new (arena_) HLoadClass(storage_index, is_outer_class, dex_pc);
    728           current_block_->AddInstruction(load_class);
    729           clinit_check = new (arena_) HClinitCheck(load_class, dex_pc);
    730           current_block_->AddInstruction(clinit_check);
    731         }
    732       }
    733     }
    734 
    735     invoke = new (arena_) HInvokeStaticOrDirect(
    736         arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index,
    737         is_recursive, string_init_offset, invoke_type, optimized_invoke_type,
    738         clinit_check_requirement);
    739   }
    740 
    741   size_t start_index = 0;
    742   Temporaries temps(graph_);
    743   if (is_instance_call) {
    744     HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot);
    745     HNullCheck* null_check = new (arena_) HNullCheck(arg, dex_pc);
    746     current_block_->AddInstruction(null_check);
    747     temps.Add(null_check);
    748     invoke->SetArgumentAt(0, null_check);
    749     start_index = 1;
    750   }
    751 
    752   uint32_t descriptor_index = 1;  // Skip the return type.
    753   uint32_t argument_index = start_index;
    754   if (is_string_init) {
    755     start_index = 1;
    756   }
    757   for (size_t i = start_index;
    758        // Make sure we don't go over the expected arguments or over the number of
    759        // dex registers given. If the instruction was seen as dead by the verifier,
    760        // it hasn't been properly checked.
    761        (i < number_of_vreg_arguments) && (argument_index < number_of_arguments);
    762        i++, argument_index++) {
    763     Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]);
    764     bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
    765     if (!is_range
    766         && is_wide
    767         && ((i + 1 == number_of_vreg_arguments) || (args[i] + 1 != args[i + 1]))) {
    768       // Longs and doubles should be in pairs, that is, sequential registers. The verifier should
    769       // reject any class where this is violated. However, the verifier only does these checks
    770       // on non trivially dead instructions, so we just bailout the compilation.
    771       VLOG(compiler) << "Did not compile "
    772                      << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
    773                      << " because of non-sequential dex register pair in wide argument";
    774       MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
    775       return false;
    776     }
    777     HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type);
    778     invoke->SetArgumentAt(argument_index, arg);
    779     if (is_wide) {
    780       i++;
    781     }
    782   }
    783 
    784   if (argument_index != number_of_arguments) {
    785     VLOG(compiler) << "Did not compile "
    786                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
    787                    << " because of wrong number of arguments in invoke instruction";
    788     MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
    789     return false;
    790   }
    791 
    792   if (clinit_check_requirement == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit) {
    793     // Add the class initialization check as last input of `invoke`.
    794     DCHECK(clinit_check != nullptr);
    795     invoke->SetArgumentAt(argument_index, clinit_check);
    796   }
    797 
    798   current_block_->AddInstruction(invoke);
    799   latest_result_ = invoke;
    800 
    801   // Add move-result for StringFactory method.
    802   if (is_string_init) {
    803     uint32_t orig_this_reg = is_range ? register_index : args[0];
    804     UpdateLocal(orig_this_reg, invoke);
    805     const VerifiedMethod* verified_method =
    806         compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex());
    807     if (verified_method == nullptr) {
    808       LOG(WARNING) << "No verified method for method calling String.<init>: "
    809                    << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_);
    810       return false;
    811     }
    812     const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map =
    813         verified_method->GetStringInitPcRegMap();
    814     auto map_it = string_init_map.find(dex_pc);
    815     if (map_it != string_init_map.end()) {
    816       std::set<uint32_t> reg_set = map_it->second;
    817       for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
    818         HInstruction* load_local = LoadLocal(orig_this_reg, Primitive::kPrimNot);
    819         UpdateLocal(*set_it, load_local);
    820       }
    821     }
    822   }
    823   return true;
    824 }
    825 
    826 bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
    827                                              uint32_t dex_pc,
    828                                              bool is_put) {
    829   uint32_t source_or_dest_reg = instruction.VRegA_22c();
    830   uint32_t obj_reg = instruction.VRegB_22c();
    831   uint16_t field_index = instruction.VRegC_22c();
    832 
    833   ScopedObjectAccess soa(Thread::Current());
    834   ArtField* resolved_field =
    835       compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa);
    836 
    837   if (resolved_field == nullptr) {
    838     MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
    839     return false;
    840   }
    841 
    842   Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
    843 
    844   HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot);
    845   current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc));
    846   if (is_put) {
    847     Temporaries temps(graph_);
    848     HInstruction* null_check = current_block_->GetLastInstruction();
    849     // We need one temporary for the null check.
    850     temps.Add(null_check);
    851     HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
    852     current_block_->AddInstruction(new (arena_) HInstanceFieldSet(
    853         null_check,
    854         value,
    855         field_type,
    856         resolved_field->GetOffset(),
    857         resolved_field->IsVolatile()));
    858   } else {
    859     current_block_->AddInstruction(new (arena_) HInstanceFieldGet(
    860         current_block_->GetLastInstruction(),
    861         field_type,
    862         resolved_field->GetOffset(),
    863         resolved_field->IsVolatile()));
    864 
    865     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
    866   }
    867   return true;
    868 }
    869 
    870 static mirror::Class* GetClassFrom(CompilerDriver* driver,
    871                                    const DexCompilationUnit& compilation_unit) {
    872   ScopedObjectAccess soa(Thread::Current());
    873   StackHandleScope<2> hs(soa.Self());
    874   const DexFile& dex_file = *compilation_unit.GetDexFile();
    875   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    876       soa.Decode<mirror::ClassLoader*>(compilation_unit.GetClassLoader())));
    877   Handle<mirror::DexCache> dex_cache(hs.NewHandle(
    878       compilation_unit.GetClassLinker()->FindDexCache(dex_file)));
    879 
    880   return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit);
    881 }
    882 
    883 mirror::Class* HGraphBuilder::GetOutermostCompilingClass() const {
    884   return GetClassFrom(compiler_driver_, *outer_compilation_unit_);
    885 }
    886 
    887 mirror::Class* HGraphBuilder::GetCompilingClass() const {
    888   return GetClassFrom(compiler_driver_, *dex_compilation_unit_);
    889 }
    890 
    891 bool HGraphBuilder::IsOutermostCompilingClass(uint16_t type_index) const {
    892   ScopedObjectAccess soa(Thread::Current());
    893   StackHandleScope<4> hs(soa.Self());
    894   Handle<mirror::DexCache> dex_cache(hs.NewHandle(
    895       dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile())));
    896   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    897       soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
    898   Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass(
    899       soa, dex_cache, class_loader, type_index, dex_compilation_unit_)));
    900   Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
    901 
    902   return outer_class.Get() == cls.Get();
    903 }
    904 
    905 bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
    906                                            uint32_t dex_pc,
    907                                            bool is_put) {
    908   uint32_t source_or_dest_reg = instruction.VRegA_21c();
    909   uint16_t field_index = instruction.VRegB_21c();
    910 
    911   ScopedObjectAccess soa(Thread::Current());
    912   StackHandleScope<4> hs(soa.Self());
    913   Handle<mirror::DexCache> dex_cache(hs.NewHandle(
    914       dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile())));
    915   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    916       soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
    917   ArtField* resolved_field = compiler_driver_->ResolveField(
    918       soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true);
    919 
    920   if (resolved_field == nullptr) {
    921     MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
    922     return false;
    923   }
    924 
    925   const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
    926   Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle(
    927       outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file)));
    928   Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
    929 
    930   // The index at which the field's class is stored in the DexCache's type array.
    931   uint32_t storage_index;
    932   bool is_outer_class = (outer_class.Get() == resolved_field->GetDeclaringClass());
    933   if (is_outer_class) {
    934     storage_index = outer_class->GetDexTypeIndex();
    935   } else if (outer_dex_cache.Get() != dex_cache.Get()) {
    936     // The compiler driver cannot currently understand multiple dex caches involved. Just bailout.
    937     return false;
    938   } else {
    939     std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField(
    940         outer_dex_cache.Get(),
    941         GetCompilingClass(),
    942         resolved_field,
    943         field_index,
    944         &storage_index);
    945     bool can_easily_access = is_put ? pair.second : pair.first;
    946     if (!can_easily_access) {
    947       return false;
    948     }
    949   }
    950 
    951   // TODO: find out why this check is needed.
    952   bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache(
    953       *outer_compilation_unit_->GetDexFile(), storage_index);
    954   bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache;
    955 
    956   HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_outer_class, dex_pc);
    957   current_block_->AddInstruction(constant);
    958 
    959   HInstruction* cls = constant;
    960   if (!is_initialized && !is_outer_class) {
    961     cls = new (arena_) HClinitCheck(constant, dex_pc);
    962     current_block_->AddInstruction(cls);
    963   }
    964 
    965   Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
    966   if (is_put) {
    967     // We need to keep the class alive before loading the value.
    968     Temporaries temps(graph_);
    969     temps.Add(cls);
    970     HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
    971     DCHECK_EQ(value->GetType(), field_type);
    972     current_block_->AddInstruction(
    973         new (arena_) HStaticFieldSet(cls, value, field_type, resolved_field->GetOffset(),
    974             resolved_field->IsVolatile()));
    975   } else {
    976     current_block_->AddInstruction(
    977         new (arena_) HStaticFieldGet(cls, field_type, resolved_field->GetOffset(),
    978             resolved_field->IsVolatile()));
    979     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
    980   }
    981   return true;
    982 }
    983 
    984 void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg,
    985                                        uint16_t first_vreg,
    986                                        int64_t second_vreg_or_constant,
    987                                        uint32_t dex_pc,
    988                                        Primitive::Type type,
    989                                        bool second_is_constant,
    990                                        bool isDiv) {
    991   DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong);
    992 
    993   HInstruction* first = LoadLocal(first_vreg, type);
    994   HInstruction* second = nullptr;
    995   if (second_is_constant) {
    996     if (type == Primitive::kPrimInt) {
    997       second = graph_->GetIntConstant(second_vreg_or_constant);
    998     } else {
    999       second = graph_->GetLongConstant(second_vreg_or_constant);
   1000     }
   1001   } else {
   1002     second = LoadLocal(second_vreg_or_constant, type);
   1003   }
   1004 
   1005   if (!second_is_constant
   1006       || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0)
   1007       || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) {
   1008     second = new (arena_) HDivZeroCheck(second, dex_pc);
   1009     Temporaries temps(graph_);
   1010     current_block_->AddInstruction(second);
   1011     temps.Add(current_block_->GetLastInstruction());
   1012   }
   1013 
   1014   if (isDiv) {
   1015     current_block_->AddInstruction(new (arena_) HDiv(type, first, second, dex_pc));
   1016   } else {
   1017     current_block_->AddInstruction(new (arena_) HRem(type, first, second, dex_pc));
   1018   }
   1019   UpdateLocal(out_vreg, current_block_->GetLastInstruction());
   1020 }
   1021 
   1022 void HGraphBuilder::BuildArrayAccess(const Instruction& instruction,
   1023                                      uint32_t dex_pc,
   1024                                      bool is_put,
   1025                                      Primitive::Type anticipated_type) {
   1026   uint8_t source_or_dest_reg = instruction.VRegA_23x();
   1027   uint8_t array_reg = instruction.VRegB_23x();
   1028   uint8_t index_reg = instruction.VRegC_23x();
   1029 
   1030   // We need one temporary for the null check, one for the index, and one for the length.
   1031   Temporaries temps(graph_);
   1032 
   1033   HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot);
   1034   object = new (arena_) HNullCheck(object, dex_pc);
   1035   current_block_->AddInstruction(object);
   1036   temps.Add(object);
   1037 
   1038   HInstruction* length = new (arena_) HArrayLength(object);
   1039   current_block_->AddInstruction(length);
   1040   temps.Add(length);
   1041   HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt);
   1042   index = new (arena_) HBoundsCheck(index, length, dex_pc);
   1043   current_block_->AddInstruction(index);
   1044   temps.Add(index);
   1045   if (is_put) {
   1046     HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type);
   1047     // TODO: Insert a type check node if the type is Object.
   1048     current_block_->AddInstruction(new (arena_) HArraySet(
   1049         object, index, value, anticipated_type, dex_pc));
   1050   } else {
   1051     current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type));
   1052     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
   1053   }
   1054   graph_->SetHasBoundsChecks(true);
   1055 }
   1056 
   1057 void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc,
   1058                                         uint32_t type_index,
   1059                                         uint32_t number_of_vreg_arguments,
   1060                                         bool is_range,
   1061                                         uint32_t* args,
   1062                                         uint32_t register_index) {
   1063   HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments);
   1064   QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
   1065       ? kQuickAllocArrayWithAccessCheck
   1066       : kQuickAllocArray;
   1067   HInstruction* object = new (arena_) HNewArray(length, dex_pc, type_index, entrypoint);
   1068   current_block_->AddInstruction(object);
   1069 
   1070   const char* descriptor = dex_file_->StringByTypeIdx(type_index);
   1071   DCHECK_EQ(descriptor[0], '[') << descriptor;
   1072   char primitive = descriptor[1];
   1073   DCHECK(primitive == 'I'
   1074       || primitive == 'L'
   1075       || primitive == '[') << descriptor;
   1076   bool is_reference_array = (primitive == 'L') || (primitive == '[');
   1077   Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt;
   1078 
   1079   Temporaries temps(graph_);
   1080   temps.Add(object);
   1081   for (size_t i = 0; i < number_of_vreg_arguments; ++i) {
   1082     HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type);
   1083     HInstruction* index = graph_->GetIntConstant(i);
   1084     current_block_->AddInstruction(
   1085         new (arena_) HArraySet(object, index, value, type, dex_pc));
   1086   }
   1087   latest_result_ = object;
   1088 }
   1089 
   1090 template <typename T>
   1091 void HGraphBuilder::BuildFillArrayData(HInstruction* object,
   1092                                        const T* data,
   1093                                        uint32_t element_count,
   1094                                        Primitive::Type anticipated_type,
   1095                                        uint32_t dex_pc) {
   1096   for (uint32_t i = 0; i < element_count; ++i) {
   1097     HInstruction* index = graph_->GetIntConstant(i);
   1098     HInstruction* value = graph_->GetIntConstant(data[i]);
   1099     current_block_->AddInstruction(new (arena_) HArraySet(
   1100       object, index, value, anticipated_type, dex_pc));
   1101   }
   1102 }
   1103 
   1104 void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) {
   1105   Temporaries temps(graph_);
   1106   HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot);
   1107   HNullCheck* null_check = new (arena_) HNullCheck(array, dex_pc);
   1108   current_block_->AddInstruction(null_check);
   1109   temps.Add(null_check);
   1110 
   1111   HInstruction* length = new (arena_) HArrayLength(null_check);
   1112   current_block_->AddInstruction(length);
   1113 
   1114   int32_t payload_offset = instruction.VRegB_31t() + dex_pc;
   1115   const Instruction::ArrayDataPayload* payload =
   1116       reinterpret_cast<const Instruction::ArrayDataPayload*>(code_start_ + payload_offset);
   1117   const uint8_t* data = payload->data;
   1118   uint32_t element_count = payload->element_count;
   1119 
   1120   // Implementation of this DEX instruction seems to be that the bounds check is
   1121   // done before doing any stores.
   1122   HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1);
   1123   current_block_->AddInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc));
   1124 
   1125   switch (payload->element_width) {
   1126     case 1:
   1127       BuildFillArrayData(null_check,
   1128                          reinterpret_cast<const int8_t*>(data),
   1129                          element_count,
   1130                          Primitive::kPrimByte,
   1131                          dex_pc);
   1132       break;
   1133     case 2:
   1134       BuildFillArrayData(null_check,
   1135                          reinterpret_cast<const int16_t*>(data),
   1136                          element_count,
   1137                          Primitive::kPrimShort,
   1138                          dex_pc);
   1139       break;
   1140     case 4:
   1141       BuildFillArrayData(null_check,
   1142                          reinterpret_cast<const int32_t*>(data),
   1143                          element_count,
   1144                          Primitive::kPrimInt,
   1145                          dex_pc);
   1146       break;
   1147     case 8:
   1148       BuildFillWideArrayData(null_check,
   1149                              reinterpret_cast<const int64_t*>(data),
   1150                              element_count,
   1151                              dex_pc);
   1152       break;
   1153     default:
   1154       LOG(FATAL) << "Unknown element width for " << payload->element_width;
   1155   }
   1156   graph_->SetHasBoundsChecks(true);
   1157 }
   1158 
   1159 void HGraphBuilder::BuildFillWideArrayData(HInstruction* object,
   1160                                            const int64_t* data,
   1161                                            uint32_t element_count,
   1162                                            uint32_t dex_pc) {
   1163   for (uint32_t i = 0; i < element_count; ++i) {
   1164     HInstruction* index = graph_->GetIntConstant(i);
   1165     HInstruction* value = graph_->GetLongConstant(data[i]);
   1166     current_block_->AddInstruction(new (arena_) HArraySet(
   1167       object, index, value, Primitive::kPrimLong, dex_pc));
   1168   }
   1169 }
   1170 
   1171 bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
   1172                                    uint8_t destination,
   1173                                    uint8_t reference,
   1174                                    uint16_t type_index,
   1175                                    uint32_t dex_pc) {
   1176   bool type_known_final;
   1177   bool type_known_abstract;
   1178   // `CanAccessTypeWithoutChecks` will tell whether the method being
   1179   // built is trying to access its own class, so that the generated
   1180   // code can optimize for this case. However, the optimization does not
   1181   // work for inlining, so we use `IsOutermostCompilingClass` instead.
   1182   bool dont_use_is_referrers_class;
   1183   bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
   1184       dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
   1185       &type_known_final, &type_known_abstract, &dont_use_is_referrers_class);
   1186   if (!can_access) {
   1187     MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
   1188     return false;
   1189   }
   1190   HInstruction* object = LoadLocal(reference, Primitive::kPrimNot);
   1191   HLoadClass* cls = new (arena_) HLoadClass(
   1192       type_index, IsOutermostCompilingClass(type_index), dex_pc);
   1193   current_block_->AddInstruction(cls);
   1194   // The class needs a temporary before being used by the type check.
   1195   Temporaries temps(graph_);
   1196   temps.Add(cls);
   1197   if (instruction.Opcode() == Instruction::INSTANCE_OF) {
   1198     current_block_->AddInstruction(
   1199         new (arena_) HInstanceOf(object, cls, type_known_final, dex_pc));
   1200     UpdateLocal(destination, current_block_->GetLastInstruction());
   1201   } else {
   1202     DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST);
   1203     current_block_->AddInstruction(
   1204         new (arena_) HCheckCast(object, cls, type_known_final, dex_pc));
   1205   }
   1206   return true;
   1207 }
   1208 
   1209 bool HGraphBuilder::NeedsAccessCheck(uint32_t type_index) const {
   1210   return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks(
   1211       dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index);
   1212 }
   1213 
   1214 void HGraphBuilder::BuildPackedSwitch(const Instruction& instruction, uint32_t dex_pc) {
   1215   // Verifier guarantees that the payload for PackedSwitch contains:
   1216   //   (a) number of entries (may be zero)
   1217   //   (b) first and lowest switch case value (entry 0, always present)
   1218   //   (c) list of target pcs (entries 1 <= i <= N)
   1219   SwitchTable table(instruction, dex_pc, false);
   1220 
   1221   // Value to test against.
   1222   HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
   1223 
   1224   // Retrieve number of entries.
   1225   uint16_t num_entries = table.GetNumEntries();
   1226   if (num_entries == 0) {
   1227     return;
   1228   }
   1229 
   1230   // Chained cmp-and-branch, starting from starting_key.
   1231   int32_t starting_key = table.GetEntryAt(0);
   1232 
   1233   for (size_t i = 1; i <= num_entries; i++) {
   1234     BuildSwitchCaseHelper(instruction, i, i == num_entries, table, value, starting_key + i - 1,
   1235                           table.GetEntryAt(i), dex_pc);
   1236   }
   1237 }
   1238 
   1239 void HGraphBuilder::BuildSparseSwitch(const Instruction& instruction, uint32_t dex_pc) {
   1240   // Verifier guarantees that the payload for SparseSwitch contains:
   1241   //   (a) number of entries (may be zero)
   1242   //   (b) sorted key values (entries 0 <= i < N)
   1243   //   (c) target pcs corresponding to the switch values (entries N <= i < 2*N)
   1244   SwitchTable table(instruction, dex_pc, true);
   1245 
   1246   // Value to test against.
   1247   HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
   1248 
   1249   uint16_t num_entries = table.GetNumEntries();
   1250 
   1251   for (size_t i = 0; i < num_entries; i++) {
   1252     BuildSwitchCaseHelper(instruction, i, i == static_cast<size_t>(num_entries) - 1, table, value,
   1253                           table.GetEntryAt(i), table.GetEntryAt(i + num_entries), dex_pc);
   1254   }
   1255 }
   1256 
   1257 void HGraphBuilder::BuildSwitchCaseHelper(const Instruction& instruction, size_t index,
   1258                                           bool is_last_case, const SwitchTable& table,
   1259                                           HInstruction* value, int32_t case_value_int,
   1260                                           int32_t target_offset, uint32_t dex_pc) {
   1261   HBasicBlock* case_target = FindBlockStartingAt(dex_pc + target_offset);
   1262   DCHECK(case_target != nullptr);
   1263   PotentiallyAddSuspendCheck(case_target, dex_pc);
   1264 
   1265   // The current case's value.
   1266   HInstruction* this_case_value = graph_->GetIntConstant(case_value_int);
   1267 
   1268   // Compare value and this_case_value.
   1269   HEqual* comparison = new (arena_) HEqual(value, this_case_value);
   1270   current_block_->AddInstruction(comparison);
   1271   HInstruction* ifinst = new (arena_) HIf(comparison);
   1272   current_block_->AddInstruction(ifinst);
   1273 
   1274   // Case hit: use the target offset to determine where to go.
   1275   current_block_->AddSuccessor(case_target);
   1276 
   1277   // Case miss: go to the next case (or default fall-through).
   1278   // When there is a next case, we use the block stored with the table offset representing this
   1279   // case (that is where we registered them in ComputeBranchTargets).
   1280   // When there is no next case, we use the following instruction.
   1281   // TODO: Find a good way to peel the last iteration to avoid conditional, but still have re-use.
   1282   if (!is_last_case) {
   1283     HBasicBlock* next_case_target = FindBlockStartingAt(table.GetDexPcForIndex(index));
   1284     DCHECK(next_case_target != nullptr);
   1285     current_block_->AddSuccessor(next_case_target);
   1286 
   1287     // Need to manually add the block, as there is no dex-pc transition for the cases.
   1288     graph_->AddBlock(next_case_target);
   1289 
   1290     current_block_ = next_case_target;
   1291   } else {
   1292     HBasicBlock* default_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
   1293     DCHECK(default_target != nullptr);
   1294     current_block_->AddSuccessor(default_target);
   1295     current_block_ = nullptr;
   1296   }
   1297 }
   1298 
   1299 void HGraphBuilder::PotentiallyAddSuspendCheck(HBasicBlock* target, uint32_t dex_pc) {
   1300   int32_t target_offset = target->GetDexPc() - dex_pc;
   1301   if (target_offset <= 0) {
   1302     // DX generates back edges to the first encountered return. We can save
   1303     // time of later passes by not adding redundant suspend checks.
   1304     HInstruction* last_in_target = target->GetLastInstruction();
   1305     if (last_in_target != nullptr &&
   1306         (last_in_target->IsReturn() || last_in_target->IsReturnVoid())) {
   1307       return;
   1308     }
   1309 
   1310     // Add a suspend check to backward branches which may potentially loop. We
   1311     // can remove them after we recognize loops in the graph.
   1312     current_block_->AddInstruction(new (arena_) HSuspendCheck(dex_pc));
   1313   }
   1314 }
   1315 
   1316 bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc) {
   1317   if (current_block_ == nullptr) {
   1318     return true;  // Dead code
   1319   }
   1320 
   1321   switch (instruction.Opcode()) {
   1322     case Instruction::CONST_4: {
   1323       int32_t register_index = instruction.VRegA();
   1324       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n());
   1325       UpdateLocal(register_index, constant);
   1326       break;
   1327     }
   1328 
   1329     case Instruction::CONST_16: {
   1330       int32_t register_index = instruction.VRegA();
   1331       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s());
   1332       UpdateLocal(register_index, constant);
   1333       break;
   1334     }
   1335 
   1336     case Instruction::CONST: {
   1337       int32_t register_index = instruction.VRegA();
   1338       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i());
   1339       UpdateLocal(register_index, constant);
   1340       break;
   1341     }
   1342 
   1343     case Instruction::CONST_HIGH16: {
   1344       int32_t register_index = instruction.VRegA();
   1345       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16);
   1346       UpdateLocal(register_index, constant);
   1347       break;
   1348     }
   1349 
   1350     case Instruction::CONST_WIDE_16: {
   1351       int32_t register_index = instruction.VRegA();
   1352       // Get 16 bits of constant value, sign extended to 64 bits.
   1353       int64_t value = instruction.VRegB_21s();
   1354       value <<= 48;
   1355       value >>= 48;
   1356       HLongConstant* constant = graph_->GetLongConstant(value);
   1357       UpdateLocal(register_index, constant);
   1358       break;
   1359     }
   1360 
   1361     case Instruction::CONST_WIDE_32: {
   1362       int32_t register_index = instruction.VRegA();
   1363       // Get 32 bits of constant value, sign extended to 64 bits.
   1364       int64_t value = instruction.VRegB_31i();
   1365       value <<= 32;
   1366       value >>= 32;
   1367       HLongConstant* constant = graph_->GetLongConstant(value);
   1368       UpdateLocal(register_index, constant);
   1369       break;
   1370     }
   1371 
   1372     case Instruction::CONST_WIDE: {
   1373       int32_t register_index = instruction.VRegA();
   1374       HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l());
   1375       UpdateLocal(register_index, constant);
   1376       break;
   1377     }
   1378 
   1379     case Instruction::CONST_WIDE_HIGH16: {
   1380       int32_t register_index = instruction.VRegA();
   1381       int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48;
   1382       HLongConstant* constant = graph_->GetLongConstant(value);
   1383       UpdateLocal(register_index, constant);
   1384       break;
   1385     }
   1386 
   1387     // Note that the SSA building will refine the types.
   1388     case Instruction::MOVE:
   1389     case Instruction::MOVE_FROM16:
   1390     case Instruction::MOVE_16: {
   1391       HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
   1392       UpdateLocal(instruction.VRegA(), value);
   1393       break;
   1394     }
   1395 
   1396     // Note that the SSA building will refine the types.
   1397     case Instruction::MOVE_WIDE:
   1398     case Instruction::MOVE_WIDE_FROM16:
   1399     case Instruction::MOVE_WIDE_16: {
   1400       HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong);
   1401       UpdateLocal(instruction.VRegA(), value);
   1402       break;
   1403     }
   1404 
   1405     case Instruction::MOVE_OBJECT:
   1406     case Instruction::MOVE_OBJECT_16:
   1407     case Instruction::MOVE_OBJECT_FROM16: {
   1408       HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot);
   1409       UpdateLocal(instruction.VRegA(), value);
   1410       break;
   1411     }
   1412 
   1413     case Instruction::RETURN_VOID: {
   1414       BuildReturn(instruction, Primitive::kPrimVoid);
   1415       break;
   1416     }
   1417 
   1418 #define IF_XX(comparison, cond) \
   1419     case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \
   1420     case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break
   1421 
   1422     IF_XX(HEqual, EQ);
   1423     IF_XX(HNotEqual, NE);
   1424     IF_XX(HLessThan, LT);
   1425     IF_XX(HLessThanOrEqual, LE);
   1426     IF_XX(HGreaterThan, GT);
   1427     IF_XX(HGreaterThanOrEqual, GE);
   1428 
   1429     case Instruction::GOTO:
   1430     case Instruction::GOTO_16:
   1431     case Instruction::GOTO_32: {
   1432       int32_t offset = instruction.GetTargetOffset();
   1433       HBasicBlock* target = FindBlockStartingAt(offset + dex_pc);
   1434       DCHECK(target != nullptr);
   1435       PotentiallyAddSuspendCheck(target, dex_pc);
   1436       current_block_->AddInstruction(new (arena_) HGoto());
   1437       current_block_->AddSuccessor(target);
   1438       current_block_ = nullptr;
   1439       break;
   1440     }
   1441 
   1442     case Instruction::RETURN: {
   1443       BuildReturn(instruction, return_type_);
   1444       break;
   1445     }
   1446 
   1447     case Instruction::RETURN_OBJECT: {
   1448       BuildReturn(instruction, return_type_);
   1449       break;
   1450     }
   1451 
   1452     case Instruction::RETURN_WIDE: {
   1453       BuildReturn(instruction, return_type_);
   1454       break;
   1455     }
   1456 
   1457     case Instruction::INVOKE_DIRECT:
   1458     case Instruction::INVOKE_INTERFACE:
   1459     case Instruction::INVOKE_STATIC:
   1460     case Instruction::INVOKE_SUPER:
   1461     case Instruction::INVOKE_VIRTUAL: {
   1462       uint32_t method_idx = instruction.VRegB_35c();
   1463       uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
   1464       uint32_t args[5];
   1465       instruction.GetVarArgs(args);
   1466       if (!BuildInvoke(instruction, dex_pc, method_idx,
   1467                        number_of_vreg_arguments, false, args, -1)) {
   1468         return false;
   1469       }
   1470       break;
   1471     }
   1472 
   1473     case Instruction::INVOKE_DIRECT_RANGE:
   1474     case Instruction::INVOKE_INTERFACE_RANGE:
   1475     case Instruction::INVOKE_STATIC_RANGE:
   1476     case Instruction::INVOKE_SUPER_RANGE:
   1477     case Instruction::INVOKE_VIRTUAL_RANGE: {
   1478       uint32_t method_idx = instruction.VRegB_3rc();
   1479       uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
   1480       uint32_t register_index = instruction.VRegC();
   1481       if (!BuildInvoke(instruction, dex_pc, method_idx,
   1482                        number_of_vreg_arguments, true, nullptr, register_index)) {
   1483         return false;
   1484       }
   1485       break;
   1486     }
   1487 
   1488     case Instruction::NEG_INT: {
   1489       Unop_12x<HNeg>(instruction, Primitive::kPrimInt);
   1490       break;
   1491     }
   1492 
   1493     case Instruction::NEG_LONG: {
   1494       Unop_12x<HNeg>(instruction, Primitive::kPrimLong);
   1495       break;
   1496     }
   1497 
   1498     case Instruction::NEG_FLOAT: {
   1499       Unop_12x<HNeg>(instruction, Primitive::kPrimFloat);
   1500       break;
   1501     }
   1502 
   1503     case Instruction::NEG_DOUBLE: {
   1504       Unop_12x<HNeg>(instruction, Primitive::kPrimDouble);
   1505       break;
   1506     }
   1507 
   1508     case Instruction::NOT_INT: {
   1509       Unop_12x<HNot>(instruction, Primitive::kPrimInt);
   1510       break;
   1511     }
   1512 
   1513     case Instruction::NOT_LONG: {
   1514       Unop_12x<HNot>(instruction, Primitive::kPrimLong);
   1515       break;
   1516     }
   1517 
   1518     case Instruction::INT_TO_LONG: {
   1519       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc);
   1520       break;
   1521     }
   1522 
   1523     case Instruction::INT_TO_FLOAT: {
   1524       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc);
   1525       break;
   1526     }
   1527 
   1528     case Instruction::INT_TO_DOUBLE: {
   1529       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc);
   1530       break;
   1531     }
   1532 
   1533     case Instruction::LONG_TO_INT: {
   1534       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc);
   1535       break;
   1536     }
   1537 
   1538     case Instruction::LONG_TO_FLOAT: {
   1539       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc);
   1540       break;
   1541     }
   1542 
   1543     case Instruction::LONG_TO_DOUBLE: {
   1544       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc);
   1545       break;
   1546     }
   1547 
   1548     case Instruction::FLOAT_TO_INT: {
   1549       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc);
   1550       break;
   1551     }
   1552 
   1553     case Instruction::FLOAT_TO_LONG: {
   1554       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc);
   1555       break;
   1556     }
   1557 
   1558     case Instruction::FLOAT_TO_DOUBLE: {
   1559       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc);
   1560       break;
   1561     }
   1562 
   1563     case Instruction::DOUBLE_TO_INT: {
   1564       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc);
   1565       break;
   1566     }
   1567 
   1568     case Instruction::DOUBLE_TO_LONG: {
   1569       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc);
   1570       break;
   1571     }
   1572 
   1573     case Instruction::DOUBLE_TO_FLOAT: {
   1574       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc);
   1575       break;
   1576     }
   1577 
   1578     case Instruction::INT_TO_BYTE: {
   1579       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc);
   1580       break;
   1581     }
   1582 
   1583     case Instruction::INT_TO_SHORT: {
   1584       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc);
   1585       break;
   1586     }
   1587 
   1588     case Instruction::INT_TO_CHAR: {
   1589       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc);
   1590       break;
   1591     }
   1592 
   1593     case Instruction::ADD_INT: {
   1594       Binop_23x<HAdd>(instruction, Primitive::kPrimInt);
   1595       break;
   1596     }
   1597 
   1598     case Instruction::ADD_LONG: {
   1599       Binop_23x<HAdd>(instruction, Primitive::kPrimLong);
   1600       break;
   1601     }
   1602 
   1603     case Instruction::ADD_DOUBLE: {
   1604       Binop_23x<HAdd>(instruction, Primitive::kPrimDouble);
   1605       break;
   1606     }
   1607 
   1608     case Instruction::ADD_FLOAT: {
   1609       Binop_23x<HAdd>(instruction, Primitive::kPrimFloat);
   1610       break;
   1611     }
   1612 
   1613     case Instruction::SUB_INT: {
   1614       Binop_23x<HSub>(instruction, Primitive::kPrimInt);
   1615       break;
   1616     }
   1617 
   1618     case Instruction::SUB_LONG: {
   1619       Binop_23x<HSub>(instruction, Primitive::kPrimLong);
   1620       break;
   1621     }
   1622 
   1623     case Instruction::SUB_FLOAT: {
   1624       Binop_23x<HSub>(instruction, Primitive::kPrimFloat);
   1625       break;
   1626     }
   1627 
   1628     case Instruction::SUB_DOUBLE: {
   1629       Binop_23x<HSub>(instruction, Primitive::kPrimDouble);
   1630       break;
   1631     }
   1632 
   1633     case Instruction::ADD_INT_2ADDR: {
   1634       Binop_12x<HAdd>(instruction, Primitive::kPrimInt);
   1635       break;
   1636     }
   1637 
   1638     case Instruction::MUL_INT: {
   1639       Binop_23x<HMul>(instruction, Primitive::kPrimInt);
   1640       break;
   1641     }
   1642 
   1643     case Instruction::MUL_LONG: {
   1644       Binop_23x<HMul>(instruction, Primitive::kPrimLong);
   1645       break;
   1646     }
   1647 
   1648     case Instruction::MUL_FLOAT: {
   1649       Binop_23x<HMul>(instruction, Primitive::kPrimFloat);
   1650       break;
   1651     }
   1652 
   1653     case Instruction::MUL_DOUBLE: {
   1654       Binop_23x<HMul>(instruction, Primitive::kPrimDouble);
   1655       break;
   1656     }
   1657 
   1658     case Instruction::DIV_INT: {
   1659       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1660                          dex_pc, Primitive::kPrimInt, false, true);
   1661       break;
   1662     }
   1663 
   1664     case Instruction::DIV_LONG: {
   1665       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1666                          dex_pc, Primitive::kPrimLong, false, true);
   1667       break;
   1668     }
   1669 
   1670     case Instruction::DIV_FLOAT: {
   1671       Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
   1672       break;
   1673     }
   1674 
   1675     case Instruction::DIV_DOUBLE: {
   1676       Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
   1677       break;
   1678     }
   1679 
   1680     case Instruction::REM_INT: {
   1681       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1682                          dex_pc, Primitive::kPrimInt, false, false);
   1683       break;
   1684     }
   1685 
   1686     case Instruction::REM_LONG: {
   1687       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1688                          dex_pc, Primitive::kPrimLong, false, false);
   1689       break;
   1690     }
   1691 
   1692     case Instruction::REM_FLOAT: {
   1693       Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
   1694       break;
   1695     }
   1696 
   1697     case Instruction::REM_DOUBLE: {
   1698       Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
   1699       break;
   1700     }
   1701 
   1702     case Instruction::AND_INT: {
   1703       Binop_23x<HAnd>(instruction, Primitive::kPrimInt);
   1704       break;
   1705     }
   1706 
   1707     case Instruction::AND_LONG: {
   1708       Binop_23x<HAnd>(instruction, Primitive::kPrimLong);
   1709       break;
   1710     }
   1711 
   1712     case Instruction::SHL_INT: {
   1713       Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt);
   1714       break;
   1715     }
   1716 
   1717     case Instruction::SHL_LONG: {
   1718       Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong);
   1719       break;
   1720     }
   1721 
   1722     case Instruction::SHR_INT: {
   1723       Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt);
   1724       break;
   1725     }
   1726 
   1727     case Instruction::SHR_LONG: {
   1728       Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong);
   1729       break;
   1730     }
   1731 
   1732     case Instruction::USHR_INT: {
   1733       Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt);
   1734       break;
   1735     }
   1736 
   1737     case Instruction::USHR_LONG: {
   1738       Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong);
   1739       break;
   1740     }
   1741 
   1742     case Instruction::OR_INT: {
   1743       Binop_23x<HOr>(instruction, Primitive::kPrimInt);
   1744       break;
   1745     }
   1746 
   1747     case Instruction::OR_LONG: {
   1748       Binop_23x<HOr>(instruction, Primitive::kPrimLong);
   1749       break;
   1750     }
   1751 
   1752     case Instruction::XOR_INT: {
   1753       Binop_23x<HXor>(instruction, Primitive::kPrimInt);
   1754       break;
   1755     }
   1756 
   1757     case Instruction::XOR_LONG: {
   1758       Binop_23x<HXor>(instruction, Primitive::kPrimLong);
   1759       break;
   1760     }
   1761 
   1762     case Instruction::ADD_LONG_2ADDR: {
   1763       Binop_12x<HAdd>(instruction, Primitive::kPrimLong);
   1764       break;
   1765     }
   1766 
   1767     case Instruction::ADD_DOUBLE_2ADDR: {
   1768       Binop_12x<HAdd>(instruction, Primitive::kPrimDouble);
   1769       break;
   1770     }
   1771 
   1772     case Instruction::ADD_FLOAT_2ADDR: {
   1773       Binop_12x<HAdd>(instruction, Primitive::kPrimFloat);
   1774       break;
   1775     }
   1776 
   1777     case Instruction::SUB_INT_2ADDR: {
   1778       Binop_12x<HSub>(instruction, Primitive::kPrimInt);
   1779       break;
   1780     }
   1781 
   1782     case Instruction::SUB_LONG_2ADDR: {
   1783       Binop_12x<HSub>(instruction, Primitive::kPrimLong);
   1784       break;
   1785     }
   1786 
   1787     case Instruction::SUB_FLOAT_2ADDR: {
   1788       Binop_12x<HSub>(instruction, Primitive::kPrimFloat);
   1789       break;
   1790     }
   1791 
   1792     case Instruction::SUB_DOUBLE_2ADDR: {
   1793       Binop_12x<HSub>(instruction, Primitive::kPrimDouble);
   1794       break;
   1795     }
   1796 
   1797     case Instruction::MUL_INT_2ADDR: {
   1798       Binop_12x<HMul>(instruction, Primitive::kPrimInt);
   1799       break;
   1800     }
   1801 
   1802     case Instruction::MUL_LONG_2ADDR: {
   1803       Binop_12x<HMul>(instruction, Primitive::kPrimLong);
   1804       break;
   1805     }
   1806 
   1807     case Instruction::MUL_FLOAT_2ADDR: {
   1808       Binop_12x<HMul>(instruction, Primitive::kPrimFloat);
   1809       break;
   1810     }
   1811 
   1812     case Instruction::MUL_DOUBLE_2ADDR: {
   1813       Binop_12x<HMul>(instruction, Primitive::kPrimDouble);
   1814       break;
   1815     }
   1816 
   1817     case Instruction::DIV_INT_2ADDR: {
   1818       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   1819                          dex_pc, Primitive::kPrimInt, false, true);
   1820       break;
   1821     }
   1822 
   1823     case Instruction::DIV_LONG_2ADDR: {
   1824       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   1825                          dex_pc, Primitive::kPrimLong, false, true);
   1826       break;
   1827     }
   1828 
   1829     case Instruction::REM_INT_2ADDR: {
   1830       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   1831                          dex_pc, Primitive::kPrimInt, false, false);
   1832       break;
   1833     }
   1834 
   1835     case Instruction::REM_LONG_2ADDR: {
   1836       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   1837                          dex_pc, Primitive::kPrimLong, false, false);
   1838       break;
   1839     }
   1840 
   1841     case Instruction::REM_FLOAT_2ADDR: {
   1842       Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
   1843       break;
   1844     }
   1845 
   1846     case Instruction::REM_DOUBLE_2ADDR: {
   1847       Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
   1848       break;
   1849     }
   1850 
   1851     case Instruction::SHL_INT_2ADDR: {
   1852       Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt);
   1853       break;
   1854     }
   1855 
   1856     case Instruction::SHL_LONG_2ADDR: {
   1857       Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong);
   1858       break;
   1859     }
   1860 
   1861     case Instruction::SHR_INT_2ADDR: {
   1862       Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt);
   1863       break;
   1864     }
   1865 
   1866     case Instruction::SHR_LONG_2ADDR: {
   1867       Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong);
   1868       break;
   1869     }
   1870 
   1871     case Instruction::USHR_INT_2ADDR: {
   1872       Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt);
   1873       break;
   1874     }
   1875 
   1876     case Instruction::USHR_LONG_2ADDR: {
   1877       Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong);
   1878       break;
   1879     }
   1880 
   1881     case Instruction::DIV_FLOAT_2ADDR: {
   1882       Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
   1883       break;
   1884     }
   1885 
   1886     case Instruction::DIV_DOUBLE_2ADDR: {
   1887       Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
   1888       break;
   1889     }
   1890 
   1891     case Instruction::AND_INT_2ADDR: {
   1892       Binop_12x<HAnd>(instruction, Primitive::kPrimInt);
   1893       break;
   1894     }
   1895 
   1896     case Instruction::AND_LONG_2ADDR: {
   1897       Binop_12x<HAnd>(instruction, Primitive::kPrimLong);
   1898       break;
   1899     }
   1900 
   1901     case Instruction::OR_INT_2ADDR: {
   1902       Binop_12x<HOr>(instruction, Primitive::kPrimInt);
   1903       break;
   1904     }
   1905 
   1906     case Instruction::OR_LONG_2ADDR: {
   1907       Binop_12x<HOr>(instruction, Primitive::kPrimLong);
   1908       break;
   1909     }
   1910 
   1911     case Instruction::XOR_INT_2ADDR: {
   1912       Binop_12x<HXor>(instruction, Primitive::kPrimInt);
   1913       break;
   1914     }
   1915 
   1916     case Instruction::XOR_LONG_2ADDR: {
   1917       Binop_12x<HXor>(instruction, Primitive::kPrimLong);
   1918       break;
   1919     }
   1920 
   1921     case Instruction::ADD_INT_LIT16: {
   1922       Binop_22s<HAdd>(instruction, false);
   1923       break;
   1924     }
   1925 
   1926     case Instruction::AND_INT_LIT16: {
   1927       Binop_22s<HAnd>(instruction, false);
   1928       break;
   1929     }
   1930 
   1931     case Instruction::OR_INT_LIT16: {
   1932       Binop_22s<HOr>(instruction, false);
   1933       break;
   1934     }
   1935 
   1936     case Instruction::XOR_INT_LIT16: {
   1937       Binop_22s<HXor>(instruction, false);
   1938       break;
   1939     }
   1940 
   1941     case Instruction::RSUB_INT: {
   1942       Binop_22s<HSub>(instruction, true);
   1943       break;
   1944     }
   1945 
   1946     case Instruction::MUL_INT_LIT16: {
   1947       Binop_22s<HMul>(instruction, false);
   1948       break;
   1949     }
   1950 
   1951     case Instruction::ADD_INT_LIT8: {
   1952       Binop_22b<HAdd>(instruction, false);
   1953       break;
   1954     }
   1955 
   1956     case Instruction::AND_INT_LIT8: {
   1957       Binop_22b<HAnd>(instruction, false);
   1958       break;
   1959     }
   1960 
   1961     case Instruction::OR_INT_LIT8: {
   1962       Binop_22b<HOr>(instruction, false);
   1963       break;
   1964     }
   1965 
   1966     case Instruction::XOR_INT_LIT8: {
   1967       Binop_22b<HXor>(instruction, false);
   1968       break;
   1969     }
   1970 
   1971     case Instruction::RSUB_INT_LIT8: {
   1972       Binop_22b<HSub>(instruction, true);
   1973       break;
   1974     }
   1975 
   1976     case Instruction::MUL_INT_LIT8: {
   1977       Binop_22b<HMul>(instruction, false);
   1978       break;
   1979     }
   1980 
   1981     case Instruction::DIV_INT_LIT16:
   1982     case Instruction::DIV_INT_LIT8: {
   1983       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1984                          dex_pc, Primitive::kPrimInt, true, true);
   1985       break;
   1986     }
   1987 
   1988     case Instruction::REM_INT_LIT16:
   1989     case Instruction::REM_INT_LIT8: {
   1990       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   1991                          dex_pc, Primitive::kPrimInt, true, false);
   1992       break;
   1993     }
   1994 
   1995     case Instruction::SHL_INT_LIT8: {
   1996       Binop_22b<HShl>(instruction, false);
   1997       break;
   1998     }
   1999 
   2000     case Instruction::SHR_INT_LIT8: {
   2001       Binop_22b<HShr>(instruction, false);
   2002       break;
   2003     }
   2004 
   2005     case Instruction::USHR_INT_LIT8: {
   2006       Binop_22b<HUShr>(instruction, false);
   2007       break;
   2008     }
   2009 
   2010     case Instruction::NEW_INSTANCE: {
   2011       uint16_t type_index = instruction.VRegB_21c();
   2012       if (compiler_driver_->IsStringTypeIndex(type_index, dex_file_)) {
   2013         // Turn new-instance of string into a const 0.
   2014         int32_t register_index = instruction.VRegA();
   2015         HNullConstant* constant = graph_->GetNullConstant();
   2016         UpdateLocal(register_index, constant);
   2017       } else {
   2018         QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
   2019             ? kQuickAllocObjectWithAccessCheck
   2020             : kQuickAllocObject;
   2021 
   2022         current_block_->AddInstruction(new (arena_) HNewInstance(dex_pc, type_index, entrypoint));
   2023         UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
   2024       }
   2025       break;
   2026     }
   2027 
   2028     case Instruction::NEW_ARRAY: {
   2029       uint16_t type_index = instruction.VRegC_22c();
   2030       HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt);
   2031       QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
   2032           ? kQuickAllocArrayWithAccessCheck
   2033           : kQuickAllocArray;
   2034       current_block_->AddInstruction(
   2035           new (arena_) HNewArray(length, dex_pc, type_index, entrypoint));
   2036       UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
   2037       break;
   2038     }
   2039 
   2040     case Instruction::FILLED_NEW_ARRAY: {
   2041       uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
   2042       uint32_t type_index = instruction.VRegB_35c();
   2043       uint32_t args[5];
   2044       instruction.GetVarArgs(args);
   2045       BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0);
   2046       break;
   2047     }
   2048 
   2049     case Instruction::FILLED_NEW_ARRAY_RANGE: {
   2050       uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
   2051       uint32_t type_index = instruction.VRegB_3rc();
   2052       uint32_t register_index = instruction.VRegC_3rc();
   2053       BuildFilledNewArray(
   2054           dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index);
   2055       break;
   2056     }
   2057 
   2058     case Instruction::FILL_ARRAY_DATA: {
   2059       BuildFillArrayData(instruction, dex_pc);
   2060       break;
   2061     }
   2062 
   2063     case Instruction::MOVE_RESULT:
   2064     case Instruction::MOVE_RESULT_WIDE:
   2065     case Instruction::MOVE_RESULT_OBJECT:
   2066       if (latest_result_ == nullptr) {
   2067         // Only dead code can lead to this situation, where the verifier
   2068         // does not reject the method.
   2069       } else {
   2070         UpdateLocal(instruction.VRegA(), latest_result_);
   2071         latest_result_ = nullptr;
   2072       }
   2073       break;
   2074 
   2075     case Instruction::CMP_LONG: {
   2076       Binop_23x_cmp(instruction, Primitive::kPrimLong, HCompare::kNoBias, dex_pc);
   2077       break;
   2078     }
   2079 
   2080     case Instruction::CMPG_FLOAT: {
   2081       Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kGtBias, dex_pc);
   2082       break;
   2083     }
   2084 
   2085     case Instruction::CMPG_DOUBLE: {
   2086       Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kGtBias, dex_pc);
   2087       break;
   2088     }
   2089 
   2090     case Instruction::CMPL_FLOAT: {
   2091       Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kLtBias, dex_pc);
   2092       break;
   2093     }
   2094 
   2095     case Instruction::CMPL_DOUBLE: {
   2096       Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kLtBias, dex_pc);
   2097       break;
   2098     }
   2099 
   2100     case Instruction::NOP:
   2101       break;
   2102 
   2103     case Instruction::IGET:
   2104     case Instruction::IGET_WIDE:
   2105     case Instruction::IGET_OBJECT:
   2106     case Instruction::IGET_BOOLEAN:
   2107     case Instruction::IGET_BYTE:
   2108     case Instruction::IGET_CHAR:
   2109     case Instruction::IGET_SHORT: {
   2110       if (!BuildInstanceFieldAccess(instruction, dex_pc, false)) {
   2111         return false;
   2112       }
   2113       break;
   2114     }
   2115 
   2116     case Instruction::IPUT:
   2117     case Instruction::IPUT_WIDE:
   2118     case Instruction::IPUT_OBJECT:
   2119     case Instruction::IPUT_BOOLEAN:
   2120     case Instruction::IPUT_BYTE:
   2121     case Instruction::IPUT_CHAR:
   2122     case Instruction::IPUT_SHORT: {
   2123       if (!BuildInstanceFieldAccess(instruction, dex_pc, true)) {
   2124         return false;
   2125       }
   2126       break;
   2127     }
   2128 
   2129     case Instruction::SGET:
   2130     case Instruction::SGET_WIDE:
   2131     case Instruction::SGET_OBJECT:
   2132     case Instruction::SGET_BOOLEAN:
   2133     case Instruction::SGET_BYTE:
   2134     case Instruction::SGET_CHAR:
   2135     case Instruction::SGET_SHORT: {
   2136       if (!BuildStaticFieldAccess(instruction, dex_pc, false)) {
   2137         return false;
   2138       }
   2139       break;
   2140     }
   2141 
   2142     case Instruction::SPUT:
   2143     case Instruction::SPUT_WIDE:
   2144     case Instruction::SPUT_OBJECT:
   2145     case Instruction::SPUT_BOOLEAN:
   2146     case Instruction::SPUT_BYTE:
   2147     case Instruction::SPUT_CHAR:
   2148     case Instruction::SPUT_SHORT: {
   2149       if (!BuildStaticFieldAccess(instruction, dex_pc, true)) {
   2150         return false;
   2151       }
   2152       break;
   2153     }
   2154 
   2155 #define ARRAY_XX(kind, anticipated_type)                                          \
   2156     case Instruction::AGET##kind: {                                               \
   2157       BuildArrayAccess(instruction, dex_pc, false, anticipated_type);         \
   2158       break;                                                                      \
   2159     }                                                                             \
   2160     case Instruction::APUT##kind: {                                               \
   2161       BuildArrayAccess(instruction, dex_pc, true, anticipated_type);          \
   2162       break;                                                                      \
   2163     }
   2164 
   2165     ARRAY_XX(, Primitive::kPrimInt);
   2166     ARRAY_XX(_WIDE, Primitive::kPrimLong);
   2167     ARRAY_XX(_OBJECT, Primitive::kPrimNot);
   2168     ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean);
   2169     ARRAY_XX(_BYTE, Primitive::kPrimByte);
   2170     ARRAY_XX(_CHAR, Primitive::kPrimChar);
   2171     ARRAY_XX(_SHORT, Primitive::kPrimShort);
   2172 
   2173     case Instruction::ARRAY_LENGTH: {
   2174       HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot);
   2175       // No need for a temporary for the null check, it is the only input of the following
   2176       // instruction.
   2177       object = new (arena_) HNullCheck(object, dex_pc);
   2178       current_block_->AddInstruction(object);
   2179       current_block_->AddInstruction(new (arena_) HArrayLength(object));
   2180       UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction());
   2181       break;
   2182     }
   2183 
   2184     case Instruction::CONST_STRING: {
   2185       current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_21c(), dex_pc));
   2186       UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
   2187       break;
   2188     }
   2189 
   2190     case Instruction::CONST_STRING_JUMBO: {
   2191       current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_31c(), dex_pc));
   2192       UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction());
   2193       break;
   2194     }
   2195 
   2196     case Instruction::CONST_CLASS: {
   2197       uint16_t type_index = instruction.VRegB_21c();
   2198       bool type_known_final;
   2199       bool type_known_abstract;
   2200       bool dont_use_is_referrers_class;
   2201       // `CanAccessTypeWithoutChecks` will tell whether the method being
   2202       // built is trying to access its own class, so that the generated
   2203       // code can optimize for this case. However, the optimization does not
   2204       // work for inlining, so we use `IsOutermostCompilingClass` instead.
   2205       bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
   2206           dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
   2207           &type_known_final, &type_known_abstract, &dont_use_is_referrers_class);
   2208       if (!can_access) {
   2209         MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
   2210         return false;
   2211       }
   2212       current_block_->AddInstruction(
   2213           new (arena_) HLoadClass(type_index, IsOutermostCompilingClass(type_index), dex_pc));
   2214       UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
   2215       break;
   2216     }
   2217 
   2218     case Instruction::MOVE_EXCEPTION: {
   2219       current_block_->AddInstruction(new (arena_) HLoadException());
   2220       UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction());
   2221       break;
   2222     }
   2223 
   2224     case Instruction::THROW: {
   2225       HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot);
   2226       current_block_->AddInstruction(new (arena_) HThrow(exception, dex_pc));
   2227       // A throw instruction must branch to the exit block.
   2228       current_block_->AddSuccessor(exit_block_);
   2229       // We finished building this block. Set the current block to null to avoid
   2230       // adding dead instructions to it.
   2231       current_block_ = nullptr;
   2232       break;
   2233     }
   2234 
   2235     case Instruction::INSTANCE_OF: {
   2236       uint8_t destination = instruction.VRegA_22c();
   2237       uint8_t reference = instruction.VRegB_22c();
   2238       uint16_t type_index = instruction.VRegC_22c();
   2239       if (!BuildTypeCheck(instruction, destination, reference, type_index, dex_pc)) {
   2240         return false;
   2241       }
   2242       break;
   2243     }
   2244 
   2245     case Instruction::CHECK_CAST: {
   2246       uint8_t reference = instruction.VRegA_21c();
   2247       uint16_t type_index = instruction.VRegB_21c();
   2248       if (!BuildTypeCheck(instruction, -1, reference, type_index, dex_pc)) {
   2249         return false;
   2250       }
   2251       break;
   2252     }
   2253 
   2254     case Instruction::MONITOR_ENTER: {
   2255       current_block_->AddInstruction(new (arena_) HMonitorOperation(
   2256           LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
   2257           HMonitorOperation::kEnter,
   2258           dex_pc));
   2259       break;
   2260     }
   2261 
   2262     case Instruction::MONITOR_EXIT: {
   2263       current_block_->AddInstruction(new (arena_) HMonitorOperation(
   2264           LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
   2265           HMonitorOperation::kExit,
   2266           dex_pc));
   2267       break;
   2268     }
   2269 
   2270     case Instruction::PACKED_SWITCH: {
   2271       BuildPackedSwitch(instruction, dex_pc);
   2272       break;
   2273     }
   2274 
   2275     case Instruction::SPARSE_SWITCH: {
   2276       BuildSparseSwitch(instruction, dex_pc);
   2277       break;
   2278     }
   2279 
   2280     default:
   2281       VLOG(compiler) << "Did not compile "
   2282                      << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
   2283                      << " because of unhandled instruction "
   2284                      << instruction.Name();
   2285       MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction);
   2286       return false;
   2287   }
   2288   return true;
   2289 }  // NOLINT(readability/fn_size)
   2290 
   2291 HLocal* HGraphBuilder::GetLocalAt(int register_index) const {
   2292   return locals_.Get(register_index);
   2293 }
   2294 
   2295 void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const {
   2296   HLocal* local = GetLocalAt(register_index);
   2297   current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction));
   2298 }
   2299 
   2300 HInstruction* HGraphBuilder::LoadLocal(int register_index, Primitive::Type type) const {
   2301   HLocal* local = GetLocalAt(register_index);
   2302   current_block_->AddInstruction(new (arena_) HLoadLocal(local, type));
   2303   return current_block_->GetLastInstruction();
   2304 }
   2305 
   2306 }  // namespace art
   2307