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