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