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