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