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