Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2016 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 "instruction_builder.h"
     18 
     19 #include "art_method-inl.h"
     20 #include "bytecode_utils.h"
     21 #include "class_linker.h"
     22 #include "dex_instruction-inl.h"
     23 #include "driver/compiler_options.h"
     24 #include "imtable-inl.h"
     25 #include "quicken_info.h"
     26 #include "sharpening.h"
     27 #include "scoped_thread_state_change-inl.h"
     28 
     29 namespace art {
     30 
     31 void HInstructionBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) {
     32   if (compilation_stats_ != nullptr) {
     33     compilation_stats_->RecordStat(compilation_stat);
     34   }
     35 }
     36 
     37 HBasicBlock* HInstructionBuilder::FindBlockStartingAt(uint32_t dex_pc) const {
     38   return block_builder_->GetBlockAt(dex_pc);
     39 }
     40 
     41 inline ArenaVector<HInstruction*>* HInstructionBuilder::GetLocalsFor(HBasicBlock* block) {
     42   ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()];
     43   const size_t vregs = graph_->GetNumberOfVRegs();
     44   if (locals->size() == vregs) {
     45     return locals;
     46   }
     47   return GetLocalsForWithAllocation(block, locals, vregs);
     48 }
     49 
     50 ArenaVector<HInstruction*>* HInstructionBuilder::GetLocalsForWithAllocation(
     51     HBasicBlock* block,
     52     ArenaVector<HInstruction*>* locals,
     53     const size_t vregs) {
     54   DCHECK_NE(locals->size(), vregs);
     55   locals->resize(vregs, nullptr);
     56   if (block->IsCatchBlock()) {
     57     // We record incoming inputs of catch phis at throwing instructions and
     58     // must therefore eagerly create the phis. Phis for undefined vregs will
     59     // be deleted when the first throwing instruction with the vreg undefined
     60     // is encountered. Unused phis will be removed by dead phi analysis.
     61     for (size_t i = 0; i < vregs; ++i) {
     62       // No point in creating the catch phi if it is already undefined at
     63       // the first throwing instruction.
     64       HInstruction* current_local_value = (*current_locals_)[i];
     65       if (current_local_value != nullptr) {
     66         HPhi* phi = new (arena_) HPhi(
     67             arena_,
     68             i,
     69             0,
     70             current_local_value->GetType());
     71         block->AddPhi(phi);
     72         (*locals)[i] = phi;
     73       }
     74     }
     75   }
     76   return locals;
     77 }
     78 
     79 inline HInstruction* HInstructionBuilder::ValueOfLocalAt(HBasicBlock* block, size_t local) {
     80   ArenaVector<HInstruction*>* locals = GetLocalsFor(block);
     81   return (*locals)[local];
     82 }
     83 
     84 void HInstructionBuilder::InitializeBlockLocals() {
     85   current_locals_ = GetLocalsFor(current_block_);
     86 
     87   if (current_block_->IsCatchBlock()) {
     88     // Catch phis were already created and inputs collected from throwing sites.
     89     if (kIsDebugBuild) {
     90       // Make sure there was at least one throwing instruction which initialized
     91       // locals (guaranteed by HGraphBuilder) and that all try blocks have been
     92       // visited already (from HTryBoundary scoping and reverse post order).
     93       bool catch_block_visited = false;
     94       for (HBasicBlock* current : graph_->GetReversePostOrder()) {
     95         if (current == current_block_) {
     96           catch_block_visited = true;
     97         } else if (current->IsTryBlock()) {
     98           const HTryBoundary& try_entry = current->GetTryCatchInformation()->GetTryEntry();
     99           if (try_entry.HasExceptionHandler(*current_block_)) {
    100             DCHECK(!catch_block_visited) << "Catch block visited before its try block.";
    101           }
    102         }
    103       }
    104       DCHECK_EQ(current_locals_->size(), graph_->GetNumberOfVRegs())
    105           << "No instructions throwing into a live catch block.";
    106     }
    107   } else if (current_block_->IsLoopHeader()) {
    108     // If the block is a loop header, we know we only have visited the pre header
    109     // because we are visiting in reverse post order. We create phis for all initialized
    110     // locals from the pre header. Their inputs will be populated at the end of
    111     // the analysis.
    112     for (size_t local = 0; local < current_locals_->size(); ++local) {
    113       HInstruction* incoming =
    114           ValueOfLocalAt(current_block_->GetLoopInformation()->GetPreHeader(), local);
    115       if (incoming != nullptr) {
    116         HPhi* phi = new (arena_) HPhi(
    117             arena_,
    118             local,
    119             0,
    120             incoming->GetType());
    121         current_block_->AddPhi(phi);
    122         (*current_locals_)[local] = phi;
    123       }
    124     }
    125 
    126     // Save the loop header so that the last phase of the analysis knows which
    127     // blocks need to be updated.
    128     loop_headers_.push_back(current_block_);
    129   } else if (current_block_->GetPredecessors().size() > 0) {
    130     // All predecessors have already been visited because we are visiting in reverse post order.
    131     // We merge the values of all locals, creating phis if those values differ.
    132     for (size_t local = 0; local < current_locals_->size(); ++local) {
    133       bool one_predecessor_has_no_value = false;
    134       bool is_different = false;
    135       HInstruction* value = ValueOfLocalAt(current_block_->GetPredecessors()[0], local);
    136 
    137       for (HBasicBlock* predecessor : current_block_->GetPredecessors()) {
    138         HInstruction* current = ValueOfLocalAt(predecessor, local);
    139         if (current == nullptr) {
    140           one_predecessor_has_no_value = true;
    141           break;
    142         } else if (current != value) {
    143           is_different = true;
    144         }
    145       }
    146 
    147       if (one_predecessor_has_no_value) {
    148         // If one predecessor has no value for this local, we trust the verifier has
    149         // successfully checked that there is a store dominating any read after this block.
    150         continue;
    151       }
    152 
    153       if (is_different) {
    154         HInstruction* first_input = ValueOfLocalAt(current_block_->GetPredecessors()[0], local);
    155         HPhi* phi = new (arena_) HPhi(
    156             arena_,
    157             local,
    158             current_block_->GetPredecessors().size(),
    159             first_input->GetType());
    160         for (size_t i = 0; i < current_block_->GetPredecessors().size(); i++) {
    161           HInstruction* pred_value = ValueOfLocalAt(current_block_->GetPredecessors()[i], local);
    162           phi->SetRawInputAt(i, pred_value);
    163         }
    164         current_block_->AddPhi(phi);
    165         value = phi;
    166       }
    167       (*current_locals_)[local] = value;
    168     }
    169   }
    170 }
    171 
    172 void HInstructionBuilder::PropagateLocalsToCatchBlocks() {
    173   const HTryBoundary& try_entry = current_block_->GetTryCatchInformation()->GetTryEntry();
    174   for (HBasicBlock* catch_block : try_entry.GetExceptionHandlers()) {
    175     ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(catch_block);
    176     DCHECK_EQ(handler_locals->size(), current_locals_->size());
    177     for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) {
    178       HInstruction* handler_value = (*handler_locals)[vreg];
    179       if (handler_value == nullptr) {
    180         // Vreg was undefined at a previously encountered throwing instruction
    181         // and the catch phi was deleted. Do not record the local value.
    182         continue;
    183       }
    184       DCHECK(handler_value->IsPhi());
    185 
    186       HInstruction* local_value = (*current_locals_)[vreg];
    187       if (local_value == nullptr) {
    188         // This is the first instruction throwing into `catch_block` where
    189         // `vreg` is undefined. Delete the catch phi.
    190         catch_block->RemovePhi(handler_value->AsPhi());
    191         (*handler_locals)[vreg] = nullptr;
    192       } else {
    193         // Vreg has been defined at all instructions throwing into `catch_block`
    194         // encountered so far. Record the local value in the catch phi.
    195         handler_value->AsPhi()->AddInput(local_value);
    196       }
    197     }
    198   }
    199 }
    200 
    201 void HInstructionBuilder::AppendInstruction(HInstruction* instruction) {
    202   current_block_->AddInstruction(instruction);
    203   InitializeInstruction(instruction);
    204 }
    205 
    206 void HInstructionBuilder::InsertInstructionAtTop(HInstruction* instruction) {
    207   if (current_block_->GetInstructions().IsEmpty()) {
    208     current_block_->AddInstruction(instruction);
    209   } else {
    210     current_block_->InsertInstructionBefore(instruction, current_block_->GetFirstInstruction());
    211   }
    212   InitializeInstruction(instruction);
    213 }
    214 
    215 void HInstructionBuilder::InitializeInstruction(HInstruction* instruction) {
    216   if (instruction->NeedsEnvironment()) {
    217     HEnvironment* environment = new (arena_) HEnvironment(
    218         arena_,
    219         current_locals_->size(),
    220         graph_->GetArtMethod(),
    221         instruction->GetDexPc(),
    222         instruction);
    223     environment->CopyFrom(*current_locals_);
    224     instruction->SetRawEnvironment(environment);
    225   }
    226 }
    227 
    228 HInstruction* HInstructionBuilder::LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc) {
    229   HInstruction* ref = LoadLocal(register_index, Primitive::kPrimNot);
    230   if (!ref->CanBeNull()) {
    231     return ref;
    232   }
    233 
    234   HNullCheck* null_check = new (arena_) HNullCheck(ref, dex_pc);
    235   AppendInstruction(null_check);
    236   return null_check;
    237 }
    238 
    239 void HInstructionBuilder::SetLoopHeaderPhiInputs() {
    240   for (size_t i = loop_headers_.size(); i > 0; --i) {
    241     HBasicBlock* block = loop_headers_[i - 1];
    242     for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
    243       HPhi* phi = it.Current()->AsPhi();
    244       size_t vreg = phi->GetRegNumber();
    245       for (HBasicBlock* predecessor : block->GetPredecessors()) {
    246         HInstruction* value = ValueOfLocalAt(predecessor, vreg);
    247         if (value == nullptr) {
    248           // Vreg is undefined at this predecessor. Mark it dead and leave with
    249           // fewer inputs than predecessors. SsaChecker will fail if not removed.
    250           phi->SetDead();
    251           break;
    252         } else {
    253           phi->AddInput(value);
    254         }
    255       }
    256     }
    257   }
    258 }
    259 
    260 static bool IsBlockPopulated(HBasicBlock* block) {
    261   if (block->IsLoopHeader()) {
    262     // Suspend checks were inserted into loop headers during building of dominator tree.
    263     DCHECK(block->GetFirstInstruction()->IsSuspendCheck());
    264     return block->GetFirstInstruction() != block->GetLastInstruction();
    265   } else {
    266     return !block->GetInstructions().IsEmpty();
    267   }
    268 }
    269 
    270 bool HInstructionBuilder::Build() {
    271   locals_for_.resize(graph_->GetBlocks().size(),
    272                      ArenaVector<HInstruction*>(arena_->Adapter(kArenaAllocGraphBuilder)));
    273 
    274   // Find locations where we want to generate extra stackmaps for native debugging.
    275   // This allows us to generate the info only at interesting points (for example,
    276   // at start of java statement) rather than before every dex instruction.
    277   const bool native_debuggable = compiler_driver_ != nullptr &&
    278                                  compiler_driver_->GetCompilerOptions().GetNativeDebuggable();
    279   ArenaBitVector* native_debug_info_locations = nullptr;
    280   if (native_debuggable) {
    281     const uint32_t num_instructions = code_item_.insns_size_in_code_units_;
    282     native_debug_info_locations = new (arena_) ArenaBitVector (arena_, num_instructions, false);
    283     FindNativeDebugInfoLocations(native_debug_info_locations);
    284   }
    285 
    286   for (HBasicBlock* block : graph_->GetReversePostOrder()) {
    287     current_block_ = block;
    288     uint32_t block_dex_pc = current_block_->GetDexPc();
    289 
    290     InitializeBlockLocals();
    291 
    292     if (current_block_->IsEntryBlock()) {
    293       InitializeParameters();
    294       AppendInstruction(new (arena_) HSuspendCheck(0u));
    295       AppendInstruction(new (arena_) HGoto(0u));
    296       continue;
    297     } else if (current_block_->IsExitBlock()) {
    298       AppendInstruction(new (arena_) HExit());
    299       continue;
    300     } else if (current_block_->IsLoopHeader()) {
    301       HSuspendCheck* suspend_check = new (arena_) HSuspendCheck(current_block_->GetDexPc());
    302       current_block_->GetLoopInformation()->SetSuspendCheck(suspend_check);
    303       // This is slightly odd because the loop header might not be empty (TryBoundary).
    304       // But we're still creating the environment with locals from the top of the block.
    305       InsertInstructionAtTop(suspend_check);
    306     }
    307 
    308     if (block_dex_pc == kNoDexPc || current_block_ != block_builder_->GetBlockAt(block_dex_pc)) {
    309       // Synthetic block that does not need to be populated.
    310       DCHECK(IsBlockPopulated(current_block_));
    311       continue;
    312     }
    313 
    314     DCHECK(!IsBlockPopulated(current_block_));
    315 
    316     uint32_t quicken_index = 0;
    317     if (CanDecodeQuickenedInfo()) {
    318       quicken_index = block_builder_->GetQuickenIndex(block_dex_pc);
    319     }
    320 
    321     for (CodeItemIterator it(code_item_, block_dex_pc); !it.Done(); it.Advance()) {
    322       if (current_block_ == nullptr) {
    323         // The previous instruction ended this block.
    324         break;
    325       }
    326 
    327       uint32_t dex_pc = it.CurrentDexPc();
    328       if (dex_pc != block_dex_pc && FindBlockStartingAt(dex_pc) != nullptr) {
    329         // This dex_pc starts a new basic block.
    330         break;
    331       }
    332 
    333       if (current_block_->IsTryBlock() && IsThrowingDexInstruction(it.CurrentInstruction())) {
    334         PropagateLocalsToCatchBlocks();
    335       }
    336 
    337       if (native_debuggable && native_debug_info_locations->IsBitSet(dex_pc)) {
    338         AppendInstruction(new (arena_) HNativeDebugInfo(dex_pc));
    339       }
    340 
    341       if (!ProcessDexInstruction(it.CurrentInstruction(), dex_pc, quicken_index)) {
    342         return false;
    343       }
    344 
    345       if (QuickenInfoTable::NeedsIndexForInstruction(&it.CurrentInstruction())) {
    346         ++quicken_index;
    347       }
    348     }
    349 
    350     if (current_block_ != nullptr) {
    351       // Branching instructions clear current_block, so we know the last
    352       // instruction of the current block is not a branching instruction.
    353       // We add an unconditional Goto to the next block.
    354       DCHECK_EQ(current_block_->GetSuccessors().size(), 1u);
    355       AppendInstruction(new (arena_) HGoto());
    356     }
    357   }
    358 
    359   SetLoopHeaderPhiInputs();
    360 
    361   return true;
    362 }
    363 
    364 void HInstructionBuilder::FindNativeDebugInfoLocations(ArenaBitVector* locations) {
    365   // The callback gets called when the line number changes.
    366   // In other words, it marks the start of new java statement.
    367   struct Callback {
    368     static bool Position(void* ctx, const DexFile::PositionInfo& entry) {
    369       static_cast<ArenaBitVector*>(ctx)->SetBit(entry.address_);
    370       return false;
    371     }
    372   };
    373   dex_file_->DecodeDebugPositionInfo(&code_item_, Callback::Position, locations);
    374   // Instruction-specific tweaks.
    375   const Instruction* const begin = Instruction::At(code_item_.insns_);
    376   const Instruction* const end = begin->RelativeAt(code_item_.insns_size_in_code_units_);
    377   for (const Instruction* inst = begin; inst < end; inst = inst->Next()) {
    378     switch (inst->Opcode()) {
    379       case Instruction::MOVE_EXCEPTION: {
    380         // Stop in native debugger after the exception has been moved.
    381         // The compiler also expects the move at the start of basic block so
    382         // we do not want to interfere by inserting native-debug-info before it.
    383         locations->ClearBit(inst->GetDexPc(code_item_.insns_));
    384         const Instruction* next = inst->Next();
    385         if (next < end) {
    386           locations->SetBit(next->GetDexPc(code_item_.insns_));
    387         }
    388         break;
    389       }
    390       default:
    391         break;
    392     }
    393   }
    394 }
    395 
    396 HInstruction* HInstructionBuilder::LoadLocal(uint32_t reg_number, Primitive::Type type) const {
    397   HInstruction* value = (*current_locals_)[reg_number];
    398   DCHECK(value != nullptr);
    399 
    400   // If the operation requests a specific type, we make sure its input is of that type.
    401   if (type != value->GetType()) {
    402     if (Primitive::IsFloatingPointType(type)) {
    403       value = ssa_builder_->GetFloatOrDoubleEquivalent(value, type);
    404     } else if (type == Primitive::kPrimNot) {
    405       value = ssa_builder_->GetReferenceTypeEquivalent(value);
    406     }
    407     DCHECK(value != nullptr);
    408   }
    409 
    410   return value;
    411 }
    412 
    413 void HInstructionBuilder::UpdateLocal(uint32_t reg_number, HInstruction* stored_value) {
    414   Primitive::Type stored_type = stored_value->GetType();
    415   DCHECK_NE(stored_type, Primitive::kPrimVoid);
    416 
    417   // Storing into vreg `reg_number` may implicitly invalidate the surrounding
    418   // registers. Consider the following cases:
    419   // (1) Storing a wide value must overwrite previous values in both `reg_number`
    420   //     and `reg_number+1`. We store `nullptr` in `reg_number+1`.
    421   // (2) If vreg `reg_number-1` holds a wide value, writing into `reg_number`
    422   //     must invalidate it. We store `nullptr` in `reg_number-1`.
    423   // Consequently, storing a wide value into the high vreg of another wide value
    424   // will invalidate both `reg_number-1` and `reg_number+1`.
    425 
    426   if (reg_number != 0) {
    427     HInstruction* local_low = (*current_locals_)[reg_number - 1];
    428     if (local_low != nullptr && Primitive::Is64BitType(local_low->GetType())) {
    429       // The vreg we are storing into was previously the high vreg of a pair.
    430       // We need to invalidate its low vreg.
    431       DCHECK((*current_locals_)[reg_number] == nullptr);
    432       (*current_locals_)[reg_number - 1] = nullptr;
    433     }
    434   }
    435 
    436   (*current_locals_)[reg_number] = stored_value;
    437   if (Primitive::Is64BitType(stored_type)) {
    438     // We are storing a pair. Invalidate the instruction in the high vreg.
    439     (*current_locals_)[reg_number + 1] = nullptr;
    440   }
    441 }
    442 
    443 void HInstructionBuilder::InitializeParameters() {
    444   DCHECK(current_block_->IsEntryBlock());
    445 
    446   // dex_compilation_unit_ is null only when unit testing.
    447   if (dex_compilation_unit_ == nullptr) {
    448     return;
    449   }
    450 
    451   const char* shorty = dex_compilation_unit_->GetShorty();
    452   uint16_t number_of_parameters = graph_->GetNumberOfInVRegs();
    453   uint16_t locals_index = graph_->GetNumberOfLocalVRegs();
    454   uint16_t parameter_index = 0;
    455 
    456   const DexFile::MethodId& referrer_method_id =
    457       dex_file_->GetMethodId(dex_compilation_unit_->GetDexMethodIndex());
    458   if (!dex_compilation_unit_->IsStatic()) {
    459     // Add the implicit 'this' argument, not expressed in the signature.
    460     HParameterValue* parameter = new (arena_) HParameterValue(*dex_file_,
    461                                                               referrer_method_id.class_idx_,
    462                                                               parameter_index++,
    463                                                               Primitive::kPrimNot,
    464                                                               /* is_this */ true);
    465     AppendInstruction(parameter);
    466     UpdateLocal(locals_index++, parameter);
    467     number_of_parameters--;
    468     current_this_parameter_ = parameter;
    469   } else {
    470     DCHECK(current_this_parameter_ == nullptr);
    471   }
    472 
    473   const DexFile::ProtoId& proto = dex_file_->GetMethodPrototype(referrer_method_id);
    474   const DexFile::TypeList* arg_types = dex_file_->GetProtoParameters(proto);
    475   for (int i = 0, shorty_pos = 1; i < number_of_parameters; i++) {
    476     HParameterValue* parameter = new (arena_) HParameterValue(
    477         *dex_file_,
    478         arg_types->GetTypeItem(shorty_pos - 1).type_idx_,
    479         parameter_index++,
    480         Primitive::GetType(shorty[shorty_pos]),
    481         /* is_this */ false);
    482     ++shorty_pos;
    483     AppendInstruction(parameter);
    484     // Store the parameter value in the local that the dex code will use
    485     // to reference that parameter.
    486     UpdateLocal(locals_index++, parameter);
    487     if (Primitive::Is64BitType(parameter->GetType())) {
    488       i++;
    489       locals_index++;
    490       parameter_index++;
    491     }
    492   }
    493 }
    494 
    495 template<typename T>
    496 void HInstructionBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) {
    497   HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
    498   HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    499   T* comparison = new (arena_) T(first, second, dex_pc);
    500   AppendInstruction(comparison);
    501   AppendInstruction(new (arena_) HIf(comparison, dex_pc));
    502   current_block_ = nullptr;
    503 }
    504 
    505 template<typename T>
    506 void HInstructionBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) {
    507   HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
    508   T* comparison = new (arena_) T(value, graph_->GetIntConstant(0, dex_pc), dex_pc);
    509   AppendInstruction(comparison);
    510   AppendInstruction(new (arena_) HIf(comparison, dex_pc));
    511   current_block_ = nullptr;
    512 }
    513 
    514 template<typename T>
    515 void HInstructionBuilder::Unop_12x(const Instruction& instruction,
    516                                    Primitive::Type type,
    517                                    uint32_t dex_pc) {
    518   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    519   AppendInstruction(new (arena_) T(type, first, dex_pc));
    520   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    521 }
    522 
    523 void HInstructionBuilder::Conversion_12x(const Instruction& instruction,
    524                                          Primitive::Type input_type,
    525                                          Primitive::Type result_type,
    526                                          uint32_t dex_pc) {
    527   HInstruction* first = LoadLocal(instruction.VRegB(), input_type);
    528   AppendInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc));
    529   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    530 }
    531 
    532 template<typename T>
    533 void HInstructionBuilder::Binop_23x(const Instruction& instruction,
    534                                     Primitive::Type type,
    535                                     uint32_t dex_pc) {
    536   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    537   HInstruction* second = LoadLocal(instruction.VRegC(), type);
    538   AppendInstruction(new (arena_) T(type, first, second, dex_pc));
    539   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    540 }
    541 
    542 template<typename T>
    543 void HInstructionBuilder::Binop_23x_shift(const Instruction& instruction,
    544                                           Primitive::Type type,
    545                                           uint32_t dex_pc) {
    546   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    547   HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt);
    548   AppendInstruction(new (arena_) T(type, first, second, dex_pc));
    549   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    550 }
    551 
    552 void HInstructionBuilder::Binop_23x_cmp(const Instruction& instruction,
    553                                         Primitive::Type type,
    554                                         ComparisonBias bias,
    555                                         uint32_t dex_pc) {
    556   HInstruction* first = LoadLocal(instruction.VRegB(), type);
    557   HInstruction* second = LoadLocal(instruction.VRegC(), type);
    558   AppendInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc));
    559   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    560 }
    561 
    562 template<typename T>
    563 void HInstructionBuilder::Binop_12x_shift(const Instruction& instruction,
    564                                           Primitive::Type type,
    565                                           uint32_t dex_pc) {
    566   HInstruction* first = LoadLocal(instruction.VRegA(), type);
    567   HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    568   AppendInstruction(new (arena_) T(type, first, second, dex_pc));
    569   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    570 }
    571 
    572 template<typename T>
    573 void HInstructionBuilder::Binop_12x(const Instruction& instruction,
    574                                     Primitive::Type type,
    575                                     uint32_t dex_pc) {
    576   HInstruction* first = LoadLocal(instruction.VRegA(), type);
    577   HInstruction* second = LoadLocal(instruction.VRegB(), type);
    578   AppendInstruction(new (arena_) T(type, first, second, dex_pc));
    579   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    580 }
    581 
    582 template<typename T>
    583 void HInstructionBuilder::Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc) {
    584   HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    585   HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s(), dex_pc);
    586   if (reverse) {
    587     std::swap(first, second);
    588   }
    589   AppendInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc));
    590   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    591 }
    592 
    593 template<typename T>
    594 void HInstructionBuilder::Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc) {
    595   HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
    596   HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b(), dex_pc);
    597   if (reverse) {
    598     std::swap(first, second);
    599   }
    600   AppendInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc));
    601   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
    602 }
    603 
    604 // Does the method being compiled need any constructor barriers being inserted?
    605 // (Always 'false' for methods that aren't <init>.)
    606 static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, CompilerDriver* driver) {
    607   // Can be null in unit tests only.
    608   if (UNLIKELY(cu == nullptr)) {
    609     return false;
    610   }
    611 
    612   Thread* self = Thread::Current();
    613   return cu->IsConstructor()
    614       && !cu->IsStatic()
    615       // RequiresConstructorBarrier must only be queried for <init> methods;
    616       // it's effectively "false" for every other method.
    617       //
    618       // See CompilerDriver::RequiresConstructBarrier for more explanation.
    619       && driver->RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex());
    620 }
    621 
    622 // Returns true if `block` has only one successor which starts at the next
    623 // dex_pc after `instruction` at `dex_pc`.
    624 static bool IsFallthroughInstruction(const Instruction& instruction,
    625                                      uint32_t dex_pc,
    626                                      HBasicBlock* block) {
    627   uint32_t next_dex_pc = dex_pc + instruction.SizeInCodeUnits();
    628   return block->GetSingleSuccessor()->GetDexPc() == next_dex_pc;
    629 }
    630 
    631 void HInstructionBuilder::BuildSwitch(const Instruction& instruction, uint32_t dex_pc) {
    632   HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
    633   DexSwitchTable table(instruction, dex_pc);
    634 
    635   if (table.GetNumEntries() == 0) {
    636     // Empty Switch. Code falls through to the next block.
    637     DCHECK(IsFallthroughInstruction(instruction, dex_pc, current_block_));
    638     AppendInstruction(new (arena_) HGoto(dex_pc));
    639   } else if (table.ShouldBuildDecisionTree()) {
    640     for (DexSwitchTableIterator it(table); !it.Done(); it.Advance()) {
    641       HInstruction* case_value = graph_->GetIntConstant(it.CurrentKey(), dex_pc);
    642       HEqual* comparison = new (arena_) HEqual(value, case_value, dex_pc);
    643       AppendInstruction(comparison);
    644       AppendInstruction(new (arena_) HIf(comparison, dex_pc));
    645 
    646       if (!it.IsLast()) {
    647         current_block_ = FindBlockStartingAt(it.GetDexPcForCurrentIndex());
    648       }
    649     }
    650   } else {
    651     AppendInstruction(
    652         new (arena_) HPackedSwitch(table.GetEntryAt(0), table.GetNumEntries(), value, dex_pc));
    653   }
    654 
    655   current_block_ = nullptr;
    656 }
    657 
    658 void HInstructionBuilder::BuildReturn(const Instruction& instruction,
    659                                       Primitive::Type type,
    660                                       uint32_t dex_pc) {
    661   if (type == Primitive::kPrimVoid) {
    662     // Only <init> (which is a return-void) could possibly have a constructor fence.
    663     // This may insert additional redundant constructor fences from the super constructors.
    664     // TODO: remove redundant constructor fences (b/36656456).
    665     if (RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_)) {
    666       // Compiling instance constructor.
    667       DCHECK_STREQ("<init>", graph_->GetMethodName());
    668 
    669       HInstruction* fence_target = current_this_parameter_;
    670       DCHECK(fence_target != nullptr);
    671 
    672       AppendInstruction(new (arena_) HConstructorFence(fence_target, dex_pc, arena_));
    673     }
    674     AppendInstruction(new (arena_) HReturnVoid(dex_pc));
    675   } else {
    676     DCHECK(!RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_));
    677     HInstruction* value = LoadLocal(instruction.VRegA(), type);
    678     AppendInstruction(new (arena_) HReturn(value, dex_pc));
    679   }
    680   current_block_ = nullptr;
    681 }
    682 
    683 static InvokeType GetInvokeTypeFromOpCode(Instruction::Code opcode) {
    684   switch (opcode) {
    685     case Instruction::INVOKE_STATIC:
    686     case Instruction::INVOKE_STATIC_RANGE:
    687       return kStatic;
    688     case Instruction::INVOKE_DIRECT:
    689     case Instruction::INVOKE_DIRECT_RANGE:
    690       return kDirect;
    691     case Instruction::INVOKE_VIRTUAL:
    692     case Instruction::INVOKE_VIRTUAL_QUICK:
    693     case Instruction::INVOKE_VIRTUAL_RANGE:
    694     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK:
    695       return kVirtual;
    696     case Instruction::INVOKE_INTERFACE:
    697     case Instruction::INVOKE_INTERFACE_RANGE:
    698       return kInterface;
    699     case Instruction::INVOKE_SUPER_RANGE:
    700     case Instruction::INVOKE_SUPER:
    701       return kSuper;
    702     default:
    703       LOG(FATAL) << "Unexpected invoke opcode: " << opcode;
    704       UNREACHABLE();
    705   }
    706 }
    707 
    708 ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) {
    709   ScopedObjectAccess soa(Thread::Current());
    710 
    711   ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker();
    712   Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader();
    713 
    714   ArtMethod* resolved_method =
    715       class_linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
    716           *dex_compilation_unit_->GetDexFile(),
    717           method_idx,
    718           dex_compilation_unit_->GetDexCache(),
    719           class_loader,
    720           graph_->GetArtMethod(),
    721           invoke_type);
    722 
    723   if (UNLIKELY(resolved_method == nullptr)) {
    724     // Clean up any exception left by type resolution.
    725     soa.Self()->ClearException();
    726     return nullptr;
    727   }
    728 
    729   // The referrer may be unresolved for AOT if we're compiling a class that cannot be
    730   // resolved because, for example, we don't find a superclass in the classpath.
    731   if (graph_->GetArtMethod() == nullptr) {
    732     // The class linker cannot check access without a referrer, so we have to do it.
    733     // Fall back to HInvokeUnresolved if the method isn't public.
    734     if (!resolved_method->IsPublic()) {
    735       return nullptr;
    736     }
    737   }
    738 
    739   // We have to special case the invoke-super case, as ClassLinker::ResolveMethod does not.
    740   // We need to look at the referrer's super class vtable. We need to do this to know if we need to
    741   // make this an invoke-unresolved to handle cross-dex invokes or abstract super methods, both of
    742   // which require runtime handling.
    743   if (invoke_type == kSuper) {
    744     ObjPtr<mirror::Class> compiling_class = GetCompilingClass();
    745     if (compiling_class == nullptr) {
    746       // We could not determine the method's class we need to wait until runtime.
    747       DCHECK(Runtime::Current()->IsAotCompiler());
    748       return nullptr;
    749     }
    750     ObjPtr<mirror::Class> referenced_class = class_linker->LookupResolvedType(
    751         *dex_compilation_unit_->GetDexFile(),
    752         dex_compilation_unit_->GetDexFile()->GetMethodId(method_idx).class_idx_,
    753         dex_compilation_unit_->GetDexCache().Get(),
    754         class_loader.Get());
    755     DCHECK(referenced_class != nullptr);  // We have already resolved a method from this class.
    756     if (!referenced_class->IsAssignableFrom(compiling_class)) {
    757       // We cannot statically determine the target method. The runtime will throw a
    758       // NoSuchMethodError on this one.
    759       return nullptr;
    760     }
    761     ArtMethod* actual_method;
    762     if (referenced_class->IsInterface()) {
    763       actual_method = referenced_class->FindVirtualMethodForInterfaceSuper(
    764           resolved_method, class_linker->GetImagePointerSize());
    765     } else {
    766       uint16_t vtable_index = resolved_method->GetMethodIndex();
    767       actual_method = compiling_class->GetSuperClass()->GetVTableEntry(
    768           vtable_index, class_linker->GetImagePointerSize());
    769     }
    770     if (actual_method != resolved_method &&
    771         !IsSameDexFile(*actual_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) {
    772       // The back-end code generator relies on this check in order to ensure that it will not
    773       // attempt to read the dex_cache with a dex_method_index that is not from the correct
    774       // dex_file. If we didn't do this check then the dex_method_index will not be updated in the
    775       // builder, which means that the code-generator (and compiler driver during sharpening and
    776       // inliner, maybe) might invoke an incorrect method.
    777       // TODO: The actual method could still be referenced in the current dex file, so we
    778       //       could try locating it.
    779       // TODO: Remove the dex_file restriction.
    780       return nullptr;
    781     }
    782     if (!actual_method->IsInvokable()) {
    783       // Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub
    784       // could resolve the callee to the wrong method.
    785       return nullptr;
    786     }
    787     resolved_method = actual_method;
    788   }
    789 
    790   return resolved_method;
    791 }
    792 
    793 static bool IsStringConstructor(ArtMethod* method) {
    794   ScopedObjectAccess soa(Thread::Current());
    795   return method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
    796 }
    797 
    798 bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
    799                                       uint32_t dex_pc,
    800                                       uint32_t method_idx,
    801                                       uint32_t number_of_vreg_arguments,
    802                                       bool is_range,
    803                                       uint32_t* args,
    804                                       uint32_t register_index) {
    805   InvokeType invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode());
    806   const char* descriptor = dex_file_->GetMethodShorty(method_idx);
    807   Primitive::Type return_type = Primitive::GetType(descriptor[0]);
    808 
    809   // Remove the return type from the 'proto'.
    810   size_t number_of_arguments = strlen(descriptor) - 1;
    811   if (invoke_type != kStatic) {  // instance call
    812     // One extra argument for 'this'.
    813     number_of_arguments++;
    814   }
    815 
    816   ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type);
    817 
    818   if (UNLIKELY(resolved_method == nullptr)) {
    819     MaybeRecordStat(MethodCompilationStat::kUnresolvedMethod);
    820     HInvoke* invoke = new (arena_) HInvokeUnresolved(arena_,
    821                                                      number_of_arguments,
    822                                                      return_type,
    823                                                      dex_pc,
    824                                                      method_idx,
    825                                                      invoke_type);
    826     return HandleInvoke(invoke,
    827                         number_of_vreg_arguments,
    828                         args,
    829                         register_index,
    830                         is_range,
    831                         descriptor,
    832                         nullptr, /* clinit_check */
    833                         true /* is_unresolved */);
    834   }
    835 
    836   // Replace calls to String.<init> with StringFactory.
    837   if (IsStringConstructor(resolved_method)) {
    838     uint32_t string_init_entry_point = WellKnownClasses::StringInitToEntryPoint(resolved_method);
    839     HInvokeStaticOrDirect::DispatchInfo dispatch_info = {
    840         HInvokeStaticOrDirect::MethodLoadKind::kStringInit,
    841         HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod,
    842         dchecked_integral_cast<uint64_t>(string_init_entry_point)
    843     };
    844     MethodReference target_method(dex_file_, method_idx);
    845     HInvoke* invoke = new (arena_) HInvokeStaticOrDirect(
    846         arena_,
    847         number_of_arguments - 1,
    848         Primitive::kPrimNot /*return_type */,
    849         dex_pc,
    850         method_idx,
    851         nullptr,
    852         dispatch_info,
    853         invoke_type,
    854         target_method,
    855         HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
    856     return HandleStringInit(invoke,
    857                             number_of_vreg_arguments,
    858                             args,
    859                             register_index,
    860                             is_range,
    861                             descriptor);
    862   }
    863 
    864   // Potential class initialization check, in the case of a static method call.
    865   HClinitCheck* clinit_check = nullptr;
    866   HInvoke* invoke = nullptr;
    867   if (invoke_type == kDirect || invoke_type == kStatic || invoke_type == kSuper) {
    868     // By default, consider that the called method implicitly requires
    869     // an initialization check of its declaring method.
    870     HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement
    871         = HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit;
    872     ScopedObjectAccess soa(Thread::Current());
    873     if (invoke_type == kStatic) {
    874       clinit_check = ProcessClinitCheckForInvoke(
    875           dex_pc, resolved_method, &clinit_check_requirement);
    876     } else if (invoke_type == kSuper) {
    877       if (IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) {
    878         // Update the method index to the one resolved. Note that this may be a no-op if
    879         // we resolved to the method referenced by the instruction.
    880         method_idx = resolved_method->GetDexMethodIndex();
    881       }
    882     }
    883 
    884     HInvokeStaticOrDirect::DispatchInfo dispatch_info = {
    885         HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall,
    886         HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod,
    887         0u
    888     };
    889     MethodReference target_method(resolved_method->GetDexFile(),
    890                                   resolved_method->GetDexMethodIndex());
    891     invoke = new (arena_) HInvokeStaticOrDirect(arena_,
    892                                                 number_of_arguments,
    893                                                 return_type,
    894                                                 dex_pc,
    895                                                 method_idx,
    896                                                 resolved_method,
    897                                                 dispatch_info,
    898                                                 invoke_type,
    899                                                 target_method,
    900                                                 clinit_check_requirement);
    901   } else if (invoke_type == kVirtual) {
    902     ScopedObjectAccess soa(Thread::Current());  // Needed for the method index
    903     invoke = new (arena_) HInvokeVirtual(arena_,
    904                                          number_of_arguments,
    905                                          return_type,
    906                                          dex_pc,
    907                                          method_idx,
    908                                          resolved_method,
    909                                          resolved_method->GetMethodIndex());
    910   } else {
    911     DCHECK_EQ(invoke_type, kInterface);
    912     ScopedObjectAccess soa(Thread::Current());  // Needed for the IMT index.
    913     invoke = new (arena_) HInvokeInterface(arena_,
    914                                            number_of_arguments,
    915                                            return_type,
    916                                            dex_pc,
    917                                            method_idx,
    918                                            resolved_method,
    919                                            ImTable::GetImtIndex(resolved_method));
    920   }
    921 
    922   return HandleInvoke(invoke,
    923                       number_of_vreg_arguments,
    924                       args,
    925                       register_index,
    926                       is_range,
    927                       descriptor,
    928                       clinit_check,
    929                       false /* is_unresolved */);
    930 }
    931 
    932 bool HInstructionBuilder::BuildInvokePolymorphic(const Instruction& instruction ATTRIBUTE_UNUSED,
    933                                                  uint32_t dex_pc,
    934                                                  uint32_t method_idx,
    935                                                  uint32_t proto_idx,
    936                                                  uint32_t number_of_vreg_arguments,
    937                                                  bool is_range,
    938                                                  uint32_t* args,
    939                                                  uint32_t register_index) {
    940   const char* descriptor = dex_file_->GetShorty(proto_idx);
    941   DCHECK_EQ(1 + ArtMethod::NumArgRegisters(descriptor), number_of_vreg_arguments);
    942   Primitive::Type return_type = Primitive::GetType(descriptor[0]);
    943   size_t number_of_arguments = strlen(descriptor);
    944   HInvoke* invoke = new (arena_) HInvokePolymorphic(arena_,
    945                                                     number_of_arguments,
    946                                                     return_type,
    947                                                     dex_pc,
    948                                                     method_idx);
    949   return HandleInvoke(invoke,
    950                       number_of_vreg_arguments,
    951                       args,
    952                       register_index,
    953                       is_range,
    954                       descriptor,
    955                       nullptr /* clinit_check */,
    956                       false /* is_unresolved */);
    957 }
    958 
    959 HNewInstance* HInstructionBuilder::BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc) {
    960   ScopedObjectAccess soa(Thread::Current());
    961 
    962   HLoadClass* load_class = BuildLoadClass(type_index, dex_pc);
    963 
    964   HInstruction* cls = load_class;
    965   Handle<mirror::Class> klass = load_class->GetClass();
    966 
    967   if (!IsInitialized(klass)) {
    968     cls = new (arena_) HClinitCheck(load_class, dex_pc);
    969     AppendInstruction(cls);
    970   }
    971 
    972   // Only the access check entrypoint handles the finalizable class case. If we
    973   // need access checks, then we haven't resolved the method and the class may
    974   // again be finalizable.
    975   QuickEntrypointEnum entrypoint = kQuickAllocObjectInitialized;
    976   if (load_class->NeedsAccessCheck() || klass->IsFinalizable() || !klass->IsInstantiable()) {
    977     entrypoint = kQuickAllocObjectWithChecks;
    978   }
    979 
    980   // Consider classes we haven't resolved as potentially finalizable.
    981   bool finalizable = (klass == nullptr) || klass->IsFinalizable();
    982 
    983   HNewInstance* new_instance = new (arena_) HNewInstance(
    984       cls,
    985       dex_pc,
    986       type_index,
    987       *dex_compilation_unit_->GetDexFile(),
    988       finalizable,
    989       entrypoint);
    990   AppendInstruction(new_instance);
    991 
    992   return new_instance;
    993 }
    994 
    995 void HInstructionBuilder::BuildConstructorFenceForAllocation(HInstruction* allocation) {
    996   DCHECK(allocation != nullptr &&
    997              (allocation->IsNewInstance() ||
    998               allocation->IsNewArray()));  // corresponding to "new" keyword in JLS.
    999 
   1000   if (allocation->IsNewInstance()) {
   1001     // STRING SPECIAL HANDLING:
   1002     // -------------------------------
   1003     // Strings have a real HNewInstance node but they end up always having 0 uses.
   1004     // All uses of a String HNewInstance are always transformed to replace their input
   1005     // of the HNewInstance with an input of the invoke to StringFactory.
   1006     //
   1007     // Do not emit an HConstructorFence here since it can inhibit some String new-instance
   1008     // optimizations (to pass checker tests that rely on those optimizations).
   1009     HNewInstance* new_inst = allocation->AsNewInstance();
   1010     HLoadClass* load_class = new_inst->GetLoadClass();
   1011 
   1012     Thread* self = Thread::Current();
   1013     ScopedObjectAccess soa(self);
   1014     StackHandleScope<1> hs(self);
   1015     Handle<mirror::Class> klass = load_class->GetClass();
   1016     if (klass != nullptr && klass->IsStringClass()) {
   1017       return;
   1018       // Note: Do not use allocation->IsStringAlloc which requires
   1019       // a valid ReferenceTypeInfo, but that doesn't get made until after reference type
   1020       // propagation (and instruction builder is too early).
   1021     }
   1022     // (In terms of correctness, the StringFactory needs to provide its own
   1023     // default initialization barrier, see below.)
   1024   }
   1025 
   1026   // JLS 17.4.5 "Happens-before Order" describes:
   1027   //
   1028   //   The default initialization of any object happens-before any other actions (other than
   1029   //   default-writes) of a program.
   1030   //
   1031   // In our implementation the default initialization of an object to type T means
   1032   // setting all of its initial data (object[0..size)) to 0, and setting the
   1033   // object's class header (i.e. object.getClass() == T.class).
   1034   //
   1035   // In practice this fence ensures that the writes to the object header
   1036   // are visible to other threads if this object escapes the current thread.
   1037   // (and in theory the 0-initializing, but that happens automatically
   1038   // when new memory pages are mapped in by the OS).
   1039   HConstructorFence* ctor_fence =
   1040       new (arena_) HConstructorFence(allocation, allocation->GetDexPc(), arena_);
   1041   AppendInstruction(ctor_fence);
   1042 }
   1043 
   1044 static bool IsSubClass(mirror::Class* to_test, mirror::Class* super_class)
   1045     REQUIRES_SHARED(Locks::mutator_lock_) {
   1046   return to_test != nullptr && !to_test->IsInterface() && to_test->IsSubClass(super_class);
   1047 }
   1048 
   1049 bool HInstructionBuilder::IsInitialized(Handle<mirror::Class> cls) const {
   1050   if (cls == nullptr) {
   1051     return false;
   1052   }
   1053 
   1054   // `CanAssumeClassIsLoaded` will return true if we're JITting, or will
   1055   // check whether the class is in an image for the AOT compilation.
   1056   if (cls->IsInitialized() &&
   1057       compiler_driver_->CanAssumeClassIsLoaded(cls.Get())) {
   1058     return true;
   1059   }
   1060 
   1061   if (IsSubClass(GetOutermostCompilingClass(), cls.Get())) {
   1062     return true;
   1063   }
   1064 
   1065   // TODO: We should walk over the inlined methods, but we don't pass
   1066   //       that information to the builder.
   1067   if (IsSubClass(GetCompilingClass(), cls.Get())) {
   1068     return true;
   1069   }
   1070 
   1071   return false;
   1072 }
   1073 
   1074 HClinitCheck* HInstructionBuilder::ProcessClinitCheckForInvoke(
   1075       uint32_t dex_pc,
   1076       ArtMethod* resolved_method,
   1077       HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement) {
   1078   Handle<mirror::Class> klass = handles_->NewHandle(resolved_method->GetDeclaringClass());
   1079 
   1080   HClinitCheck* clinit_check = nullptr;
   1081   if (IsInitialized(klass)) {
   1082     *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone;
   1083   } else {
   1084     HLoadClass* cls = BuildLoadClass(klass->GetDexTypeIndex(),
   1085                                      klass->GetDexFile(),
   1086                                      klass,
   1087                                      dex_pc,
   1088                                      /* needs_access_check */ false);
   1089     if (cls != nullptr) {
   1090       *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit;
   1091       clinit_check = new (arena_) HClinitCheck(cls, dex_pc);
   1092       AppendInstruction(clinit_check);
   1093     }
   1094   }
   1095   return clinit_check;
   1096 }
   1097 
   1098 bool HInstructionBuilder::SetupInvokeArguments(HInvoke* invoke,
   1099                                                uint32_t number_of_vreg_arguments,
   1100                                                uint32_t* args,
   1101                                                uint32_t register_index,
   1102                                                bool is_range,
   1103                                                const char* descriptor,
   1104                                                size_t start_index,
   1105                                                size_t* argument_index) {
   1106   uint32_t descriptor_index = 1;  // Skip the return type.
   1107 
   1108   for (size_t i = start_index;
   1109        // Make sure we don't go over the expected arguments or over the number of
   1110        // dex registers given. If the instruction was seen as dead by the verifier,
   1111        // it hasn't been properly checked.
   1112        (i < number_of_vreg_arguments) && (*argument_index < invoke->GetNumberOfArguments());
   1113        i++, (*argument_index)++) {
   1114     Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]);
   1115     bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
   1116     if (!is_range
   1117         && is_wide
   1118         && ((i + 1 == number_of_vreg_arguments) || (args[i] + 1 != args[i + 1]))) {
   1119       // Longs and doubles should be in pairs, that is, sequential registers. The verifier should
   1120       // reject any class where this is violated. However, the verifier only does these checks
   1121       // on non trivially dead instructions, so we just bailout the compilation.
   1122       VLOG(compiler) << "Did not compile "
   1123                      << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
   1124                      << " because of non-sequential dex register pair in wide argument";
   1125       MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
   1126       return false;
   1127     }
   1128     HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type);
   1129     invoke->SetArgumentAt(*argument_index, arg);
   1130     if (is_wide) {
   1131       i++;
   1132     }
   1133   }
   1134 
   1135   if (*argument_index != invoke->GetNumberOfArguments()) {
   1136     VLOG(compiler) << "Did not compile "
   1137                    << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
   1138                    << " because of wrong number of arguments in invoke instruction";
   1139     MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
   1140     return false;
   1141   }
   1142 
   1143   if (invoke->IsInvokeStaticOrDirect() &&
   1144       HInvokeStaticOrDirect::NeedsCurrentMethodInput(
   1145           invoke->AsInvokeStaticOrDirect()->GetMethodLoadKind())) {
   1146     invoke->SetArgumentAt(*argument_index, graph_->GetCurrentMethod());
   1147     (*argument_index)++;
   1148   }
   1149 
   1150   return true;
   1151 }
   1152 
   1153 bool HInstructionBuilder::HandleInvoke(HInvoke* invoke,
   1154                                        uint32_t number_of_vreg_arguments,
   1155                                        uint32_t* args,
   1156                                        uint32_t register_index,
   1157                                        bool is_range,
   1158                                        const char* descriptor,
   1159                                        HClinitCheck* clinit_check,
   1160                                        bool is_unresolved) {
   1161   DCHECK(!invoke->IsInvokeStaticOrDirect() || !invoke->AsInvokeStaticOrDirect()->IsStringInit());
   1162 
   1163   size_t start_index = 0;
   1164   size_t argument_index = 0;
   1165   if (invoke->GetInvokeType() != InvokeType::kStatic) {  // Instance call.
   1166     uint32_t obj_reg = is_range ? register_index : args[0];
   1167     HInstruction* arg = is_unresolved
   1168         ? LoadLocal(obj_reg, Primitive::kPrimNot)
   1169         : LoadNullCheckedLocal(obj_reg, invoke->GetDexPc());
   1170     invoke->SetArgumentAt(0, arg);
   1171     start_index = 1;
   1172     argument_index = 1;
   1173   }
   1174 
   1175   if (!SetupInvokeArguments(invoke,
   1176                             number_of_vreg_arguments,
   1177                             args,
   1178                             register_index,
   1179                             is_range,
   1180                             descriptor,
   1181                             start_index,
   1182                             &argument_index)) {
   1183     return false;
   1184   }
   1185 
   1186   if (clinit_check != nullptr) {
   1187     // Add the class initialization check as last input of `invoke`.
   1188     DCHECK(invoke->IsInvokeStaticOrDirect());
   1189     DCHECK(invoke->AsInvokeStaticOrDirect()->GetClinitCheckRequirement()
   1190         == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit);
   1191     invoke->SetArgumentAt(argument_index, clinit_check);
   1192     argument_index++;
   1193   }
   1194 
   1195   AppendInstruction(invoke);
   1196   latest_result_ = invoke;
   1197 
   1198   return true;
   1199 }
   1200 
   1201 bool HInstructionBuilder::HandleStringInit(HInvoke* invoke,
   1202                                            uint32_t number_of_vreg_arguments,
   1203                                            uint32_t* args,
   1204                                            uint32_t register_index,
   1205                                            bool is_range,
   1206                                            const char* descriptor) {
   1207   DCHECK(invoke->IsInvokeStaticOrDirect());
   1208   DCHECK(invoke->AsInvokeStaticOrDirect()->IsStringInit());
   1209 
   1210   size_t start_index = 1;
   1211   size_t argument_index = 0;
   1212   if (!SetupInvokeArguments(invoke,
   1213                             number_of_vreg_arguments,
   1214                             args,
   1215                             register_index,
   1216                             is_range,
   1217                             descriptor,
   1218                             start_index,
   1219                             &argument_index)) {
   1220     return false;
   1221   }
   1222 
   1223   AppendInstruction(invoke);
   1224 
   1225   // This is a StringFactory call, not an actual String constructor. Its result
   1226   // replaces the empty String pre-allocated by NewInstance.
   1227   uint32_t orig_this_reg = is_range ? register_index : args[0];
   1228   HInstruction* arg_this = LoadLocal(orig_this_reg, Primitive::kPrimNot);
   1229 
   1230   // Replacing the NewInstance might render it redundant. Keep a list of these
   1231   // to be visited once it is clear whether it is has remaining uses.
   1232   if (arg_this->IsNewInstance()) {
   1233     ssa_builder_->AddUninitializedString(arg_this->AsNewInstance());
   1234   } else {
   1235     DCHECK(arg_this->IsPhi());
   1236     // NewInstance is not the direct input of the StringFactory call. It might
   1237     // be redundant but optimizing this case is not worth the effort.
   1238   }
   1239 
   1240   // Walk over all vregs and replace any occurrence of `arg_this` with `invoke`.
   1241   for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) {
   1242     if ((*current_locals_)[vreg] == arg_this) {
   1243       (*current_locals_)[vreg] = invoke;
   1244     }
   1245   }
   1246 
   1247   return true;
   1248 }
   1249 
   1250 static Primitive::Type GetFieldAccessType(const DexFile& dex_file, uint16_t field_index) {
   1251   const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
   1252   const char* type = dex_file.GetFieldTypeDescriptor(field_id);
   1253   return Primitive::GetType(type[0]);
   1254 }
   1255 
   1256 bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
   1257                                                    uint32_t dex_pc,
   1258                                                    bool is_put,
   1259                                                    size_t quicken_index) {
   1260   uint32_t source_or_dest_reg = instruction.VRegA_22c();
   1261   uint32_t obj_reg = instruction.VRegB_22c();
   1262   uint16_t field_index;
   1263   if (instruction.IsQuickened()) {
   1264     if (!CanDecodeQuickenedInfo()) {
   1265       return false;
   1266     }
   1267     field_index = LookupQuickenedInfo(quicken_index);
   1268   } else {
   1269     field_index = instruction.VRegC_22c();
   1270   }
   1271 
   1272   ScopedObjectAccess soa(Thread::Current());
   1273   ArtField* resolved_field = ResolveField(field_index, /* is_static */ false, is_put);
   1274 
   1275   // Generate an explicit null check on the reference, unless the field access
   1276   // is unresolved. In that case, we rely on the runtime to perform various
   1277   // checks first, followed by a null check.
   1278   HInstruction* object = (resolved_field == nullptr)
   1279       ? LoadLocal(obj_reg, Primitive::kPrimNot)
   1280       : LoadNullCheckedLocal(obj_reg, dex_pc);
   1281 
   1282   Primitive::Type field_type = (resolved_field == nullptr)
   1283       ? GetFieldAccessType(*dex_file_, field_index)
   1284       : resolved_field->GetTypeAsPrimitiveType();
   1285   if (is_put) {
   1286     HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
   1287     HInstruction* field_set = nullptr;
   1288     if (resolved_field == nullptr) {
   1289       MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
   1290       field_set = new (arena_) HUnresolvedInstanceFieldSet(object,
   1291                                                            value,
   1292                                                            field_type,
   1293                                                            field_index,
   1294                                                            dex_pc);
   1295     } else {
   1296       uint16_t class_def_index = resolved_field->GetDeclaringClass()->GetDexClassDefIndex();
   1297       field_set = new (arena_) HInstanceFieldSet(object,
   1298                                                  value,
   1299                                                  resolved_field,
   1300                                                  field_type,
   1301                                                  resolved_field->GetOffset(),
   1302                                                  resolved_field->IsVolatile(),
   1303                                                  field_index,
   1304                                                  class_def_index,
   1305                                                  *dex_file_,
   1306                                                  dex_pc);
   1307     }
   1308     AppendInstruction(field_set);
   1309   } else {
   1310     HInstruction* field_get = nullptr;
   1311     if (resolved_field == nullptr) {
   1312       MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
   1313       field_get = new (arena_) HUnresolvedInstanceFieldGet(object,
   1314                                                            field_type,
   1315                                                            field_index,
   1316                                                            dex_pc);
   1317     } else {
   1318       uint16_t class_def_index = resolved_field->GetDeclaringClass()->GetDexClassDefIndex();
   1319       field_get = new (arena_) HInstanceFieldGet(object,
   1320                                                  resolved_field,
   1321                                                  field_type,
   1322                                                  resolved_field->GetOffset(),
   1323                                                  resolved_field->IsVolatile(),
   1324                                                  field_index,
   1325                                                  class_def_index,
   1326                                                  *dex_file_,
   1327                                                  dex_pc);
   1328     }
   1329     AppendInstruction(field_get);
   1330     UpdateLocal(source_or_dest_reg, field_get);
   1331   }
   1332 
   1333   return true;
   1334 }
   1335 
   1336 static mirror::Class* GetClassFrom(CompilerDriver* driver,
   1337                                    const DexCompilationUnit& compilation_unit) {
   1338   ScopedObjectAccess soa(Thread::Current());
   1339   Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader();
   1340   Handle<mirror::DexCache> dex_cache = compilation_unit.GetDexCache();
   1341 
   1342   return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit);
   1343 }
   1344 
   1345 mirror::Class* HInstructionBuilder::GetOutermostCompilingClass() const {
   1346   return GetClassFrom(compiler_driver_, *outer_compilation_unit_);
   1347 }
   1348 
   1349 mirror::Class* HInstructionBuilder::GetCompilingClass() const {
   1350   return GetClassFrom(compiler_driver_, *dex_compilation_unit_);
   1351 }
   1352 
   1353 bool HInstructionBuilder::IsOutermostCompilingClass(dex::TypeIndex type_index) const {
   1354   ScopedObjectAccess soa(Thread::Current());
   1355   StackHandleScope<2> hs(soa.Self());
   1356   Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache();
   1357   Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader();
   1358   Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass(
   1359       soa, dex_cache, class_loader, type_index, dex_compilation_unit_)));
   1360   Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
   1361 
   1362   // GetOutermostCompilingClass returns null when the class is unresolved
   1363   // (e.g. if it derives from an unresolved class). This is bogus knowing that
   1364   // we are compiling it.
   1365   // When this happens we cannot establish a direct relation between the current
   1366   // class and the outer class, so we return false.
   1367   // (Note that this is only used for optimizing invokes and field accesses)
   1368   return (cls != nullptr) && (outer_class.Get() == cls.Get());
   1369 }
   1370 
   1371 void HInstructionBuilder::BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
   1372                                                            uint32_t dex_pc,
   1373                                                            bool is_put,
   1374                                                            Primitive::Type field_type) {
   1375   uint32_t source_or_dest_reg = instruction.VRegA_21c();
   1376   uint16_t field_index = instruction.VRegB_21c();
   1377 
   1378   if (is_put) {
   1379     HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
   1380     AppendInstruction(
   1381         new (arena_) HUnresolvedStaticFieldSet(value, field_type, field_index, dex_pc));
   1382   } else {
   1383     AppendInstruction(new (arena_) HUnresolvedStaticFieldGet(field_type, field_index, dex_pc));
   1384     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
   1385   }
   1386 }
   1387 
   1388 ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, bool is_put) {
   1389   ScopedObjectAccess soa(Thread::Current());
   1390   StackHandleScope<2> hs(soa.Self());
   1391 
   1392   ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker();
   1393   Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader();
   1394   Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass()));
   1395 
   1396   ArtField* resolved_field = class_linker->ResolveField(*dex_compilation_unit_->GetDexFile(),
   1397                                                         field_idx,
   1398                                                         dex_compilation_unit_->GetDexCache(),
   1399                                                         class_loader,
   1400                                                         is_static);
   1401 
   1402   if (UNLIKELY(resolved_field == nullptr)) {
   1403     // Clean up any exception left by type resolution.
   1404     soa.Self()->ClearException();
   1405     return nullptr;
   1406   }
   1407 
   1408   // Check static/instance. The class linker has a fast path for looking into the dex cache
   1409   // and does not check static/instance if it hits it.
   1410   if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
   1411     return nullptr;
   1412   }
   1413 
   1414   // Check access.
   1415   if (compiling_class == nullptr) {
   1416     if (!resolved_field->IsPublic()) {
   1417       return nullptr;
   1418     }
   1419   } else if (!compiling_class->CanAccessResolvedField(resolved_field->GetDeclaringClass(),
   1420                                                       resolved_field,
   1421                                                       dex_compilation_unit_->GetDexCache().Get(),
   1422                                                       field_idx)) {
   1423     return nullptr;
   1424   }
   1425 
   1426   if (is_put &&
   1427       resolved_field->IsFinal() &&
   1428       (compiling_class.Get() != resolved_field->GetDeclaringClass())) {
   1429     // Final fields can only be updated within their own class.
   1430     // TODO: Only allow it in constructors. b/34966607.
   1431     return nullptr;
   1432   }
   1433 
   1434   return resolved_field;
   1435 }
   1436 
   1437 bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction,
   1438                                                  uint32_t dex_pc,
   1439                                                  bool is_put) {
   1440   uint32_t source_or_dest_reg = instruction.VRegA_21c();
   1441   uint16_t field_index = instruction.VRegB_21c();
   1442 
   1443   ScopedObjectAccess soa(Thread::Current());
   1444   ArtField* resolved_field = ResolveField(field_index, /* is_static */ true, is_put);
   1445 
   1446   if (resolved_field == nullptr) {
   1447     MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
   1448     Primitive::Type field_type = GetFieldAccessType(*dex_file_, field_index);
   1449     BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type);
   1450     return true;
   1451   }
   1452 
   1453   Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
   1454 
   1455   Handle<mirror::Class> klass = handles_->NewHandle(resolved_field->GetDeclaringClass());
   1456   HLoadClass* constant = BuildLoadClass(klass->GetDexTypeIndex(),
   1457                                         klass->GetDexFile(),
   1458                                         klass,
   1459                                         dex_pc,
   1460                                         /* needs_access_check */ false);
   1461 
   1462   if (constant == nullptr) {
   1463     // The class cannot be referenced from this compiled code. Generate
   1464     // an unresolved access.
   1465     MaybeRecordStat(MethodCompilationStat::kUnresolvedFieldNotAFastAccess);
   1466     BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type);
   1467     return true;
   1468   }
   1469 
   1470   HInstruction* cls = constant;
   1471   if (!IsInitialized(klass)) {
   1472     cls = new (arena_) HClinitCheck(constant, dex_pc);
   1473     AppendInstruction(cls);
   1474   }
   1475 
   1476   uint16_t class_def_index = klass->GetDexClassDefIndex();
   1477   if (is_put) {
   1478     // We need to keep the class alive before loading the value.
   1479     HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
   1480     DCHECK_EQ(HPhi::ToPhiType(value->GetType()), HPhi::ToPhiType(field_type));
   1481     AppendInstruction(new (arena_) HStaticFieldSet(cls,
   1482                                                    value,
   1483                                                    resolved_field,
   1484                                                    field_type,
   1485                                                    resolved_field->GetOffset(),
   1486                                                    resolved_field->IsVolatile(),
   1487                                                    field_index,
   1488                                                    class_def_index,
   1489                                                    *dex_file_,
   1490                                                    dex_pc));
   1491   } else {
   1492     AppendInstruction(new (arena_) HStaticFieldGet(cls,
   1493                                                    resolved_field,
   1494                                                    field_type,
   1495                                                    resolved_field->GetOffset(),
   1496                                                    resolved_field->IsVolatile(),
   1497                                                    field_index,
   1498                                                    class_def_index,
   1499                                                    *dex_file_,
   1500                                                    dex_pc));
   1501     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
   1502   }
   1503   return true;
   1504 }
   1505 
   1506 void HInstructionBuilder::BuildCheckedDivRem(uint16_t out_vreg,
   1507                                        uint16_t first_vreg,
   1508                                        int64_t second_vreg_or_constant,
   1509                                        uint32_t dex_pc,
   1510                                        Primitive::Type type,
   1511                                        bool second_is_constant,
   1512                                        bool isDiv) {
   1513   DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong);
   1514 
   1515   HInstruction* first = LoadLocal(first_vreg, type);
   1516   HInstruction* second = nullptr;
   1517   if (second_is_constant) {
   1518     if (type == Primitive::kPrimInt) {
   1519       second = graph_->GetIntConstant(second_vreg_or_constant, dex_pc);
   1520     } else {
   1521       second = graph_->GetLongConstant(second_vreg_or_constant, dex_pc);
   1522     }
   1523   } else {
   1524     second = LoadLocal(second_vreg_or_constant, type);
   1525   }
   1526 
   1527   if (!second_is_constant
   1528       || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0)
   1529       || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) {
   1530     second = new (arena_) HDivZeroCheck(second, dex_pc);
   1531     AppendInstruction(second);
   1532   }
   1533 
   1534   if (isDiv) {
   1535     AppendInstruction(new (arena_) HDiv(type, first, second, dex_pc));
   1536   } else {
   1537     AppendInstruction(new (arena_) HRem(type, first, second, dex_pc));
   1538   }
   1539   UpdateLocal(out_vreg, current_block_->GetLastInstruction());
   1540 }
   1541 
   1542 void HInstructionBuilder::BuildArrayAccess(const Instruction& instruction,
   1543                                            uint32_t dex_pc,
   1544                                            bool is_put,
   1545                                            Primitive::Type anticipated_type) {
   1546   uint8_t source_or_dest_reg = instruction.VRegA_23x();
   1547   uint8_t array_reg = instruction.VRegB_23x();
   1548   uint8_t index_reg = instruction.VRegC_23x();
   1549 
   1550   HInstruction* object = LoadNullCheckedLocal(array_reg, dex_pc);
   1551   HInstruction* length = new (arena_) HArrayLength(object, dex_pc);
   1552   AppendInstruction(length);
   1553   HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt);
   1554   index = new (arena_) HBoundsCheck(index, length, dex_pc);
   1555   AppendInstruction(index);
   1556   if (is_put) {
   1557     HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type);
   1558     // TODO: Insert a type check node if the type is Object.
   1559     HArraySet* aset = new (arena_) HArraySet(object, index, value, anticipated_type, dex_pc);
   1560     ssa_builder_->MaybeAddAmbiguousArraySet(aset);
   1561     AppendInstruction(aset);
   1562   } else {
   1563     HArrayGet* aget = new (arena_) HArrayGet(object, index, anticipated_type, dex_pc);
   1564     ssa_builder_->MaybeAddAmbiguousArrayGet(aget);
   1565     AppendInstruction(aget);
   1566     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
   1567   }
   1568   graph_->SetHasBoundsChecks(true);
   1569 }
   1570 
   1571 HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc,
   1572                                                     dex::TypeIndex type_index,
   1573                                                     uint32_t number_of_vreg_arguments,
   1574                                                     bool is_range,
   1575                                                     uint32_t* args,
   1576                                                     uint32_t register_index) {
   1577   HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments, dex_pc);
   1578   HLoadClass* cls = BuildLoadClass(type_index, dex_pc);
   1579   HNewArray* const object = new (arena_) HNewArray(cls, length, dex_pc);
   1580   AppendInstruction(object);
   1581 
   1582   const char* descriptor = dex_file_->StringByTypeIdx(type_index);
   1583   DCHECK_EQ(descriptor[0], '[') << descriptor;
   1584   char primitive = descriptor[1];
   1585   DCHECK(primitive == 'I'
   1586       || primitive == 'L'
   1587       || primitive == '[') << descriptor;
   1588   bool is_reference_array = (primitive == 'L') || (primitive == '[');
   1589   Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt;
   1590 
   1591   for (size_t i = 0; i < number_of_vreg_arguments; ++i) {
   1592     HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type);
   1593     HInstruction* index = graph_->GetIntConstant(i, dex_pc);
   1594     HArraySet* aset = new (arena_) HArraySet(object, index, value, type, dex_pc);
   1595     ssa_builder_->MaybeAddAmbiguousArraySet(aset);
   1596     AppendInstruction(aset);
   1597   }
   1598   latest_result_ = object;
   1599 
   1600   return object;
   1601 }
   1602 
   1603 template <typename T>
   1604 void HInstructionBuilder::BuildFillArrayData(HInstruction* object,
   1605                                              const T* data,
   1606                                              uint32_t element_count,
   1607                                              Primitive::Type anticipated_type,
   1608                                              uint32_t dex_pc) {
   1609   for (uint32_t i = 0; i < element_count; ++i) {
   1610     HInstruction* index = graph_->GetIntConstant(i, dex_pc);
   1611     HInstruction* value = graph_->GetIntConstant(data[i], dex_pc);
   1612     HArraySet* aset = new (arena_) HArraySet(object, index, value, anticipated_type, dex_pc);
   1613     ssa_builder_->MaybeAddAmbiguousArraySet(aset);
   1614     AppendInstruction(aset);
   1615   }
   1616 }
   1617 
   1618 void HInstructionBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) {
   1619   HInstruction* array = LoadNullCheckedLocal(instruction.VRegA_31t(), dex_pc);
   1620 
   1621   int32_t payload_offset = instruction.VRegB_31t() + dex_pc;
   1622   const Instruction::ArrayDataPayload* payload =
   1623       reinterpret_cast<const Instruction::ArrayDataPayload*>(code_item_.insns_ + payload_offset);
   1624   const uint8_t* data = payload->data;
   1625   uint32_t element_count = payload->element_count;
   1626 
   1627   if (element_count == 0u) {
   1628     // For empty payload we emit only the null check above.
   1629     return;
   1630   }
   1631 
   1632   HInstruction* length = new (arena_) HArrayLength(array, dex_pc);
   1633   AppendInstruction(length);
   1634 
   1635   // Implementation of this DEX instruction seems to be that the bounds check is
   1636   // done before doing any stores.
   1637   HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1, dex_pc);
   1638   AppendInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc));
   1639 
   1640   switch (payload->element_width) {
   1641     case 1:
   1642       BuildFillArrayData(array,
   1643                          reinterpret_cast<const int8_t*>(data),
   1644                          element_count,
   1645                          Primitive::kPrimByte,
   1646                          dex_pc);
   1647       break;
   1648     case 2:
   1649       BuildFillArrayData(array,
   1650                          reinterpret_cast<const int16_t*>(data),
   1651                          element_count,
   1652                          Primitive::kPrimShort,
   1653                          dex_pc);
   1654       break;
   1655     case 4:
   1656       BuildFillArrayData(array,
   1657                          reinterpret_cast<const int32_t*>(data),
   1658                          element_count,
   1659                          Primitive::kPrimInt,
   1660                          dex_pc);
   1661       break;
   1662     case 8:
   1663       BuildFillWideArrayData(array,
   1664                              reinterpret_cast<const int64_t*>(data),
   1665                              element_count,
   1666                              dex_pc);
   1667       break;
   1668     default:
   1669       LOG(FATAL) << "Unknown element width for " << payload->element_width;
   1670   }
   1671   graph_->SetHasBoundsChecks(true);
   1672 }
   1673 
   1674 void HInstructionBuilder::BuildFillWideArrayData(HInstruction* object,
   1675                                                  const int64_t* data,
   1676                                                  uint32_t element_count,
   1677                                                  uint32_t dex_pc) {
   1678   for (uint32_t i = 0; i < element_count; ++i) {
   1679     HInstruction* index = graph_->GetIntConstant(i, dex_pc);
   1680     HInstruction* value = graph_->GetLongConstant(data[i], dex_pc);
   1681     HArraySet* aset = new (arena_) HArraySet(object, index, value, Primitive::kPrimLong, dex_pc);
   1682     ssa_builder_->MaybeAddAmbiguousArraySet(aset);
   1683     AppendInstruction(aset);
   1684   }
   1685 }
   1686 
   1687 static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls)
   1688     REQUIRES_SHARED(Locks::mutator_lock_) {
   1689   if (cls == nullptr) {
   1690     return TypeCheckKind::kUnresolvedCheck;
   1691   } else if (cls->IsInterface()) {
   1692     return TypeCheckKind::kInterfaceCheck;
   1693   } else if (cls->IsArrayClass()) {
   1694     if (cls->GetComponentType()->IsObjectClass()) {
   1695       return TypeCheckKind::kArrayObjectCheck;
   1696     } else if (cls->CannotBeAssignedFromOtherTypes()) {
   1697       return TypeCheckKind::kExactCheck;
   1698     } else {
   1699       return TypeCheckKind::kArrayCheck;
   1700     }
   1701   } else if (cls->IsFinal()) {
   1702     return TypeCheckKind::kExactCheck;
   1703   } else if (cls->IsAbstract()) {
   1704     return TypeCheckKind::kAbstractClassCheck;
   1705   } else {
   1706     return TypeCheckKind::kClassHierarchyCheck;
   1707   }
   1708 }
   1709 
   1710 HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) {
   1711   ScopedObjectAccess soa(Thread::Current());
   1712   const DexFile& dex_file = *dex_compilation_unit_->GetDexFile();
   1713   Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader();
   1714   Handle<mirror::Class> klass = handles_->NewHandle(compiler_driver_->ResolveClass(
   1715       soa, dex_compilation_unit_->GetDexCache(), class_loader, type_index, dex_compilation_unit_));
   1716 
   1717   bool needs_access_check = true;
   1718   if (klass != nullptr) {
   1719     if (klass->IsPublic()) {
   1720       needs_access_check = false;
   1721     } else {
   1722       mirror::Class* compiling_class = GetCompilingClass();
   1723       if (compiling_class != nullptr && compiling_class->CanAccess(klass.Get())) {
   1724         needs_access_check = false;
   1725       }
   1726     }
   1727   }
   1728 
   1729   return BuildLoadClass(type_index, dex_file, klass, dex_pc, needs_access_check);
   1730 }
   1731 
   1732 HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index,
   1733                                                 const DexFile& dex_file,
   1734                                                 Handle<mirror::Class> klass,
   1735                                                 uint32_t dex_pc,
   1736                                                 bool needs_access_check) {
   1737   // Try to find a reference in the compiling dex file.
   1738   const DexFile* actual_dex_file = &dex_file;
   1739   if (!IsSameDexFile(dex_file, *dex_compilation_unit_->GetDexFile())) {
   1740     dex::TypeIndex local_type_index =
   1741         klass->FindTypeIndexInOtherDexFile(*dex_compilation_unit_->GetDexFile());
   1742     if (local_type_index.IsValid()) {
   1743       type_index = local_type_index;
   1744       actual_dex_file = dex_compilation_unit_->GetDexFile();
   1745     }
   1746   }
   1747 
   1748   // Note: `klass` must be from `handles_`.
   1749   HLoadClass* load_class = new (arena_) HLoadClass(
   1750       graph_->GetCurrentMethod(),
   1751       type_index,
   1752       *actual_dex_file,
   1753       klass,
   1754       klass != nullptr && (klass.Get() == GetOutermostCompilingClass()),
   1755       dex_pc,
   1756       needs_access_check);
   1757 
   1758   HLoadClass::LoadKind load_kind = HSharpening::ComputeLoadClassKind(load_class,
   1759                                                                      code_generator_,
   1760                                                                      compiler_driver_,
   1761                                                                      *dex_compilation_unit_);
   1762 
   1763   if (load_kind == HLoadClass::LoadKind::kInvalid) {
   1764     // We actually cannot reference this class, we're forced to bail.
   1765     return nullptr;
   1766   }
   1767   // Append the instruction first, as setting the load kind affects the inputs.
   1768   AppendInstruction(load_class);
   1769   load_class->SetLoadKind(load_kind);
   1770   return load_class;
   1771 }
   1772 
   1773 void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction,
   1774                                          uint8_t destination,
   1775                                          uint8_t reference,
   1776                                          dex::TypeIndex type_index,
   1777                                          uint32_t dex_pc) {
   1778   HInstruction* object = LoadLocal(reference, Primitive::kPrimNot);
   1779   HLoadClass* cls = BuildLoadClass(type_index, dex_pc);
   1780 
   1781   ScopedObjectAccess soa(Thread::Current());
   1782   TypeCheckKind check_kind = ComputeTypeCheckKind(cls->GetClass());
   1783   if (instruction.Opcode() == Instruction::INSTANCE_OF) {
   1784     AppendInstruction(new (arena_) HInstanceOf(object, cls, check_kind, dex_pc));
   1785     UpdateLocal(destination, current_block_->GetLastInstruction());
   1786   } else {
   1787     DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST);
   1788     // We emit a CheckCast followed by a BoundType. CheckCast is a statement
   1789     // which may throw. If it succeeds BoundType sets the new type of `object`
   1790     // for all subsequent uses.
   1791     AppendInstruction(new (arena_) HCheckCast(object, cls, check_kind, dex_pc));
   1792     AppendInstruction(new (arena_) HBoundType(object, dex_pc));
   1793     UpdateLocal(reference, current_block_->GetLastInstruction());
   1794   }
   1795 }
   1796 
   1797 bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const {
   1798   return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks(
   1799       LookupReferrerClass(), LookupResolvedType(type_index, *dex_compilation_unit_), finalizable);
   1800 }
   1801 
   1802 bool HInstructionBuilder::CanDecodeQuickenedInfo() const {
   1803   return !quicken_info_.IsNull();
   1804 }
   1805 
   1806 uint16_t HInstructionBuilder::LookupQuickenedInfo(uint32_t quicken_index) {
   1807   DCHECK(CanDecodeQuickenedInfo());
   1808   return quicken_info_.GetData(quicken_index);
   1809 }
   1810 
   1811 bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction,
   1812                                                 uint32_t dex_pc,
   1813                                                 size_t quicken_index) {
   1814   switch (instruction.Opcode()) {
   1815     case Instruction::CONST_4: {
   1816       int32_t register_index = instruction.VRegA();
   1817       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n(), dex_pc);
   1818       UpdateLocal(register_index, constant);
   1819       break;
   1820     }
   1821 
   1822     case Instruction::CONST_16: {
   1823       int32_t register_index = instruction.VRegA();
   1824       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s(), dex_pc);
   1825       UpdateLocal(register_index, constant);
   1826       break;
   1827     }
   1828 
   1829     case Instruction::CONST: {
   1830       int32_t register_index = instruction.VRegA();
   1831       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i(), dex_pc);
   1832       UpdateLocal(register_index, constant);
   1833       break;
   1834     }
   1835 
   1836     case Instruction::CONST_HIGH16: {
   1837       int32_t register_index = instruction.VRegA();
   1838       HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16, dex_pc);
   1839       UpdateLocal(register_index, constant);
   1840       break;
   1841     }
   1842 
   1843     case Instruction::CONST_WIDE_16: {
   1844       int32_t register_index = instruction.VRegA();
   1845       // Get 16 bits of constant value, sign extended to 64 bits.
   1846       int64_t value = instruction.VRegB_21s();
   1847       value <<= 48;
   1848       value >>= 48;
   1849       HLongConstant* constant = graph_->GetLongConstant(value, dex_pc);
   1850       UpdateLocal(register_index, constant);
   1851       break;
   1852     }
   1853 
   1854     case Instruction::CONST_WIDE_32: {
   1855       int32_t register_index = instruction.VRegA();
   1856       // Get 32 bits of constant value, sign extended to 64 bits.
   1857       int64_t value = instruction.VRegB_31i();
   1858       value <<= 32;
   1859       value >>= 32;
   1860       HLongConstant* constant = graph_->GetLongConstant(value, dex_pc);
   1861       UpdateLocal(register_index, constant);
   1862       break;
   1863     }
   1864 
   1865     case Instruction::CONST_WIDE: {
   1866       int32_t register_index = instruction.VRegA();
   1867       HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l(), dex_pc);
   1868       UpdateLocal(register_index, constant);
   1869       break;
   1870     }
   1871 
   1872     case Instruction::CONST_WIDE_HIGH16: {
   1873       int32_t register_index = instruction.VRegA();
   1874       int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48;
   1875       HLongConstant* constant = graph_->GetLongConstant(value, dex_pc);
   1876       UpdateLocal(register_index, constant);
   1877       break;
   1878     }
   1879 
   1880     // Note that the SSA building will refine the types.
   1881     case Instruction::MOVE:
   1882     case Instruction::MOVE_FROM16:
   1883     case Instruction::MOVE_16: {
   1884       HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
   1885       UpdateLocal(instruction.VRegA(), value);
   1886       break;
   1887     }
   1888 
   1889     // Note that the SSA building will refine the types.
   1890     case Instruction::MOVE_WIDE:
   1891     case Instruction::MOVE_WIDE_FROM16:
   1892     case Instruction::MOVE_WIDE_16: {
   1893       HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong);
   1894       UpdateLocal(instruction.VRegA(), value);
   1895       break;
   1896     }
   1897 
   1898     case Instruction::MOVE_OBJECT:
   1899     case Instruction::MOVE_OBJECT_16:
   1900     case Instruction::MOVE_OBJECT_FROM16: {
   1901       // The verifier has no notion of a null type, so a move-object of constant 0
   1902       // will lead to the same constant 0 in the destination register. To mimic
   1903       // this behavior, we just pretend we haven't seen a type change (int to reference)
   1904       // for the 0 constant and phis. We rely on our type propagation to eventually get the
   1905       // types correct.
   1906       uint32_t reg_number = instruction.VRegB();
   1907       HInstruction* value = (*current_locals_)[reg_number];
   1908       if (value->IsIntConstant()) {
   1909         DCHECK_EQ(value->AsIntConstant()->GetValue(), 0);
   1910       } else if (value->IsPhi()) {
   1911         DCHECK(value->GetType() == Primitive::kPrimInt || value->GetType() == Primitive::kPrimNot);
   1912       } else {
   1913         value = LoadLocal(reg_number, Primitive::kPrimNot);
   1914       }
   1915       UpdateLocal(instruction.VRegA(), value);
   1916       break;
   1917     }
   1918 
   1919     case Instruction::RETURN_VOID_NO_BARRIER:
   1920     case Instruction::RETURN_VOID: {
   1921       BuildReturn(instruction, Primitive::kPrimVoid, dex_pc);
   1922       break;
   1923     }
   1924 
   1925 #define IF_XX(comparison, cond) \
   1926     case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \
   1927     case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break
   1928 
   1929     IF_XX(HEqual, EQ);
   1930     IF_XX(HNotEqual, NE);
   1931     IF_XX(HLessThan, LT);
   1932     IF_XX(HLessThanOrEqual, LE);
   1933     IF_XX(HGreaterThan, GT);
   1934     IF_XX(HGreaterThanOrEqual, GE);
   1935 
   1936     case Instruction::GOTO:
   1937     case Instruction::GOTO_16:
   1938     case Instruction::GOTO_32: {
   1939       AppendInstruction(new (arena_) HGoto(dex_pc));
   1940       current_block_ = nullptr;
   1941       break;
   1942     }
   1943 
   1944     case Instruction::RETURN: {
   1945       BuildReturn(instruction, return_type_, dex_pc);
   1946       break;
   1947     }
   1948 
   1949     case Instruction::RETURN_OBJECT: {
   1950       BuildReturn(instruction, return_type_, dex_pc);
   1951       break;
   1952     }
   1953 
   1954     case Instruction::RETURN_WIDE: {
   1955       BuildReturn(instruction, return_type_, dex_pc);
   1956       break;
   1957     }
   1958 
   1959     case Instruction::INVOKE_DIRECT:
   1960     case Instruction::INVOKE_INTERFACE:
   1961     case Instruction::INVOKE_STATIC:
   1962     case Instruction::INVOKE_SUPER:
   1963     case Instruction::INVOKE_VIRTUAL:
   1964     case Instruction::INVOKE_VIRTUAL_QUICK: {
   1965       uint16_t method_idx;
   1966       if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_QUICK) {
   1967         if (!CanDecodeQuickenedInfo()) {
   1968           return false;
   1969         }
   1970         method_idx = LookupQuickenedInfo(quicken_index);
   1971       } else {
   1972         method_idx = instruction.VRegB_35c();
   1973       }
   1974       uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
   1975       uint32_t args[5];
   1976       instruction.GetVarArgs(args);
   1977       if (!BuildInvoke(instruction, dex_pc, method_idx,
   1978                        number_of_vreg_arguments, false, args, -1)) {
   1979         return false;
   1980       }
   1981       break;
   1982     }
   1983 
   1984     case Instruction::INVOKE_DIRECT_RANGE:
   1985     case Instruction::INVOKE_INTERFACE_RANGE:
   1986     case Instruction::INVOKE_STATIC_RANGE:
   1987     case Instruction::INVOKE_SUPER_RANGE:
   1988     case Instruction::INVOKE_VIRTUAL_RANGE:
   1989     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
   1990       uint16_t method_idx;
   1991       if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK) {
   1992         if (!CanDecodeQuickenedInfo()) {
   1993           return false;
   1994         }
   1995         method_idx = LookupQuickenedInfo(quicken_index);
   1996       } else {
   1997         method_idx = instruction.VRegB_3rc();
   1998       }
   1999       uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
   2000       uint32_t register_index = instruction.VRegC();
   2001       if (!BuildInvoke(instruction, dex_pc, method_idx,
   2002                        number_of_vreg_arguments, true, nullptr, register_index)) {
   2003         return false;
   2004       }
   2005       break;
   2006     }
   2007 
   2008     case Instruction::INVOKE_POLYMORPHIC: {
   2009       uint16_t method_idx = instruction.VRegB_45cc();
   2010       uint16_t proto_idx = instruction.VRegH_45cc();
   2011       uint32_t number_of_vreg_arguments = instruction.VRegA_45cc();
   2012       uint32_t args[5];
   2013       instruction.GetVarArgs(args);
   2014       return BuildInvokePolymorphic(instruction,
   2015                                     dex_pc,
   2016                                     method_idx,
   2017                                     proto_idx,
   2018                                     number_of_vreg_arguments,
   2019                                     false,
   2020                                     args,
   2021                                     -1);
   2022     }
   2023 
   2024     case Instruction::INVOKE_POLYMORPHIC_RANGE: {
   2025       uint16_t method_idx = instruction.VRegB_4rcc();
   2026       uint16_t proto_idx = instruction.VRegH_4rcc();
   2027       uint32_t number_of_vreg_arguments = instruction.VRegA_4rcc();
   2028       uint32_t register_index = instruction.VRegC_4rcc();
   2029       return BuildInvokePolymorphic(instruction,
   2030                                     dex_pc,
   2031                                     method_idx,
   2032                                     proto_idx,
   2033                                     number_of_vreg_arguments,
   2034                                     true,
   2035                                     nullptr,
   2036                                     register_index);
   2037     }
   2038 
   2039     case Instruction::NEG_INT: {
   2040       Unop_12x<HNeg>(instruction, Primitive::kPrimInt, dex_pc);
   2041       break;
   2042     }
   2043 
   2044     case Instruction::NEG_LONG: {
   2045       Unop_12x<HNeg>(instruction, Primitive::kPrimLong, dex_pc);
   2046       break;
   2047     }
   2048 
   2049     case Instruction::NEG_FLOAT: {
   2050       Unop_12x<HNeg>(instruction, Primitive::kPrimFloat, dex_pc);
   2051       break;
   2052     }
   2053 
   2054     case Instruction::NEG_DOUBLE: {
   2055       Unop_12x<HNeg>(instruction, Primitive::kPrimDouble, dex_pc);
   2056       break;
   2057     }
   2058 
   2059     case Instruction::NOT_INT: {
   2060       Unop_12x<HNot>(instruction, Primitive::kPrimInt, dex_pc);
   2061       break;
   2062     }
   2063 
   2064     case Instruction::NOT_LONG: {
   2065       Unop_12x<HNot>(instruction, Primitive::kPrimLong, dex_pc);
   2066       break;
   2067     }
   2068 
   2069     case Instruction::INT_TO_LONG: {
   2070       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc);
   2071       break;
   2072     }
   2073 
   2074     case Instruction::INT_TO_FLOAT: {
   2075       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc);
   2076       break;
   2077     }
   2078 
   2079     case Instruction::INT_TO_DOUBLE: {
   2080       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc);
   2081       break;
   2082     }
   2083 
   2084     case Instruction::LONG_TO_INT: {
   2085       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc);
   2086       break;
   2087     }
   2088 
   2089     case Instruction::LONG_TO_FLOAT: {
   2090       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc);
   2091       break;
   2092     }
   2093 
   2094     case Instruction::LONG_TO_DOUBLE: {
   2095       Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc);
   2096       break;
   2097     }
   2098 
   2099     case Instruction::FLOAT_TO_INT: {
   2100       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc);
   2101       break;
   2102     }
   2103 
   2104     case Instruction::FLOAT_TO_LONG: {
   2105       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc);
   2106       break;
   2107     }
   2108 
   2109     case Instruction::FLOAT_TO_DOUBLE: {
   2110       Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc);
   2111       break;
   2112     }
   2113 
   2114     case Instruction::DOUBLE_TO_INT: {
   2115       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc);
   2116       break;
   2117     }
   2118 
   2119     case Instruction::DOUBLE_TO_LONG: {
   2120       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc);
   2121       break;
   2122     }
   2123 
   2124     case Instruction::DOUBLE_TO_FLOAT: {
   2125       Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc);
   2126       break;
   2127     }
   2128 
   2129     case Instruction::INT_TO_BYTE: {
   2130       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc);
   2131       break;
   2132     }
   2133 
   2134     case Instruction::INT_TO_SHORT: {
   2135       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc);
   2136       break;
   2137     }
   2138 
   2139     case Instruction::INT_TO_CHAR: {
   2140       Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc);
   2141       break;
   2142     }
   2143 
   2144     case Instruction::ADD_INT: {
   2145       Binop_23x<HAdd>(instruction, Primitive::kPrimInt, dex_pc);
   2146       break;
   2147     }
   2148 
   2149     case Instruction::ADD_LONG: {
   2150       Binop_23x<HAdd>(instruction, Primitive::kPrimLong, dex_pc);
   2151       break;
   2152     }
   2153 
   2154     case Instruction::ADD_DOUBLE: {
   2155       Binop_23x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc);
   2156       break;
   2157     }
   2158 
   2159     case Instruction::ADD_FLOAT: {
   2160       Binop_23x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc);
   2161       break;
   2162     }
   2163 
   2164     case Instruction::SUB_INT: {
   2165       Binop_23x<HSub>(instruction, Primitive::kPrimInt, dex_pc);
   2166       break;
   2167     }
   2168 
   2169     case Instruction::SUB_LONG: {
   2170       Binop_23x<HSub>(instruction, Primitive::kPrimLong, dex_pc);
   2171       break;
   2172     }
   2173 
   2174     case Instruction::SUB_FLOAT: {
   2175       Binop_23x<HSub>(instruction, Primitive::kPrimFloat, dex_pc);
   2176       break;
   2177     }
   2178 
   2179     case Instruction::SUB_DOUBLE: {
   2180       Binop_23x<HSub>(instruction, Primitive::kPrimDouble, dex_pc);
   2181       break;
   2182     }
   2183 
   2184     case Instruction::ADD_INT_2ADDR: {
   2185       Binop_12x<HAdd>(instruction, Primitive::kPrimInt, dex_pc);
   2186       break;
   2187     }
   2188 
   2189     case Instruction::MUL_INT: {
   2190       Binop_23x<HMul>(instruction, Primitive::kPrimInt, dex_pc);
   2191       break;
   2192     }
   2193 
   2194     case Instruction::MUL_LONG: {
   2195       Binop_23x<HMul>(instruction, Primitive::kPrimLong, dex_pc);
   2196       break;
   2197     }
   2198 
   2199     case Instruction::MUL_FLOAT: {
   2200       Binop_23x<HMul>(instruction, Primitive::kPrimFloat, dex_pc);
   2201       break;
   2202     }
   2203 
   2204     case Instruction::MUL_DOUBLE: {
   2205       Binop_23x<HMul>(instruction, Primitive::kPrimDouble, dex_pc);
   2206       break;
   2207     }
   2208 
   2209     case Instruction::DIV_INT: {
   2210       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2211                          dex_pc, Primitive::kPrimInt, false, true);
   2212       break;
   2213     }
   2214 
   2215     case Instruction::DIV_LONG: {
   2216       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2217                          dex_pc, Primitive::kPrimLong, false, true);
   2218       break;
   2219     }
   2220 
   2221     case Instruction::DIV_FLOAT: {
   2222       Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
   2223       break;
   2224     }
   2225 
   2226     case Instruction::DIV_DOUBLE: {
   2227       Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
   2228       break;
   2229     }
   2230 
   2231     case Instruction::REM_INT: {
   2232       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2233                          dex_pc, Primitive::kPrimInt, false, false);
   2234       break;
   2235     }
   2236 
   2237     case Instruction::REM_LONG: {
   2238       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2239                          dex_pc, Primitive::kPrimLong, false, false);
   2240       break;
   2241     }
   2242 
   2243     case Instruction::REM_FLOAT: {
   2244       Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
   2245       break;
   2246     }
   2247 
   2248     case Instruction::REM_DOUBLE: {
   2249       Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
   2250       break;
   2251     }
   2252 
   2253     case Instruction::AND_INT: {
   2254       Binop_23x<HAnd>(instruction, Primitive::kPrimInt, dex_pc);
   2255       break;
   2256     }
   2257 
   2258     case Instruction::AND_LONG: {
   2259       Binop_23x<HAnd>(instruction, Primitive::kPrimLong, dex_pc);
   2260       break;
   2261     }
   2262 
   2263     case Instruction::SHL_INT: {
   2264       Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc);
   2265       break;
   2266     }
   2267 
   2268     case Instruction::SHL_LONG: {
   2269       Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc);
   2270       break;
   2271     }
   2272 
   2273     case Instruction::SHR_INT: {
   2274       Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc);
   2275       break;
   2276     }
   2277 
   2278     case Instruction::SHR_LONG: {
   2279       Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc);
   2280       break;
   2281     }
   2282 
   2283     case Instruction::USHR_INT: {
   2284       Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc);
   2285       break;
   2286     }
   2287 
   2288     case Instruction::USHR_LONG: {
   2289       Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc);
   2290       break;
   2291     }
   2292 
   2293     case Instruction::OR_INT: {
   2294       Binop_23x<HOr>(instruction, Primitive::kPrimInt, dex_pc);
   2295       break;
   2296     }
   2297 
   2298     case Instruction::OR_LONG: {
   2299       Binop_23x<HOr>(instruction, Primitive::kPrimLong, dex_pc);
   2300       break;
   2301     }
   2302 
   2303     case Instruction::XOR_INT: {
   2304       Binop_23x<HXor>(instruction, Primitive::kPrimInt, dex_pc);
   2305       break;
   2306     }
   2307 
   2308     case Instruction::XOR_LONG: {
   2309       Binop_23x<HXor>(instruction, Primitive::kPrimLong, dex_pc);
   2310       break;
   2311     }
   2312 
   2313     case Instruction::ADD_LONG_2ADDR: {
   2314       Binop_12x<HAdd>(instruction, Primitive::kPrimLong, dex_pc);
   2315       break;
   2316     }
   2317 
   2318     case Instruction::ADD_DOUBLE_2ADDR: {
   2319       Binop_12x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc);
   2320       break;
   2321     }
   2322 
   2323     case Instruction::ADD_FLOAT_2ADDR: {
   2324       Binop_12x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc);
   2325       break;
   2326     }
   2327 
   2328     case Instruction::SUB_INT_2ADDR: {
   2329       Binop_12x<HSub>(instruction, Primitive::kPrimInt, dex_pc);
   2330       break;
   2331     }
   2332 
   2333     case Instruction::SUB_LONG_2ADDR: {
   2334       Binop_12x<HSub>(instruction, Primitive::kPrimLong, dex_pc);
   2335       break;
   2336     }
   2337 
   2338     case Instruction::SUB_FLOAT_2ADDR: {
   2339       Binop_12x<HSub>(instruction, Primitive::kPrimFloat, dex_pc);
   2340       break;
   2341     }
   2342 
   2343     case Instruction::SUB_DOUBLE_2ADDR: {
   2344       Binop_12x<HSub>(instruction, Primitive::kPrimDouble, dex_pc);
   2345       break;
   2346     }
   2347 
   2348     case Instruction::MUL_INT_2ADDR: {
   2349       Binop_12x<HMul>(instruction, Primitive::kPrimInt, dex_pc);
   2350       break;
   2351     }
   2352 
   2353     case Instruction::MUL_LONG_2ADDR: {
   2354       Binop_12x<HMul>(instruction, Primitive::kPrimLong, dex_pc);
   2355       break;
   2356     }
   2357 
   2358     case Instruction::MUL_FLOAT_2ADDR: {
   2359       Binop_12x<HMul>(instruction, Primitive::kPrimFloat, dex_pc);
   2360       break;
   2361     }
   2362 
   2363     case Instruction::MUL_DOUBLE_2ADDR: {
   2364       Binop_12x<HMul>(instruction, Primitive::kPrimDouble, dex_pc);
   2365       break;
   2366     }
   2367 
   2368     case Instruction::DIV_INT_2ADDR: {
   2369       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   2370                          dex_pc, Primitive::kPrimInt, false, true);
   2371       break;
   2372     }
   2373 
   2374     case Instruction::DIV_LONG_2ADDR: {
   2375       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   2376                          dex_pc, Primitive::kPrimLong, false, true);
   2377       break;
   2378     }
   2379 
   2380     case Instruction::REM_INT_2ADDR: {
   2381       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   2382                          dex_pc, Primitive::kPrimInt, false, false);
   2383       break;
   2384     }
   2385 
   2386     case Instruction::REM_LONG_2ADDR: {
   2387       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
   2388                          dex_pc, Primitive::kPrimLong, false, false);
   2389       break;
   2390     }
   2391 
   2392     case Instruction::REM_FLOAT_2ADDR: {
   2393       Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
   2394       break;
   2395     }
   2396 
   2397     case Instruction::REM_DOUBLE_2ADDR: {
   2398       Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
   2399       break;
   2400     }
   2401 
   2402     case Instruction::SHL_INT_2ADDR: {
   2403       Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc);
   2404       break;
   2405     }
   2406 
   2407     case Instruction::SHL_LONG_2ADDR: {
   2408       Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc);
   2409       break;
   2410     }
   2411 
   2412     case Instruction::SHR_INT_2ADDR: {
   2413       Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc);
   2414       break;
   2415     }
   2416 
   2417     case Instruction::SHR_LONG_2ADDR: {
   2418       Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc);
   2419       break;
   2420     }
   2421 
   2422     case Instruction::USHR_INT_2ADDR: {
   2423       Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc);
   2424       break;
   2425     }
   2426 
   2427     case Instruction::USHR_LONG_2ADDR: {
   2428       Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc);
   2429       break;
   2430     }
   2431 
   2432     case Instruction::DIV_FLOAT_2ADDR: {
   2433       Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
   2434       break;
   2435     }
   2436 
   2437     case Instruction::DIV_DOUBLE_2ADDR: {
   2438       Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
   2439       break;
   2440     }
   2441 
   2442     case Instruction::AND_INT_2ADDR: {
   2443       Binop_12x<HAnd>(instruction, Primitive::kPrimInt, dex_pc);
   2444       break;
   2445     }
   2446 
   2447     case Instruction::AND_LONG_2ADDR: {
   2448       Binop_12x<HAnd>(instruction, Primitive::kPrimLong, dex_pc);
   2449       break;
   2450     }
   2451 
   2452     case Instruction::OR_INT_2ADDR: {
   2453       Binop_12x<HOr>(instruction, Primitive::kPrimInt, dex_pc);
   2454       break;
   2455     }
   2456 
   2457     case Instruction::OR_LONG_2ADDR: {
   2458       Binop_12x<HOr>(instruction, Primitive::kPrimLong, dex_pc);
   2459       break;
   2460     }
   2461 
   2462     case Instruction::XOR_INT_2ADDR: {
   2463       Binop_12x<HXor>(instruction, Primitive::kPrimInt, dex_pc);
   2464       break;
   2465     }
   2466 
   2467     case Instruction::XOR_LONG_2ADDR: {
   2468       Binop_12x<HXor>(instruction, Primitive::kPrimLong, dex_pc);
   2469       break;
   2470     }
   2471 
   2472     case Instruction::ADD_INT_LIT16: {
   2473       Binop_22s<HAdd>(instruction, false, dex_pc);
   2474       break;
   2475     }
   2476 
   2477     case Instruction::AND_INT_LIT16: {
   2478       Binop_22s<HAnd>(instruction, false, dex_pc);
   2479       break;
   2480     }
   2481 
   2482     case Instruction::OR_INT_LIT16: {
   2483       Binop_22s<HOr>(instruction, false, dex_pc);
   2484       break;
   2485     }
   2486 
   2487     case Instruction::XOR_INT_LIT16: {
   2488       Binop_22s<HXor>(instruction, false, dex_pc);
   2489       break;
   2490     }
   2491 
   2492     case Instruction::RSUB_INT: {
   2493       Binop_22s<HSub>(instruction, true, dex_pc);
   2494       break;
   2495     }
   2496 
   2497     case Instruction::MUL_INT_LIT16: {
   2498       Binop_22s<HMul>(instruction, false, dex_pc);
   2499       break;
   2500     }
   2501 
   2502     case Instruction::ADD_INT_LIT8: {
   2503       Binop_22b<HAdd>(instruction, false, dex_pc);
   2504       break;
   2505     }
   2506 
   2507     case Instruction::AND_INT_LIT8: {
   2508       Binop_22b<HAnd>(instruction, false, dex_pc);
   2509       break;
   2510     }
   2511 
   2512     case Instruction::OR_INT_LIT8: {
   2513       Binop_22b<HOr>(instruction, false, dex_pc);
   2514       break;
   2515     }
   2516 
   2517     case Instruction::XOR_INT_LIT8: {
   2518       Binop_22b<HXor>(instruction, false, dex_pc);
   2519       break;
   2520     }
   2521 
   2522     case Instruction::RSUB_INT_LIT8: {
   2523       Binop_22b<HSub>(instruction, true, dex_pc);
   2524       break;
   2525     }
   2526 
   2527     case Instruction::MUL_INT_LIT8: {
   2528       Binop_22b<HMul>(instruction, false, dex_pc);
   2529       break;
   2530     }
   2531 
   2532     case Instruction::DIV_INT_LIT16:
   2533     case Instruction::DIV_INT_LIT8: {
   2534       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2535                          dex_pc, Primitive::kPrimInt, true, true);
   2536       break;
   2537     }
   2538 
   2539     case Instruction::REM_INT_LIT16:
   2540     case Instruction::REM_INT_LIT8: {
   2541       BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
   2542                          dex_pc, Primitive::kPrimInt, true, false);
   2543       break;
   2544     }
   2545 
   2546     case Instruction::SHL_INT_LIT8: {
   2547       Binop_22b<HShl>(instruction, false, dex_pc);
   2548       break;
   2549     }
   2550 
   2551     case Instruction::SHR_INT_LIT8: {
   2552       Binop_22b<HShr>(instruction, false, dex_pc);
   2553       break;
   2554     }
   2555 
   2556     case Instruction::USHR_INT_LIT8: {
   2557       Binop_22b<HUShr>(instruction, false, dex_pc);
   2558       break;
   2559     }
   2560 
   2561     case Instruction::NEW_INSTANCE: {
   2562       HNewInstance* new_instance =
   2563           BuildNewInstance(dex::TypeIndex(instruction.VRegB_21c()), dex_pc);
   2564       DCHECK(new_instance != nullptr);
   2565 
   2566       UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
   2567       BuildConstructorFenceForAllocation(new_instance);
   2568       break;
   2569     }
   2570 
   2571     case Instruction::NEW_ARRAY: {
   2572       dex::TypeIndex type_index(instruction.VRegC_22c());
   2573       HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt);
   2574       HLoadClass* cls = BuildLoadClass(type_index, dex_pc);
   2575 
   2576       HNewArray* new_array = new (arena_) HNewArray(cls, length, dex_pc);
   2577       AppendInstruction(new_array);
   2578       UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
   2579       BuildConstructorFenceForAllocation(new_array);
   2580       break;
   2581     }
   2582 
   2583     case Instruction::FILLED_NEW_ARRAY: {
   2584       uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
   2585       dex::TypeIndex type_index(instruction.VRegB_35c());
   2586       uint32_t args[5];
   2587       instruction.GetVarArgs(args);
   2588       HNewArray* new_array = BuildFilledNewArray(dex_pc,
   2589                                                  type_index,
   2590                                                  number_of_vreg_arguments,
   2591                                                  /* is_range */ false,
   2592                                                  args,
   2593                                                  /* register_index */ 0);
   2594       BuildConstructorFenceForAllocation(new_array);
   2595       break;
   2596     }
   2597 
   2598     case Instruction::FILLED_NEW_ARRAY_RANGE: {
   2599       uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
   2600       dex::TypeIndex type_index(instruction.VRegB_3rc());
   2601       uint32_t register_index = instruction.VRegC_3rc();
   2602       HNewArray* new_array = BuildFilledNewArray(dex_pc,
   2603                                                  type_index,
   2604                                                  number_of_vreg_arguments,
   2605                                                  /* is_range */ true,
   2606                                                  /* args*/ nullptr,
   2607                                                  register_index);
   2608       BuildConstructorFenceForAllocation(new_array);
   2609       break;
   2610     }
   2611 
   2612     case Instruction::FILL_ARRAY_DATA: {
   2613       BuildFillArrayData(instruction, dex_pc);
   2614       break;
   2615     }
   2616 
   2617     case Instruction::MOVE_RESULT:
   2618     case Instruction::MOVE_RESULT_WIDE:
   2619     case Instruction::MOVE_RESULT_OBJECT: {
   2620       DCHECK(latest_result_ != nullptr);
   2621       UpdateLocal(instruction.VRegA(), latest_result_);
   2622       latest_result_ = nullptr;
   2623       break;
   2624     }
   2625 
   2626     case Instruction::CMP_LONG: {
   2627       Binop_23x_cmp(instruction, Primitive::kPrimLong, ComparisonBias::kNoBias, dex_pc);
   2628       break;
   2629     }
   2630 
   2631     case Instruction::CMPG_FLOAT: {
   2632       Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kGtBias, dex_pc);
   2633       break;
   2634     }
   2635 
   2636     case Instruction::CMPG_DOUBLE: {
   2637       Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kGtBias, dex_pc);
   2638       break;
   2639     }
   2640 
   2641     case Instruction::CMPL_FLOAT: {
   2642       Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kLtBias, dex_pc);
   2643       break;
   2644     }
   2645 
   2646     case Instruction::CMPL_DOUBLE: {
   2647       Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kLtBias, dex_pc);
   2648       break;
   2649     }
   2650 
   2651     case Instruction::NOP:
   2652       break;
   2653 
   2654     case Instruction::IGET:
   2655     case Instruction::IGET_QUICK:
   2656     case Instruction::IGET_WIDE:
   2657     case Instruction::IGET_WIDE_QUICK:
   2658     case Instruction::IGET_OBJECT:
   2659     case Instruction::IGET_OBJECT_QUICK:
   2660     case Instruction::IGET_BOOLEAN:
   2661     case Instruction::IGET_BOOLEAN_QUICK:
   2662     case Instruction::IGET_BYTE:
   2663     case Instruction::IGET_BYTE_QUICK:
   2664     case Instruction::IGET_CHAR:
   2665     case Instruction::IGET_CHAR_QUICK:
   2666     case Instruction::IGET_SHORT:
   2667     case Instruction::IGET_SHORT_QUICK: {
   2668       if (!BuildInstanceFieldAccess(instruction, dex_pc, false, quicken_index)) {
   2669         return false;
   2670       }
   2671       break;
   2672     }
   2673 
   2674     case Instruction::IPUT:
   2675     case Instruction::IPUT_QUICK:
   2676     case Instruction::IPUT_WIDE:
   2677     case Instruction::IPUT_WIDE_QUICK:
   2678     case Instruction::IPUT_OBJECT:
   2679     case Instruction::IPUT_OBJECT_QUICK:
   2680     case Instruction::IPUT_BOOLEAN:
   2681     case Instruction::IPUT_BOOLEAN_QUICK:
   2682     case Instruction::IPUT_BYTE:
   2683     case Instruction::IPUT_BYTE_QUICK:
   2684     case Instruction::IPUT_CHAR:
   2685     case Instruction::IPUT_CHAR_QUICK:
   2686     case Instruction::IPUT_SHORT:
   2687     case Instruction::IPUT_SHORT_QUICK: {
   2688       if (!BuildInstanceFieldAccess(instruction, dex_pc, true, quicken_index)) {
   2689         return false;
   2690       }
   2691       break;
   2692     }
   2693 
   2694     case Instruction::SGET:
   2695     case Instruction::SGET_WIDE:
   2696     case Instruction::SGET_OBJECT:
   2697     case Instruction::SGET_BOOLEAN:
   2698     case Instruction::SGET_BYTE:
   2699     case Instruction::SGET_CHAR:
   2700     case Instruction::SGET_SHORT: {
   2701       if (!BuildStaticFieldAccess(instruction, dex_pc, false)) {
   2702         return false;
   2703       }
   2704       break;
   2705     }
   2706 
   2707     case Instruction::SPUT:
   2708     case Instruction::SPUT_WIDE:
   2709     case Instruction::SPUT_OBJECT:
   2710     case Instruction::SPUT_BOOLEAN:
   2711     case Instruction::SPUT_BYTE:
   2712     case Instruction::SPUT_CHAR:
   2713     case Instruction::SPUT_SHORT: {
   2714       if (!BuildStaticFieldAccess(instruction, dex_pc, true)) {
   2715         return false;
   2716       }
   2717       break;
   2718     }
   2719 
   2720 #define ARRAY_XX(kind, anticipated_type)                                          \
   2721     case Instruction::AGET##kind: {                                               \
   2722       BuildArrayAccess(instruction, dex_pc, false, anticipated_type);         \
   2723       break;                                                                      \
   2724     }                                                                             \
   2725     case Instruction::APUT##kind: {                                               \
   2726       BuildArrayAccess(instruction, dex_pc, true, anticipated_type);          \
   2727       break;                                                                      \
   2728     }
   2729 
   2730     ARRAY_XX(, Primitive::kPrimInt);
   2731     ARRAY_XX(_WIDE, Primitive::kPrimLong);
   2732     ARRAY_XX(_OBJECT, Primitive::kPrimNot);
   2733     ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean);
   2734     ARRAY_XX(_BYTE, Primitive::kPrimByte);
   2735     ARRAY_XX(_CHAR, Primitive::kPrimChar);
   2736     ARRAY_XX(_SHORT, Primitive::kPrimShort);
   2737 
   2738     case Instruction::ARRAY_LENGTH: {
   2739       HInstruction* object = LoadNullCheckedLocal(instruction.VRegB_12x(), dex_pc);
   2740       AppendInstruction(new (arena_) HArrayLength(object, dex_pc));
   2741       UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction());
   2742       break;
   2743     }
   2744 
   2745     case Instruction::CONST_STRING: {
   2746       dex::StringIndex string_index(instruction.VRegB_21c());
   2747       AppendInstruction(
   2748           new (arena_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc));
   2749       UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
   2750       break;
   2751     }
   2752 
   2753     case Instruction::CONST_STRING_JUMBO: {
   2754       dex::StringIndex string_index(instruction.VRegB_31c());
   2755       AppendInstruction(
   2756           new (arena_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc));
   2757       UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction());
   2758       break;
   2759     }
   2760 
   2761     case Instruction::CONST_CLASS: {
   2762       dex::TypeIndex type_index(instruction.VRegB_21c());
   2763       BuildLoadClass(type_index, dex_pc);
   2764       UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
   2765       break;
   2766     }
   2767 
   2768     case Instruction::MOVE_EXCEPTION: {
   2769       AppendInstruction(new (arena_) HLoadException(dex_pc));
   2770       UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction());
   2771       AppendInstruction(new (arena_) HClearException(dex_pc));
   2772       break;
   2773     }
   2774 
   2775     case Instruction::THROW: {
   2776       HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot);
   2777       AppendInstruction(new (arena_) HThrow(exception, dex_pc));
   2778       // We finished building this block. Set the current block to null to avoid
   2779       // adding dead instructions to it.
   2780       current_block_ = nullptr;
   2781       break;
   2782     }
   2783 
   2784     case Instruction::INSTANCE_OF: {
   2785       uint8_t destination = instruction.VRegA_22c();
   2786       uint8_t reference = instruction.VRegB_22c();
   2787       dex::TypeIndex type_index(instruction.VRegC_22c());
   2788       BuildTypeCheck(instruction, destination, reference, type_index, dex_pc);
   2789       break;
   2790     }
   2791 
   2792     case Instruction::CHECK_CAST: {
   2793       uint8_t reference = instruction.VRegA_21c();
   2794       dex::TypeIndex type_index(instruction.VRegB_21c());
   2795       BuildTypeCheck(instruction, -1, reference, type_index, dex_pc);
   2796       break;
   2797     }
   2798 
   2799     case Instruction::MONITOR_ENTER: {
   2800       AppendInstruction(new (arena_) HMonitorOperation(
   2801           LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
   2802           HMonitorOperation::OperationKind::kEnter,
   2803           dex_pc));
   2804       break;
   2805     }
   2806 
   2807     case Instruction::MONITOR_EXIT: {
   2808       AppendInstruction(new (arena_) HMonitorOperation(
   2809           LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
   2810           HMonitorOperation::OperationKind::kExit,
   2811           dex_pc));
   2812       break;
   2813     }
   2814 
   2815     case Instruction::SPARSE_SWITCH:
   2816     case Instruction::PACKED_SWITCH: {
   2817       BuildSwitch(instruction, dex_pc);
   2818       break;
   2819     }
   2820 
   2821     default:
   2822       VLOG(compiler) << "Did not compile "
   2823                      << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
   2824                      << " because of unhandled instruction "
   2825                      << instruction.Name();
   2826       MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction);
   2827       return false;
   2828   }
   2829   return true;
   2830 }  // NOLINT(readability/fn_size)
   2831 
   2832 ObjPtr<mirror::Class> HInstructionBuilder::LookupResolvedType(
   2833     dex::TypeIndex type_index,
   2834     const DexCompilationUnit& compilation_unit) const {
   2835   return ClassLinker::LookupResolvedType(
   2836         type_index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get());
   2837 }
   2838 
   2839 ObjPtr<mirror::Class> HInstructionBuilder::LookupReferrerClass() const {
   2840   // TODO: Cache the result in a Handle<mirror::Class>.
   2841   const DexFile::MethodId& method_id =
   2842       dex_compilation_unit_->GetDexFile()->GetMethodId(dex_compilation_unit_->GetDexMethodIndex());
   2843   return LookupResolvedType(method_id.class_idx_, *dex_compilation_unit_);
   2844 }
   2845 
   2846 }  // namespace art
   2847