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