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