1/*
2 * Copyright (C) 2014 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 "builder.h"
18
19#include "art_field-inl.h"
20#include "base/logging.h"
21#include "class_linker.h"
22#include "dex/verified_method.h"
23#include "dex_file-inl.h"
24#include "dex_instruction-inl.h"
25#include "dex/verified_method.h"
26#include "driver/compiler_driver-inl.h"
27#include "driver/compiler_options.h"
28#include "mirror/class_loader.h"
29#include "mirror/dex_cache.h"
30#include "nodes.h"
31#include "primitive.h"
32#include "scoped_thread_state_change.h"
33#include "thread.h"
34
35namespace art {
36
37/**
38 * Helper class to add HTemporary instructions. This class is used when
39 * converting a DEX instruction to multiple HInstruction, and where those
40 * instructions do not die at the following instruction, but instead spans
41 * multiple instructions.
42 */
43class Temporaries : public ValueObject {
44 public:
45  explicit Temporaries(HGraph* graph) : graph_(graph), index_(0) {}
46
47  void Add(HInstruction* instruction) {
48    HInstruction* temp = new (graph_->GetArena()) HTemporary(index_);
49    instruction->GetBlock()->AddInstruction(temp);
50
51    DCHECK(temp->GetPrevious() == instruction);
52
53    size_t offset;
54    if (instruction->GetType() == Primitive::kPrimLong
55        || instruction->GetType() == Primitive::kPrimDouble) {
56      offset = 2;
57    } else {
58      offset = 1;
59    }
60    index_ += offset;
61
62    graph_->UpdateTemporariesVRegSlots(index_);
63  }
64
65 private:
66  HGraph* const graph_;
67
68  // Current index in the temporary stack, updated by `Add`.
69  size_t index_;
70};
71
72class SwitchTable : public ValueObject {
73 public:
74  SwitchTable(const Instruction& instruction, uint32_t dex_pc, bool sparse)
75      : instruction_(instruction), dex_pc_(dex_pc), sparse_(sparse) {
76    int32_t table_offset = instruction.VRegB_31t();
77    const uint16_t* table = reinterpret_cast<const uint16_t*>(&instruction) + table_offset;
78    if (sparse) {
79      CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
80    } else {
81      CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
82    }
83    num_entries_ = table[1];
84    values_ = reinterpret_cast<const int32_t*>(&table[2]);
85  }
86
87  uint16_t GetNumEntries() const {
88    return num_entries_;
89  }
90
91  void CheckIndex(size_t index) const {
92    if (sparse_) {
93      // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order.
94      DCHECK_LT(index, 2 * static_cast<size_t>(num_entries_));
95    } else {
96      // In a packed table, we have the starting key and num_entries_ values.
97      DCHECK_LT(index, 1 + static_cast<size_t>(num_entries_));
98    }
99  }
100
101  int32_t GetEntryAt(size_t index) const {
102    CheckIndex(index);
103    return values_[index];
104  }
105
106  uint32_t GetDexPcForIndex(size_t index) const {
107    CheckIndex(index);
108    return dex_pc_ +
109        (reinterpret_cast<const int16_t*>(values_ + index) -
110         reinterpret_cast<const int16_t*>(&instruction_));
111  }
112
113  // Index of the first value in the table.
114  size_t GetFirstValueIndex() const {
115    if (sparse_) {
116      // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order.
117      return num_entries_;
118    } else {
119      // In a packed table, we have the starting key and num_entries_ values.
120      return 1;
121    }
122  }
123
124 private:
125  const Instruction& instruction_;
126  const uint32_t dex_pc_;
127
128  // Whether this is a sparse-switch table (or a packed-switch one).
129  const bool sparse_;
130
131  // This can't be const as it needs to be computed off of the given instruction, and complicated
132  // expressions in the initializer list seemed very ugly.
133  uint16_t num_entries_;
134
135  const int32_t* values_;
136
137  DISALLOW_COPY_AND_ASSIGN(SwitchTable);
138};
139
140void HGraphBuilder::InitializeLocals(uint16_t count) {
141  graph_->SetNumberOfVRegs(count);
142  locals_.SetSize(count);
143  for (int i = 0; i < count; i++) {
144    HLocal* local = new (arena_) HLocal(i);
145    entry_block_->AddInstruction(local);
146    locals_.Put(i, local);
147  }
148}
149
150void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
151  // dex_compilation_unit_ is null only when unit testing.
152  if (dex_compilation_unit_ == nullptr) {
153    return;
154  }
155
156  graph_->SetNumberOfInVRegs(number_of_parameters);
157  const char* shorty = dex_compilation_unit_->GetShorty();
158  int locals_index = locals_.Size() - number_of_parameters;
159  int parameter_index = 0;
160
161  if (!dex_compilation_unit_->IsStatic()) {
162    // Add the implicit 'this' argument, not expressed in the signature.
163    HParameterValue* parameter =
164        new (arena_) HParameterValue(parameter_index++, Primitive::kPrimNot, true);
165    entry_block_->AddInstruction(parameter);
166    HLocal* local = GetLocalAt(locals_index++);
167    entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter));
168    number_of_parameters--;
169  }
170
171  uint32_t pos = 1;
172  for (int i = 0; i < number_of_parameters; i++) {
173    HParameterValue* parameter =
174        new (arena_) HParameterValue(parameter_index++, Primitive::GetType(shorty[pos++]));
175    entry_block_->AddInstruction(parameter);
176    HLocal* local = GetLocalAt(locals_index++);
177    // Store the parameter value in the local that the dex code will use
178    // to reference that parameter.
179    entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter));
180    bool is_wide = (parameter->GetType() == Primitive::kPrimLong)
181        || (parameter->GetType() == Primitive::kPrimDouble);
182    if (is_wide) {
183      i++;
184      locals_index++;
185      parameter_index++;
186    }
187  }
188}
189
190template<typename T>
191void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) {
192  int32_t target_offset = instruction.GetTargetOffset();
193  HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset);
194  HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
195  DCHECK(branch_target != nullptr);
196  DCHECK(fallthrough_target != nullptr);
197  PotentiallyAddSuspendCheck(branch_target, dex_pc);
198  HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
199  HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
200  T* comparison = new (arena_) T(first, second);
201  current_block_->AddInstruction(comparison);
202  HInstruction* ifinst = new (arena_) HIf(comparison);
203  current_block_->AddInstruction(ifinst);
204  current_block_->AddSuccessor(branch_target);
205  current_block_->AddSuccessor(fallthrough_target);
206  current_block_ = nullptr;
207}
208
209template<typename T>
210void HGraphBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) {
211  int32_t target_offset = instruction.GetTargetOffset();
212  HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset);
213  HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
214  DCHECK(branch_target != nullptr);
215  DCHECK(fallthrough_target != nullptr);
216  PotentiallyAddSuspendCheck(branch_target, dex_pc);
217  HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
218  T* comparison = new (arena_) T(value, graph_->GetIntConstant(0));
219  current_block_->AddInstruction(comparison);
220  HInstruction* ifinst = new (arena_) HIf(comparison);
221  current_block_->AddInstruction(ifinst);
222  current_block_->AddSuccessor(branch_target);
223  current_block_->AddSuccessor(fallthrough_target);
224  current_block_ = nullptr;
225}
226
227void HGraphBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) {
228  if (compilation_stats_ != nullptr) {
229    compilation_stats_->RecordStat(compilation_stat);
230  }
231}
232
233bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item,
234                                    size_t number_of_branches) {
235  const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
236  CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
237  if (compiler_filter == CompilerOptions::kEverything) {
238    return false;
239  }
240
241  if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) {
242    VLOG(compiler) << "Skip compilation of huge method "
243                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
244                   << ": " << code_item.insns_size_in_code_units_ << " code units";
245    MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod);
246    return true;
247  }
248
249  // If it's large and contains no branches, it's likely to be machine generated initialization.
250  if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_)
251      && (number_of_branches == 0)) {
252    VLOG(compiler) << "Skip compilation of large method with no branch "
253                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
254                   << ": " << code_item.insns_size_in_code_units_ << " code units";
255    MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
256    return true;
257  }
258
259  return false;
260}
261
262bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
263  DCHECK(graph_->GetBlocks().IsEmpty());
264
265  const uint16_t* code_ptr = code_item.insns_;
266  const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
267  code_start_ = code_ptr;
268
269  // Setup the graph with the entry block and exit block.
270  entry_block_ = new (arena_) HBasicBlock(graph_, 0);
271  graph_->AddBlock(entry_block_);
272  exit_block_ = new (arena_) HBasicBlock(graph_, kNoDexPc);
273  graph_->SetEntryBlock(entry_block_);
274  graph_->SetExitBlock(exit_block_);
275
276  InitializeLocals(code_item.registers_size_);
277  graph_->SetMaximumNumberOfOutVRegs(code_item.outs_size_);
278
279  // Compute the number of dex instructions, blocks, and branches. We will
280  // check these values against limits given to the compiler.
281  size_t number_of_branches = 0;
282
283  // To avoid splitting blocks, we compute ahead of time the instructions that
284  // start a new block, and create these blocks.
285  if (!ComputeBranchTargets(code_ptr, code_end, &number_of_branches)) {
286    MaybeRecordStat(MethodCompilationStat::kNotCompiledBranchOutsideMethodCode);
287    return false;
288  }
289
290  // Note that the compiler driver is null when unit testing.
291  if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) {
292    return false;
293  }
294
295  // Also create blocks for catch handlers.
296  if (code_item.tries_size_ != 0) {
297    const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0);
298    uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
299    for (uint32_t idx = 0; idx < handlers_size; ++idx) {
300      CatchHandlerIterator iterator(handlers_ptr);
301      for (; iterator.HasNext(); iterator.Next()) {
302        uint32_t address = iterator.GetHandlerAddress();
303        HBasicBlock* block = FindBlockStartingAt(address);
304        if (block == nullptr) {
305          block = new (arena_) HBasicBlock(graph_, address);
306          branch_targets_.Put(address, block);
307        }
308        block->SetIsCatchBlock();
309      }
310      handlers_ptr = iterator.EndDataPointer();
311    }
312  }
313
314  InitializeParameters(code_item.ins_size_);
315
316  size_t dex_pc = 0;
317  while (code_ptr < code_end) {
318    // Update the current block if dex_pc starts a new block.
319    MaybeUpdateCurrentBlock(dex_pc);
320    const Instruction& instruction = *Instruction::At(code_ptr);
321    if (!AnalyzeDexInstruction(instruction, dex_pc)) {
322      return false;
323    }
324    dex_pc += instruction.SizeInCodeUnits();
325    code_ptr += instruction.SizeInCodeUnits();
326  }
327
328  // Add the exit block at the end to give it the highest id.
329  graph_->AddBlock(exit_block_);
330  exit_block_->AddInstruction(new (arena_) HExit());
331  // Add the suspend check to the entry block.
332  entry_block_->AddInstruction(new (arena_) HSuspendCheck(0));
333  entry_block_->AddInstruction(new (arena_) HGoto());
334
335  return true;
336}
337
338void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
339  HBasicBlock* block = FindBlockStartingAt(index);
340  if (block == nullptr) {
341    return;
342  }
343
344  if (current_block_ != nullptr) {
345    // Branching instructions clear current_block, so we know
346    // the last instruction of the current block is not a branching
347    // instruction. We add an unconditional goto to the found block.
348    current_block_->AddInstruction(new (arena_) HGoto());
349    current_block_->AddSuccessor(block);
350  }
351  graph_->AddBlock(block);
352  current_block_ = block;
353}
354
355bool HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
356                                         const uint16_t* code_end,
357                                         size_t* number_of_branches) {
358  branch_targets_.SetSize(code_end - code_ptr);
359
360  // Create the first block for the dex instructions, single successor of the entry block.
361  HBasicBlock* block = new (arena_) HBasicBlock(graph_, 0);
362  branch_targets_.Put(0, block);
363  entry_block_->AddSuccessor(block);
364
365  // Iterate over all instructions and find branching instructions. Create blocks for
366  // the locations these instructions branch to.
367  uint32_t dex_pc = 0;
368  while (code_ptr < code_end) {
369    const Instruction& instruction = *Instruction::At(code_ptr);
370    if (instruction.IsBranch()) {
371      (*number_of_branches)++;
372      int32_t target = instruction.GetTargetOffset() + dex_pc;
373      // Create a block for the target instruction.
374      if (FindBlockStartingAt(target) == nullptr) {
375        block = new (arena_) HBasicBlock(graph_, target);
376        branch_targets_.Put(target, block);
377      }
378      dex_pc += instruction.SizeInCodeUnits();
379      code_ptr += instruction.SizeInCodeUnits();
380
381      if (code_ptr >= code_end) {
382        if (instruction.CanFlowThrough()) {
383          // In the normal case we should never hit this but someone can artificially forge a dex
384          // file to fall-through out the method code. In this case we bail out compilation.
385          return false;
386        }
387      } else if (FindBlockStartingAt(dex_pc) == nullptr) {
388        block = new (arena_) HBasicBlock(graph_, dex_pc);
389        branch_targets_.Put(dex_pc, block);
390      }
391    } else if (instruction.IsSwitch()) {
392      SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
393
394      uint16_t num_entries = table.GetNumEntries();
395
396      // In a packed-switch, the entry at index 0 is the starting key. In a sparse-switch, the
397      // entry at index 0 is the first key, and values are after *all* keys.
398      size_t offset = table.GetFirstValueIndex();
399
400      // Use a larger loop counter type to avoid overflow issues.
401      for (size_t i = 0; i < num_entries; ++i) {
402        // The target of the case.
403        uint32_t target = dex_pc + table.GetEntryAt(i + offset);
404        if (FindBlockStartingAt(target) == nullptr) {
405          block = new (arena_) HBasicBlock(graph_, target);
406          branch_targets_.Put(target, block);
407        }
408
409        // The next case gets its own block.
410        if (i < num_entries) {
411          block = new (arena_) HBasicBlock(graph_, target);
412          branch_targets_.Put(table.GetDexPcForIndex(i), block);
413        }
414      }
415
416      // Fall-through. Add a block if there is more code afterwards.
417      dex_pc += instruction.SizeInCodeUnits();
418      code_ptr += instruction.SizeInCodeUnits();
419      if (code_ptr >= code_end) {
420        // In the normal case we should never hit this but someone can artificially forge a dex
421        // file to fall-through out the method code. In this case we bail out compilation.
422        // (A switch can fall-through so we don't need to check CanFlowThrough().)
423        return false;
424      } else if (FindBlockStartingAt(dex_pc) == nullptr) {
425        block = new (arena_) HBasicBlock(graph_, dex_pc);
426        branch_targets_.Put(dex_pc, block);
427      }
428    } else {
429      code_ptr += instruction.SizeInCodeUnits();
430      dex_pc += instruction.SizeInCodeUnits();
431    }
432  }
433  return true;
434}
435
436HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t index) const {
437  DCHECK_GE(index, 0);
438  return branch_targets_.Get(index);
439}
440
441template<typename T>
442void HGraphBuilder::Unop_12x(const Instruction& instruction, Primitive::Type type) {
443  HInstruction* first = LoadLocal(instruction.VRegB(), type);
444  current_block_->AddInstruction(new (arena_) T(type, first));
445  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
446}
447
448void HGraphBuilder::Conversion_12x(const Instruction& instruction,
449                                   Primitive::Type input_type,
450                                   Primitive::Type result_type,
451                                   uint32_t dex_pc) {
452  HInstruction* first = LoadLocal(instruction.VRegB(), input_type);
453  current_block_->AddInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc));
454  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
455}
456
457template<typename T>
458void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type) {
459  HInstruction* first = LoadLocal(instruction.VRegB(), type);
460  HInstruction* second = LoadLocal(instruction.VRegC(), type);
461  current_block_->AddInstruction(new (arena_) T(type, first, second));
462  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
463}
464
465template<typename T>
466void HGraphBuilder::Binop_23x(const Instruction& instruction,
467                              Primitive::Type type,
468                              uint32_t dex_pc) {
469  HInstruction* first = LoadLocal(instruction.VRegB(), type);
470  HInstruction* second = LoadLocal(instruction.VRegC(), type);
471  current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc));
472  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
473}
474
475template<typename T>
476void HGraphBuilder::Binop_23x_shift(const Instruction& instruction,
477                                    Primitive::Type type) {
478  HInstruction* first = LoadLocal(instruction.VRegB(), type);
479  HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt);
480  current_block_->AddInstruction(new (arena_) T(type, first, second));
481  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
482}
483
484void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction,
485                                  Primitive::Type type,
486                                  HCompare::Bias bias,
487                                  uint32_t dex_pc) {
488  HInstruction* first = LoadLocal(instruction.VRegB(), type);
489  HInstruction* second = LoadLocal(instruction.VRegC(), type);
490  current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc));
491  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
492}
493
494template<typename T>
495void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) {
496  HInstruction* first = LoadLocal(instruction.VRegA(), type);
497  HInstruction* second = LoadLocal(instruction.VRegB(), type);
498  current_block_->AddInstruction(new (arena_) T(type, first, second));
499  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
500}
501
502template<typename T>
503void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type) {
504  HInstruction* first = LoadLocal(instruction.VRegA(), type);
505  HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
506  current_block_->AddInstruction(new (arena_) T(type, first, second));
507  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
508}
509
510template<typename T>
511void HGraphBuilder::Binop_12x(const Instruction& instruction,
512                              Primitive::Type type,
513                              uint32_t dex_pc) {
514  HInstruction* first = LoadLocal(instruction.VRegA(), type);
515  HInstruction* second = LoadLocal(instruction.VRegB(), type);
516  current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc));
517  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
518}
519
520template<typename T>
521void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse) {
522  HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
523  HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s());
524  if (reverse) {
525    std::swap(first, second);
526  }
527  current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second));
528  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
529}
530
531template<typename T>
532void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse) {
533  HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
534  HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b());
535  if (reverse) {
536    std::swap(first, second);
537  }
538  current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second));
539  UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
540}
541
542static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, const CompilerDriver& driver) {
543  // dex compilation unit is null only when unit testing.
544  if (cu == nullptr) {
545    return false;
546  }
547
548  Thread* self = Thread::Current();
549  return cu->IsConstructor()
550      && driver.RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex());
551}
552
553void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) {
554  if (type == Primitive::kPrimVoid) {
555    // Note that we might insert redundant barriers when inlining `super` calls.
556    // TODO: add a data flow analysis to get rid of duplicate barriers.
557    if (RequiresConstructorBarrier(dex_compilation_unit_, *compiler_driver_)) {
558      current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore));
559    }
560    current_block_->AddInstruction(new (arena_) HReturnVoid());
561  } else {
562    HInstruction* value = LoadLocal(instruction.VRegA(), type);
563    current_block_->AddInstruction(new (arena_) HReturn(value));
564  }
565  current_block_->AddSuccessor(exit_block_);
566  current_block_ = nullptr;
567}
568
569bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
570                                uint32_t dex_pc,
571                                uint32_t method_idx,
572                                uint32_t number_of_vreg_arguments,
573                                bool is_range,
574                                uint32_t* args,
575                                uint32_t register_index) {
576  Instruction::Code opcode = instruction.Opcode();
577  InvokeType invoke_type;
578  switch (opcode) {
579    case Instruction::INVOKE_STATIC:
580    case Instruction::INVOKE_STATIC_RANGE:
581      invoke_type = kStatic;
582      break;
583    case Instruction::INVOKE_DIRECT:
584    case Instruction::INVOKE_DIRECT_RANGE:
585      invoke_type = kDirect;
586      break;
587    case Instruction::INVOKE_VIRTUAL:
588    case Instruction::INVOKE_VIRTUAL_RANGE:
589      invoke_type = kVirtual;
590      break;
591    case Instruction::INVOKE_INTERFACE:
592    case Instruction::INVOKE_INTERFACE_RANGE:
593      invoke_type = kInterface;
594      break;
595    case Instruction::INVOKE_SUPER_RANGE:
596    case Instruction::INVOKE_SUPER:
597      invoke_type = kSuper;
598      break;
599    default:
600      LOG(FATAL) << "Unexpected invoke op: " << opcode;
601      return false;
602  }
603
604  const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
605  const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(method_id.proto_idx_);
606  const char* descriptor = dex_file_->StringDataByIdx(proto_id.shorty_idx_);
607  Primitive::Type return_type = Primitive::GetType(descriptor[0]);
608  bool is_instance_call = invoke_type != kStatic;
609  // Remove the return type from the 'proto'.
610  size_t number_of_arguments = strlen(descriptor) - 1;
611  if (is_instance_call) {
612    // One extra argument for 'this'.
613    ++number_of_arguments;
614  }
615
616  MethodReference target_method(dex_file_, method_idx);
617  uintptr_t direct_code;
618  uintptr_t direct_method;
619  int table_index;
620  InvokeType optimized_invoke_type = invoke_type;
621
622  if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, true, true,
623                                           &optimized_invoke_type, &target_method, &table_index,
624                                           &direct_code, &direct_method)) {
625    VLOG(compiler) << "Did not compile "
626                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
627                   << " because a method call could not be resolved";
628    MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod);
629    return false;
630  }
631  DCHECK(optimized_invoke_type != kSuper);
632
633  // By default, consider that the called method implicitly requires
634  // an initialization check of its declaring method.
635  HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement =
636      HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit;
637  // Potential class initialization check, in the case of a static method call.
638  HClinitCheck* clinit_check = nullptr;
639  // Replace calls to String.<init> with StringFactory.
640  int32_t string_init_offset = 0;
641  bool is_string_init = compiler_driver_->IsStringInit(method_idx, dex_file_, &string_init_offset);
642  if (is_string_init) {
643    return_type = Primitive::kPrimNot;
644    is_instance_call = false;
645    number_of_arguments--;
646    invoke_type = kStatic;
647    optimized_invoke_type = kStatic;
648  }
649
650  HInvoke* invoke = nullptr;
651
652  if (optimized_invoke_type == kVirtual) {
653    invoke = new (arena_) HInvokeVirtual(
654        arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index);
655  } else if (optimized_invoke_type == kInterface) {
656    invoke = new (arena_) HInvokeInterface(
657        arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index);
658  } else {
659    DCHECK(optimized_invoke_type == kDirect || optimized_invoke_type == kStatic);
660    // Sharpening to kDirect only works if we compile PIC.
661    DCHECK((optimized_invoke_type == invoke_type) || (optimized_invoke_type != kDirect)
662           || compiler_driver_->GetCompilerOptions().GetCompilePic());
663    bool is_recursive =
664        (target_method.dex_method_index == dex_compilation_unit_->GetDexMethodIndex());
665    DCHECK(!is_recursive || (target_method.dex_file == dex_compilation_unit_->GetDexFile()));
666
667    if (optimized_invoke_type == kStatic && !is_string_init) {
668      ScopedObjectAccess soa(Thread::Current());
669      StackHandleScope<4> hs(soa.Self());
670      Handle<mirror::DexCache> dex_cache(hs.NewHandle(
671          dex_compilation_unit_->GetClassLinker()->FindDexCache(
672              *dex_compilation_unit_->GetDexFile())));
673      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
674          soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
675      ArtMethod* resolved_method = compiler_driver_->ResolveMethod(
676          soa, dex_cache, class_loader, dex_compilation_unit_, method_idx, optimized_invoke_type);
677
678      if (resolved_method == nullptr) {
679        MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod);
680        return false;
681      }
682
683      const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
684      Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle(
685          outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file)));
686      Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
687
688      // The index at which the method's class is stored in the DexCache's type array.
689      uint32_t storage_index = DexFile::kDexNoIndex;
690      bool is_outer_class = (resolved_method->GetDeclaringClass() == outer_class.Get());
691      if (is_outer_class) {
692        storage_index = outer_class->GetDexTypeIndex();
693      } else if (outer_dex_cache.Get() == dex_cache.Get()) {
694        // Get `storage_index` from IsClassOfStaticMethodAvailableToReferrer.
695        compiler_driver_->IsClassOfStaticMethodAvailableToReferrer(outer_dex_cache.Get(),
696                                                                   GetCompilingClass(),
697                                                                   resolved_method,
698                                                                   method_idx,
699                                                                   &storage_index);
700      }
701
702      if (!outer_class->IsInterface()
703          && outer_class->IsSubClass(resolved_method->GetDeclaringClass())) {
704        // If the outer class is the declaring class or a subclass
705        // of the declaring class, no class initialization is needed
706        // before the static method call.
707        // Note that in case of inlining, we do not need to add clinit checks
708        // to calls that satisfy this subclass check with any inlined methods. This
709        // will be detected by the optimization passes.
710        clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone;
711      } else if (storage_index != DexFile::kDexNoIndex) {
712        // If the method's class type index is available, check
713        // whether we should add an explicit class initialization
714        // check for its declaring class before the static method call.
715
716        // TODO: find out why this check is needed.
717        bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache(
718            *outer_compilation_unit_->GetDexFile(), storage_index);
719        bool is_initialized =
720            resolved_method->GetDeclaringClass()->IsInitialized() && is_in_dex_cache;
721
722        if (is_initialized) {
723          clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone;
724        } else {
725          clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit;
726          HLoadClass* load_class =
727              new (arena_) HLoadClass(storage_index, is_outer_class, dex_pc);
728          current_block_->AddInstruction(load_class);
729          clinit_check = new (arena_) HClinitCheck(load_class, dex_pc);
730          current_block_->AddInstruction(clinit_check);
731        }
732      }
733    }
734
735    invoke = new (arena_) HInvokeStaticOrDirect(
736        arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index,
737        is_recursive, string_init_offset, invoke_type, optimized_invoke_type,
738        clinit_check_requirement);
739  }
740
741  size_t start_index = 0;
742  Temporaries temps(graph_);
743  if (is_instance_call) {
744    HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot);
745    HNullCheck* null_check = new (arena_) HNullCheck(arg, dex_pc);
746    current_block_->AddInstruction(null_check);
747    temps.Add(null_check);
748    invoke->SetArgumentAt(0, null_check);
749    start_index = 1;
750  }
751
752  uint32_t descriptor_index = 1;  // Skip the return type.
753  uint32_t argument_index = start_index;
754  if (is_string_init) {
755    start_index = 1;
756  }
757  for (size_t i = start_index;
758       // Make sure we don't go over the expected arguments or over the number of
759       // dex registers given. If the instruction was seen as dead by the verifier,
760       // it hasn't been properly checked.
761       (i < number_of_vreg_arguments) && (argument_index < number_of_arguments);
762       i++, argument_index++) {
763    Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]);
764    bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
765    if (!is_range
766        && is_wide
767        && ((i + 1 == number_of_vreg_arguments) || (args[i] + 1 != args[i + 1]))) {
768      // Longs and doubles should be in pairs, that is, sequential registers. The verifier should
769      // reject any class where this is violated. However, the verifier only does these checks
770      // on non trivially dead instructions, so we just bailout the compilation.
771      VLOG(compiler) << "Did not compile "
772                     << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
773                     << " because of non-sequential dex register pair in wide argument";
774      MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
775      return false;
776    }
777    HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type);
778    invoke->SetArgumentAt(argument_index, arg);
779    if (is_wide) {
780      i++;
781    }
782  }
783
784  if (argument_index != number_of_arguments) {
785    VLOG(compiler) << "Did not compile "
786                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
787                   << " because of wrong number of arguments in invoke instruction";
788    MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode);
789    return false;
790  }
791
792  if (clinit_check_requirement == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit) {
793    // Add the class initialization check as last input of `invoke`.
794    DCHECK(clinit_check != nullptr);
795    invoke->SetArgumentAt(argument_index, clinit_check);
796  }
797
798  current_block_->AddInstruction(invoke);
799  latest_result_ = invoke;
800
801  // Add move-result for StringFactory method.
802  if (is_string_init) {
803    uint32_t orig_this_reg = is_range ? register_index : args[0];
804    UpdateLocal(orig_this_reg, invoke);
805    const VerifiedMethod* verified_method =
806        compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex());
807    if (verified_method == nullptr) {
808      LOG(WARNING) << "No verified method for method calling String.<init>: "
809                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_);
810      return false;
811    }
812    const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map =
813        verified_method->GetStringInitPcRegMap();
814    auto map_it = string_init_map.find(dex_pc);
815    if (map_it != string_init_map.end()) {
816      std::set<uint32_t> reg_set = map_it->second;
817      for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
818        HInstruction* load_local = LoadLocal(orig_this_reg, Primitive::kPrimNot);
819        UpdateLocal(*set_it, load_local);
820      }
821    }
822  }
823  return true;
824}
825
826bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
827                                             uint32_t dex_pc,
828                                             bool is_put) {
829  uint32_t source_or_dest_reg = instruction.VRegA_22c();
830  uint32_t obj_reg = instruction.VRegB_22c();
831  uint16_t field_index = instruction.VRegC_22c();
832
833  ScopedObjectAccess soa(Thread::Current());
834  ArtField* resolved_field =
835      compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa);
836
837  if (resolved_field == nullptr) {
838    MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
839    return false;
840  }
841
842  Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
843
844  HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot);
845  current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc));
846  if (is_put) {
847    Temporaries temps(graph_);
848    HInstruction* null_check = current_block_->GetLastInstruction();
849    // We need one temporary for the null check.
850    temps.Add(null_check);
851    HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
852    current_block_->AddInstruction(new (arena_) HInstanceFieldSet(
853        null_check,
854        value,
855        field_type,
856        resolved_field->GetOffset(),
857        resolved_field->IsVolatile()));
858  } else {
859    current_block_->AddInstruction(new (arena_) HInstanceFieldGet(
860        current_block_->GetLastInstruction(),
861        field_type,
862        resolved_field->GetOffset(),
863        resolved_field->IsVolatile()));
864
865    UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
866  }
867  return true;
868}
869
870static mirror::Class* GetClassFrom(CompilerDriver* driver,
871                                   const DexCompilationUnit& compilation_unit) {
872  ScopedObjectAccess soa(Thread::Current());
873  StackHandleScope<2> hs(soa.Self());
874  const DexFile& dex_file = *compilation_unit.GetDexFile();
875  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
876      soa.Decode<mirror::ClassLoader*>(compilation_unit.GetClassLoader())));
877  Handle<mirror::DexCache> dex_cache(hs.NewHandle(
878      compilation_unit.GetClassLinker()->FindDexCache(dex_file)));
879
880  return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit);
881}
882
883mirror::Class* HGraphBuilder::GetOutermostCompilingClass() const {
884  return GetClassFrom(compiler_driver_, *outer_compilation_unit_);
885}
886
887mirror::Class* HGraphBuilder::GetCompilingClass() const {
888  return GetClassFrom(compiler_driver_, *dex_compilation_unit_);
889}
890
891bool HGraphBuilder::IsOutermostCompilingClass(uint16_t type_index) const {
892  ScopedObjectAccess soa(Thread::Current());
893  StackHandleScope<4> hs(soa.Self());
894  Handle<mirror::DexCache> dex_cache(hs.NewHandle(
895      dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile())));
896  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
897      soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
898  Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass(
899      soa, dex_cache, class_loader, type_index, dex_compilation_unit_)));
900  Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
901
902  return outer_class.Get() == cls.Get();
903}
904
905bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
906                                           uint32_t dex_pc,
907                                           bool is_put) {
908  uint32_t source_or_dest_reg = instruction.VRegA_21c();
909  uint16_t field_index = instruction.VRegB_21c();
910
911  ScopedObjectAccess soa(Thread::Current());
912  StackHandleScope<4> hs(soa.Self());
913  Handle<mirror::DexCache> dex_cache(hs.NewHandle(
914      dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile())));
915  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
916      soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
917  ArtField* resolved_field = compiler_driver_->ResolveField(
918      soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true);
919
920  if (resolved_field == nullptr) {
921    MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
922    return false;
923  }
924
925  const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();
926  Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle(
927      outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file)));
928  Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass()));
929
930  // The index at which the field's class is stored in the DexCache's type array.
931  uint32_t storage_index;
932  bool is_outer_class = (outer_class.Get() == resolved_field->GetDeclaringClass());
933  if (is_outer_class) {
934    storage_index = outer_class->GetDexTypeIndex();
935  } else if (outer_dex_cache.Get() != dex_cache.Get()) {
936    // The compiler driver cannot currently understand multiple dex caches involved. Just bailout.
937    return false;
938  } else {
939    std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField(
940        outer_dex_cache.Get(),
941        GetCompilingClass(),
942        resolved_field,
943        field_index,
944        &storage_index);
945    bool can_easily_access = is_put ? pair.second : pair.first;
946    if (!can_easily_access) {
947      return false;
948    }
949  }
950
951  // TODO: find out why this check is needed.
952  bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache(
953      *outer_compilation_unit_->GetDexFile(), storage_index);
954  bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache;
955
956  HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_outer_class, dex_pc);
957  current_block_->AddInstruction(constant);
958
959  HInstruction* cls = constant;
960  if (!is_initialized && !is_outer_class) {
961    cls = new (arena_) HClinitCheck(constant, dex_pc);
962    current_block_->AddInstruction(cls);
963  }
964
965  Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
966  if (is_put) {
967    // We need to keep the class alive before loading the value.
968    Temporaries temps(graph_);
969    temps.Add(cls);
970    HInstruction* value = LoadLocal(source_or_dest_reg, field_type);
971    DCHECK_EQ(value->GetType(), field_type);
972    current_block_->AddInstruction(
973        new (arena_) HStaticFieldSet(cls, value, field_type, resolved_field->GetOffset(),
974            resolved_field->IsVolatile()));
975  } else {
976    current_block_->AddInstruction(
977        new (arena_) HStaticFieldGet(cls, field_type, resolved_field->GetOffset(),
978            resolved_field->IsVolatile()));
979    UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
980  }
981  return true;
982}
983
984void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg,
985                                       uint16_t first_vreg,
986                                       int64_t second_vreg_or_constant,
987                                       uint32_t dex_pc,
988                                       Primitive::Type type,
989                                       bool second_is_constant,
990                                       bool isDiv) {
991  DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong);
992
993  HInstruction* first = LoadLocal(first_vreg, type);
994  HInstruction* second = nullptr;
995  if (second_is_constant) {
996    if (type == Primitive::kPrimInt) {
997      second = graph_->GetIntConstant(second_vreg_or_constant);
998    } else {
999      second = graph_->GetLongConstant(second_vreg_or_constant);
1000    }
1001  } else {
1002    second = LoadLocal(second_vreg_or_constant, type);
1003  }
1004
1005  if (!second_is_constant
1006      || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0)
1007      || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) {
1008    second = new (arena_) HDivZeroCheck(second, dex_pc);
1009    Temporaries temps(graph_);
1010    current_block_->AddInstruction(second);
1011    temps.Add(current_block_->GetLastInstruction());
1012  }
1013
1014  if (isDiv) {
1015    current_block_->AddInstruction(new (arena_) HDiv(type, first, second, dex_pc));
1016  } else {
1017    current_block_->AddInstruction(new (arena_) HRem(type, first, second, dex_pc));
1018  }
1019  UpdateLocal(out_vreg, current_block_->GetLastInstruction());
1020}
1021
1022void HGraphBuilder::BuildArrayAccess(const Instruction& instruction,
1023                                     uint32_t dex_pc,
1024                                     bool is_put,
1025                                     Primitive::Type anticipated_type) {
1026  uint8_t source_or_dest_reg = instruction.VRegA_23x();
1027  uint8_t array_reg = instruction.VRegB_23x();
1028  uint8_t index_reg = instruction.VRegC_23x();
1029
1030  // We need one temporary for the null check, one for the index, and one for the length.
1031  Temporaries temps(graph_);
1032
1033  HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot);
1034  object = new (arena_) HNullCheck(object, dex_pc);
1035  current_block_->AddInstruction(object);
1036  temps.Add(object);
1037
1038  HInstruction* length = new (arena_) HArrayLength(object);
1039  current_block_->AddInstruction(length);
1040  temps.Add(length);
1041  HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt);
1042  index = new (arena_) HBoundsCheck(index, length, dex_pc);
1043  current_block_->AddInstruction(index);
1044  temps.Add(index);
1045  if (is_put) {
1046    HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type);
1047    // TODO: Insert a type check node if the type is Object.
1048    current_block_->AddInstruction(new (arena_) HArraySet(
1049        object, index, value, anticipated_type, dex_pc));
1050  } else {
1051    current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type));
1052    UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
1053  }
1054  graph_->SetHasBoundsChecks(true);
1055}
1056
1057void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc,
1058                                        uint32_t type_index,
1059                                        uint32_t number_of_vreg_arguments,
1060                                        bool is_range,
1061                                        uint32_t* args,
1062                                        uint32_t register_index) {
1063  HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments);
1064  QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
1065      ? kQuickAllocArrayWithAccessCheck
1066      : kQuickAllocArray;
1067  HInstruction* object = new (arena_) HNewArray(length, dex_pc, type_index, entrypoint);
1068  current_block_->AddInstruction(object);
1069
1070  const char* descriptor = dex_file_->StringByTypeIdx(type_index);
1071  DCHECK_EQ(descriptor[0], '[') << descriptor;
1072  char primitive = descriptor[1];
1073  DCHECK(primitive == 'I'
1074      || primitive == 'L'
1075      || primitive == '[') << descriptor;
1076  bool is_reference_array = (primitive == 'L') || (primitive == '[');
1077  Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt;
1078
1079  Temporaries temps(graph_);
1080  temps.Add(object);
1081  for (size_t i = 0; i < number_of_vreg_arguments; ++i) {
1082    HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type);
1083    HInstruction* index = graph_->GetIntConstant(i);
1084    current_block_->AddInstruction(
1085        new (arena_) HArraySet(object, index, value, type, dex_pc));
1086  }
1087  latest_result_ = object;
1088}
1089
1090template <typename T>
1091void HGraphBuilder::BuildFillArrayData(HInstruction* object,
1092                                       const T* data,
1093                                       uint32_t element_count,
1094                                       Primitive::Type anticipated_type,
1095                                       uint32_t dex_pc) {
1096  for (uint32_t i = 0; i < element_count; ++i) {
1097    HInstruction* index = graph_->GetIntConstant(i);
1098    HInstruction* value = graph_->GetIntConstant(data[i]);
1099    current_block_->AddInstruction(new (arena_) HArraySet(
1100      object, index, value, anticipated_type, dex_pc));
1101  }
1102}
1103
1104void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) {
1105  Temporaries temps(graph_);
1106  HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot);
1107  HNullCheck* null_check = new (arena_) HNullCheck(array, dex_pc);
1108  current_block_->AddInstruction(null_check);
1109  temps.Add(null_check);
1110
1111  HInstruction* length = new (arena_) HArrayLength(null_check);
1112  current_block_->AddInstruction(length);
1113
1114  int32_t payload_offset = instruction.VRegB_31t() + dex_pc;
1115  const Instruction::ArrayDataPayload* payload =
1116      reinterpret_cast<const Instruction::ArrayDataPayload*>(code_start_ + payload_offset);
1117  const uint8_t* data = payload->data;
1118  uint32_t element_count = payload->element_count;
1119
1120  // Implementation of this DEX instruction seems to be that the bounds check is
1121  // done before doing any stores.
1122  HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1);
1123  current_block_->AddInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc));
1124
1125  switch (payload->element_width) {
1126    case 1:
1127      BuildFillArrayData(null_check,
1128                         reinterpret_cast<const int8_t*>(data),
1129                         element_count,
1130                         Primitive::kPrimByte,
1131                         dex_pc);
1132      break;
1133    case 2:
1134      BuildFillArrayData(null_check,
1135                         reinterpret_cast<const int16_t*>(data),
1136                         element_count,
1137                         Primitive::kPrimShort,
1138                         dex_pc);
1139      break;
1140    case 4:
1141      BuildFillArrayData(null_check,
1142                         reinterpret_cast<const int32_t*>(data),
1143                         element_count,
1144                         Primitive::kPrimInt,
1145                         dex_pc);
1146      break;
1147    case 8:
1148      BuildFillWideArrayData(null_check,
1149                             reinterpret_cast<const int64_t*>(data),
1150                             element_count,
1151                             dex_pc);
1152      break;
1153    default:
1154      LOG(FATAL) << "Unknown element width for " << payload->element_width;
1155  }
1156  graph_->SetHasBoundsChecks(true);
1157}
1158
1159void HGraphBuilder::BuildFillWideArrayData(HInstruction* object,
1160                                           const int64_t* data,
1161                                           uint32_t element_count,
1162                                           uint32_t dex_pc) {
1163  for (uint32_t i = 0; i < element_count; ++i) {
1164    HInstruction* index = graph_->GetIntConstant(i);
1165    HInstruction* value = graph_->GetLongConstant(data[i]);
1166    current_block_->AddInstruction(new (arena_) HArraySet(
1167      object, index, value, Primitive::kPrimLong, dex_pc));
1168  }
1169}
1170
1171bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
1172                                   uint8_t destination,
1173                                   uint8_t reference,
1174                                   uint16_t type_index,
1175                                   uint32_t dex_pc) {
1176  bool type_known_final;
1177  bool type_known_abstract;
1178  // `CanAccessTypeWithoutChecks` will tell whether the method being
1179  // built is trying to access its own class, so that the generated
1180  // code can optimize for this case. However, the optimization does not
1181  // work for inlining, so we use `IsOutermostCompilingClass` instead.
1182  bool dont_use_is_referrers_class;
1183  bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
1184      dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
1185      &type_known_final, &type_known_abstract, &dont_use_is_referrers_class);
1186  if (!can_access) {
1187    MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
1188    return false;
1189  }
1190  HInstruction* object = LoadLocal(reference, Primitive::kPrimNot);
1191  HLoadClass* cls = new (arena_) HLoadClass(
1192      type_index, IsOutermostCompilingClass(type_index), dex_pc);
1193  current_block_->AddInstruction(cls);
1194  // The class needs a temporary before being used by the type check.
1195  Temporaries temps(graph_);
1196  temps.Add(cls);
1197  if (instruction.Opcode() == Instruction::INSTANCE_OF) {
1198    current_block_->AddInstruction(
1199        new (arena_) HInstanceOf(object, cls, type_known_final, dex_pc));
1200    UpdateLocal(destination, current_block_->GetLastInstruction());
1201  } else {
1202    DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST);
1203    current_block_->AddInstruction(
1204        new (arena_) HCheckCast(object, cls, type_known_final, dex_pc));
1205  }
1206  return true;
1207}
1208
1209bool HGraphBuilder::NeedsAccessCheck(uint32_t type_index) const {
1210  return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks(
1211      dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index);
1212}
1213
1214void HGraphBuilder::BuildPackedSwitch(const Instruction& instruction, uint32_t dex_pc) {
1215  // Verifier guarantees that the payload for PackedSwitch contains:
1216  //   (a) number of entries (may be zero)
1217  //   (b) first and lowest switch case value (entry 0, always present)
1218  //   (c) list of target pcs (entries 1 <= i <= N)
1219  SwitchTable table(instruction, dex_pc, false);
1220
1221  // Value to test against.
1222  HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
1223
1224  // Retrieve number of entries.
1225  uint16_t num_entries = table.GetNumEntries();
1226  if (num_entries == 0) {
1227    return;
1228  }
1229
1230  // Chained cmp-and-branch, starting from starting_key.
1231  int32_t starting_key = table.GetEntryAt(0);
1232
1233  for (size_t i = 1; i <= num_entries; i++) {
1234    BuildSwitchCaseHelper(instruction, i, i == num_entries, table, value, starting_key + i - 1,
1235                          table.GetEntryAt(i), dex_pc);
1236  }
1237}
1238
1239void HGraphBuilder::BuildSparseSwitch(const Instruction& instruction, uint32_t dex_pc) {
1240  // Verifier guarantees that the payload for SparseSwitch contains:
1241  //   (a) number of entries (may be zero)
1242  //   (b) sorted key values (entries 0 <= i < N)
1243  //   (c) target pcs corresponding to the switch values (entries N <= i < 2*N)
1244  SwitchTable table(instruction, dex_pc, true);
1245
1246  // Value to test against.
1247  HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt);
1248
1249  uint16_t num_entries = table.GetNumEntries();
1250
1251  for (size_t i = 0; i < num_entries; i++) {
1252    BuildSwitchCaseHelper(instruction, i, i == static_cast<size_t>(num_entries) - 1, table, value,
1253                          table.GetEntryAt(i), table.GetEntryAt(i + num_entries), dex_pc);
1254  }
1255}
1256
1257void HGraphBuilder::BuildSwitchCaseHelper(const Instruction& instruction, size_t index,
1258                                          bool is_last_case, const SwitchTable& table,
1259                                          HInstruction* value, int32_t case_value_int,
1260                                          int32_t target_offset, uint32_t dex_pc) {
1261  HBasicBlock* case_target = FindBlockStartingAt(dex_pc + target_offset);
1262  DCHECK(case_target != nullptr);
1263  PotentiallyAddSuspendCheck(case_target, dex_pc);
1264
1265  // The current case's value.
1266  HInstruction* this_case_value = graph_->GetIntConstant(case_value_int);
1267
1268  // Compare value and this_case_value.
1269  HEqual* comparison = new (arena_) HEqual(value, this_case_value);
1270  current_block_->AddInstruction(comparison);
1271  HInstruction* ifinst = new (arena_) HIf(comparison);
1272  current_block_->AddInstruction(ifinst);
1273
1274  // Case hit: use the target offset to determine where to go.
1275  current_block_->AddSuccessor(case_target);
1276
1277  // Case miss: go to the next case (or default fall-through).
1278  // When there is a next case, we use the block stored with the table offset representing this
1279  // case (that is where we registered them in ComputeBranchTargets).
1280  // When there is no next case, we use the following instruction.
1281  // TODO: Find a good way to peel the last iteration to avoid conditional, but still have re-use.
1282  if (!is_last_case) {
1283    HBasicBlock* next_case_target = FindBlockStartingAt(table.GetDexPcForIndex(index));
1284    DCHECK(next_case_target != nullptr);
1285    current_block_->AddSuccessor(next_case_target);
1286
1287    // Need to manually add the block, as there is no dex-pc transition for the cases.
1288    graph_->AddBlock(next_case_target);
1289
1290    current_block_ = next_case_target;
1291  } else {
1292    HBasicBlock* default_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits());
1293    DCHECK(default_target != nullptr);
1294    current_block_->AddSuccessor(default_target);
1295    current_block_ = nullptr;
1296  }
1297}
1298
1299void HGraphBuilder::PotentiallyAddSuspendCheck(HBasicBlock* target, uint32_t dex_pc) {
1300  int32_t target_offset = target->GetDexPc() - dex_pc;
1301  if (target_offset <= 0) {
1302    // DX generates back edges to the first encountered return. We can save
1303    // time of later passes by not adding redundant suspend checks.
1304    HInstruction* last_in_target = target->GetLastInstruction();
1305    if (last_in_target != nullptr &&
1306        (last_in_target->IsReturn() || last_in_target->IsReturnVoid())) {
1307      return;
1308    }
1309
1310    // Add a suspend check to backward branches which may potentially loop. We
1311    // can remove them after we recognize loops in the graph.
1312    current_block_->AddInstruction(new (arena_) HSuspendCheck(dex_pc));
1313  }
1314}
1315
1316bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc) {
1317  if (current_block_ == nullptr) {
1318    return true;  // Dead code
1319  }
1320
1321  switch (instruction.Opcode()) {
1322    case Instruction::CONST_4: {
1323      int32_t register_index = instruction.VRegA();
1324      HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n());
1325      UpdateLocal(register_index, constant);
1326      break;
1327    }
1328
1329    case Instruction::CONST_16: {
1330      int32_t register_index = instruction.VRegA();
1331      HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s());
1332      UpdateLocal(register_index, constant);
1333      break;
1334    }
1335
1336    case Instruction::CONST: {
1337      int32_t register_index = instruction.VRegA();
1338      HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i());
1339      UpdateLocal(register_index, constant);
1340      break;
1341    }
1342
1343    case Instruction::CONST_HIGH16: {
1344      int32_t register_index = instruction.VRegA();
1345      HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16);
1346      UpdateLocal(register_index, constant);
1347      break;
1348    }
1349
1350    case Instruction::CONST_WIDE_16: {
1351      int32_t register_index = instruction.VRegA();
1352      // Get 16 bits of constant value, sign extended to 64 bits.
1353      int64_t value = instruction.VRegB_21s();
1354      value <<= 48;
1355      value >>= 48;
1356      HLongConstant* constant = graph_->GetLongConstant(value);
1357      UpdateLocal(register_index, constant);
1358      break;
1359    }
1360
1361    case Instruction::CONST_WIDE_32: {
1362      int32_t register_index = instruction.VRegA();
1363      // Get 32 bits of constant value, sign extended to 64 bits.
1364      int64_t value = instruction.VRegB_31i();
1365      value <<= 32;
1366      value >>= 32;
1367      HLongConstant* constant = graph_->GetLongConstant(value);
1368      UpdateLocal(register_index, constant);
1369      break;
1370    }
1371
1372    case Instruction::CONST_WIDE: {
1373      int32_t register_index = instruction.VRegA();
1374      HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l());
1375      UpdateLocal(register_index, constant);
1376      break;
1377    }
1378
1379    case Instruction::CONST_WIDE_HIGH16: {
1380      int32_t register_index = instruction.VRegA();
1381      int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48;
1382      HLongConstant* constant = graph_->GetLongConstant(value);
1383      UpdateLocal(register_index, constant);
1384      break;
1385    }
1386
1387    // Note that the SSA building will refine the types.
1388    case Instruction::MOVE:
1389    case Instruction::MOVE_FROM16:
1390    case Instruction::MOVE_16: {
1391      HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt);
1392      UpdateLocal(instruction.VRegA(), value);
1393      break;
1394    }
1395
1396    // Note that the SSA building will refine the types.
1397    case Instruction::MOVE_WIDE:
1398    case Instruction::MOVE_WIDE_FROM16:
1399    case Instruction::MOVE_WIDE_16: {
1400      HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong);
1401      UpdateLocal(instruction.VRegA(), value);
1402      break;
1403    }
1404
1405    case Instruction::MOVE_OBJECT:
1406    case Instruction::MOVE_OBJECT_16:
1407    case Instruction::MOVE_OBJECT_FROM16: {
1408      HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot);
1409      UpdateLocal(instruction.VRegA(), value);
1410      break;
1411    }
1412
1413    case Instruction::RETURN_VOID: {
1414      BuildReturn(instruction, Primitive::kPrimVoid);
1415      break;
1416    }
1417
1418#define IF_XX(comparison, cond) \
1419    case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \
1420    case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break
1421
1422    IF_XX(HEqual, EQ);
1423    IF_XX(HNotEqual, NE);
1424    IF_XX(HLessThan, LT);
1425    IF_XX(HLessThanOrEqual, LE);
1426    IF_XX(HGreaterThan, GT);
1427    IF_XX(HGreaterThanOrEqual, GE);
1428
1429    case Instruction::GOTO:
1430    case Instruction::GOTO_16:
1431    case Instruction::GOTO_32: {
1432      int32_t offset = instruction.GetTargetOffset();
1433      HBasicBlock* target = FindBlockStartingAt(offset + dex_pc);
1434      DCHECK(target != nullptr);
1435      PotentiallyAddSuspendCheck(target, dex_pc);
1436      current_block_->AddInstruction(new (arena_) HGoto());
1437      current_block_->AddSuccessor(target);
1438      current_block_ = nullptr;
1439      break;
1440    }
1441
1442    case Instruction::RETURN: {
1443      BuildReturn(instruction, return_type_);
1444      break;
1445    }
1446
1447    case Instruction::RETURN_OBJECT: {
1448      BuildReturn(instruction, return_type_);
1449      break;
1450    }
1451
1452    case Instruction::RETURN_WIDE: {
1453      BuildReturn(instruction, return_type_);
1454      break;
1455    }
1456
1457    case Instruction::INVOKE_DIRECT:
1458    case Instruction::INVOKE_INTERFACE:
1459    case Instruction::INVOKE_STATIC:
1460    case Instruction::INVOKE_SUPER:
1461    case Instruction::INVOKE_VIRTUAL: {
1462      uint32_t method_idx = instruction.VRegB_35c();
1463      uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
1464      uint32_t args[5];
1465      instruction.GetVarArgs(args);
1466      if (!BuildInvoke(instruction, dex_pc, method_idx,
1467                       number_of_vreg_arguments, false, args, -1)) {
1468        return false;
1469      }
1470      break;
1471    }
1472
1473    case Instruction::INVOKE_DIRECT_RANGE:
1474    case Instruction::INVOKE_INTERFACE_RANGE:
1475    case Instruction::INVOKE_STATIC_RANGE:
1476    case Instruction::INVOKE_SUPER_RANGE:
1477    case Instruction::INVOKE_VIRTUAL_RANGE: {
1478      uint32_t method_idx = instruction.VRegB_3rc();
1479      uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
1480      uint32_t register_index = instruction.VRegC();
1481      if (!BuildInvoke(instruction, dex_pc, method_idx,
1482                       number_of_vreg_arguments, true, nullptr, register_index)) {
1483        return false;
1484      }
1485      break;
1486    }
1487
1488    case Instruction::NEG_INT: {
1489      Unop_12x<HNeg>(instruction, Primitive::kPrimInt);
1490      break;
1491    }
1492
1493    case Instruction::NEG_LONG: {
1494      Unop_12x<HNeg>(instruction, Primitive::kPrimLong);
1495      break;
1496    }
1497
1498    case Instruction::NEG_FLOAT: {
1499      Unop_12x<HNeg>(instruction, Primitive::kPrimFloat);
1500      break;
1501    }
1502
1503    case Instruction::NEG_DOUBLE: {
1504      Unop_12x<HNeg>(instruction, Primitive::kPrimDouble);
1505      break;
1506    }
1507
1508    case Instruction::NOT_INT: {
1509      Unop_12x<HNot>(instruction, Primitive::kPrimInt);
1510      break;
1511    }
1512
1513    case Instruction::NOT_LONG: {
1514      Unop_12x<HNot>(instruction, Primitive::kPrimLong);
1515      break;
1516    }
1517
1518    case Instruction::INT_TO_LONG: {
1519      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc);
1520      break;
1521    }
1522
1523    case Instruction::INT_TO_FLOAT: {
1524      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc);
1525      break;
1526    }
1527
1528    case Instruction::INT_TO_DOUBLE: {
1529      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc);
1530      break;
1531    }
1532
1533    case Instruction::LONG_TO_INT: {
1534      Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc);
1535      break;
1536    }
1537
1538    case Instruction::LONG_TO_FLOAT: {
1539      Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc);
1540      break;
1541    }
1542
1543    case Instruction::LONG_TO_DOUBLE: {
1544      Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc);
1545      break;
1546    }
1547
1548    case Instruction::FLOAT_TO_INT: {
1549      Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc);
1550      break;
1551    }
1552
1553    case Instruction::FLOAT_TO_LONG: {
1554      Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc);
1555      break;
1556    }
1557
1558    case Instruction::FLOAT_TO_DOUBLE: {
1559      Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc);
1560      break;
1561    }
1562
1563    case Instruction::DOUBLE_TO_INT: {
1564      Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc);
1565      break;
1566    }
1567
1568    case Instruction::DOUBLE_TO_LONG: {
1569      Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc);
1570      break;
1571    }
1572
1573    case Instruction::DOUBLE_TO_FLOAT: {
1574      Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc);
1575      break;
1576    }
1577
1578    case Instruction::INT_TO_BYTE: {
1579      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc);
1580      break;
1581    }
1582
1583    case Instruction::INT_TO_SHORT: {
1584      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc);
1585      break;
1586    }
1587
1588    case Instruction::INT_TO_CHAR: {
1589      Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc);
1590      break;
1591    }
1592
1593    case Instruction::ADD_INT: {
1594      Binop_23x<HAdd>(instruction, Primitive::kPrimInt);
1595      break;
1596    }
1597
1598    case Instruction::ADD_LONG: {
1599      Binop_23x<HAdd>(instruction, Primitive::kPrimLong);
1600      break;
1601    }
1602
1603    case Instruction::ADD_DOUBLE: {
1604      Binop_23x<HAdd>(instruction, Primitive::kPrimDouble);
1605      break;
1606    }
1607
1608    case Instruction::ADD_FLOAT: {
1609      Binop_23x<HAdd>(instruction, Primitive::kPrimFloat);
1610      break;
1611    }
1612
1613    case Instruction::SUB_INT: {
1614      Binop_23x<HSub>(instruction, Primitive::kPrimInt);
1615      break;
1616    }
1617
1618    case Instruction::SUB_LONG: {
1619      Binop_23x<HSub>(instruction, Primitive::kPrimLong);
1620      break;
1621    }
1622
1623    case Instruction::SUB_FLOAT: {
1624      Binop_23x<HSub>(instruction, Primitive::kPrimFloat);
1625      break;
1626    }
1627
1628    case Instruction::SUB_DOUBLE: {
1629      Binop_23x<HSub>(instruction, Primitive::kPrimDouble);
1630      break;
1631    }
1632
1633    case Instruction::ADD_INT_2ADDR: {
1634      Binop_12x<HAdd>(instruction, Primitive::kPrimInt);
1635      break;
1636    }
1637
1638    case Instruction::MUL_INT: {
1639      Binop_23x<HMul>(instruction, Primitive::kPrimInt);
1640      break;
1641    }
1642
1643    case Instruction::MUL_LONG: {
1644      Binop_23x<HMul>(instruction, Primitive::kPrimLong);
1645      break;
1646    }
1647
1648    case Instruction::MUL_FLOAT: {
1649      Binop_23x<HMul>(instruction, Primitive::kPrimFloat);
1650      break;
1651    }
1652
1653    case Instruction::MUL_DOUBLE: {
1654      Binop_23x<HMul>(instruction, Primitive::kPrimDouble);
1655      break;
1656    }
1657
1658    case Instruction::DIV_INT: {
1659      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1660                         dex_pc, Primitive::kPrimInt, false, true);
1661      break;
1662    }
1663
1664    case Instruction::DIV_LONG: {
1665      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1666                         dex_pc, Primitive::kPrimLong, false, true);
1667      break;
1668    }
1669
1670    case Instruction::DIV_FLOAT: {
1671      Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
1672      break;
1673    }
1674
1675    case Instruction::DIV_DOUBLE: {
1676      Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
1677      break;
1678    }
1679
1680    case Instruction::REM_INT: {
1681      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1682                         dex_pc, Primitive::kPrimInt, false, false);
1683      break;
1684    }
1685
1686    case Instruction::REM_LONG: {
1687      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1688                         dex_pc, Primitive::kPrimLong, false, false);
1689      break;
1690    }
1691
1692    case Instruction::REM_FLOAT: {
1693      Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
1694      break;
1695    }
1696
1697    case Instruction::REM_DOUBLE: {
1698      Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
1699      break;
1700    }
1701
1702    case Instruction::AND_INT: {
1703      Binop_23x<HAnd>(instruction, Primitive::kPrimInt);
1704      break;
1705    }
1706
1707    case Instruction::AND_LONG: {
1708      Binop_23x<HAnd>(instruction, Primitive::kPrimLong);
1709      break;
1710    }
1711
1712    case Instruction::SHL_INT: {
1713      Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt);
1714      break;
1715    }
1716
1717    case Instruction::SHL_LONG: {
1718      Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong);
1719      break;
1720    }
1721
1722    case Instruction::SHR_INT: {
1723      Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt);
1724      break;
1725    }
1726
1727    case Instruction::SHR_LONG: {
1728      Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong);
1729      break;
1730    }
1731
1732    case Instruction::USHR_INT: {
1733      Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt);
1734      break;
1735    }
1736
1737    case Instruction::USHR_LONG: {
1738      Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong);
1739      break;
1740    }
1741
1742    case Instruction::OR_INT: {
1743      Binop_23x<HOr>(instruction, Primitive::kPrimInt);
1744      break;
1745    }
1746
1747    case Instruction::OR_LONG: {
1748      Binop_23x<HOr>(instruction, Primitive::kPrimLong);
1749      break;
1750    }
1751
1752    case Instruction::XOR_INT: {
1753      Binop_23x<HXor>(instruction, Primitive::kPrimInt);
1754      break;
1755    }
1756
1757    case Instruction::XOR_LONG: {
1758      Binop_23x<HXor>(instruction, Primitive::kPrimLong);
1759      break;
1760    }
1761
1762    case Instruction::ADD_LONG_2ADDR: {
1763      Binop_12x<HAdd>(instruction, Primitive::kPrimLong);
1764      break;
1765    }
1766
1767    case Instruction::ADD_DOUBLE_2ADDR: {
1768      Binop_12x<HAdd>(instruction, Primitive::kPrimDouble);
1769      break;
1770    }
1771
1772    case Instruction::ADD_FLOAT_2ADDR: {
1773      Binop_12x<HAdd>(instruction, Primitive::kPrimFloat);
1774      break;
1775    }
1776
1777    case Instruction::SUB_INT_2ADDR: {
1778      Binop_12x<HSub>(instruction, Primitive::kPrimInt);
1779      break;
1780    }
1781
1782    case Instruction::SUB_LONG_2ADDR: {
1783      Binop_12x<HSub>(instruction, Primitive::kPrimLong);
1784      break;
1785    }
1786
1787    case Instruction::SUB_FLOAT_2ADDR: {
1788      Binop_12x<HSub>(instruction, Primitive::kPrimFloat);
1789      break;
1790    }
1791
1792    case Instruction::SUB_DOUBLE_2ADDR: {
1793      Binop_12x<HSub>(instruction, Primitive::kPrimDouble);
1794      break;
1795    }
1796
1797    case Instruction::MUL_INT_2ADDR: {
1798      Binop_12x<HMul>(instruction, Primitive::kPrimInt);
1799      break;
1800    }
1801
1802    case Instruction::MUL_LONG_2ADDR: {
1803      Binop_12x<HMul>(instruction, Primitive::kPrimLong);
1804      break;
1805    }
1806
1807    case Instruction::MUL_FLOAT_2ADDR: {
1808      Binop_12x<HMul>(instruction, Primitive::kPrimFloat);
1809      break;
1810    }
1811
1812    case Instruction::MUL_DOUBLE_2ADDR: {
1813      Binop_12x<HMul>(instruction, Primitive::kPrimDouble);
1814      break;
1815    }
1816
1817    case Instruction::DIV_INT_2ADDR: {
1818      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
1819                         dex_pc, Primitive::kPrimInt, false, true);
1820      break;
1821    }
1822
1823    case Instruction::DIV_LONG_2ADDR: {
1824      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
1825                         dex_pc, Primitive::kPrimLong, false, true);
1826      break;
1827    }
1828
1829    case Instruction::REM_INT_2ADDR: {
1830      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
1831                         dex_pc, Primitive::kPrimInt, false, false);
1832      break;
1833    }
1834
1835    case Instruction::REM_LONG_2ADDR: {
1836      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(),
1837                         dex_pc, Primitive::kPrimLong, false, false);
1838      break;
1839    }
1840
1841    case Instruction::REM_FLOAT_2ADDR: {
1842      Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc);
1843      break;
1844    }
1845
1846    case Instruction::REM_DOUBLE_2ADDR: {
1847      Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc);
1848      break;
1849    }
1850
1851    case Instruction::SHL_INT_2ADDR: {
1852      Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt);
1853      break;
1854    }
1855
1856    case Instruction::SHL_LONG_2ADDR: {
1857      Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong);
1858      break;
1859    }
1860
1861    case Instruction::SHR_INT_2ADDR: {
1862      Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt);
1863      break;
1864    }
1865
1866    case Instruction::SHR_LONG_2ADDR: {
1867      Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong);
1868      break;
1869    }
1870
1871    case Instruction::USHR_INT_2ADDR: {
1872      Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt);
1873      break;
1874    }
1875
1876    case Instruction::USHR_LONG_2ADDR: {
1877      Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong);
1878      break;
1879    }
1880
1881    case Instruction::DIV_FLOAT_2ADDR: {
1882      Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc);
1883      break;
1884    }
1885
1886    case Instruction::DIV_DOUBLE_2ADDR: {
1887      Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc);
1888      break;
1889    }
1890
1891    case Instruction::AND_INT_2ADDR: {
1892      Binop_12x<HAnd>(instruction, Primitive::kPrimInt);
1893      break;
1894    }
1895
1896    case Instruction::AND_LONG_2ADDR: {
1897      Binop_12x<HAnd>(instruction, Primitive::kPrimLong);
1898      break;
1899    }
1900
1901    case Instruction::OR_INT_2ADDR: {
1902      Binop_12x<HOr>(instruction, Primitive::kPrimInt);
1903      break;
1904    }
1905
1906    case Instruction::OR_LONG_2ADDR: {
1907      Binop_12x<HOr>(instruction, Primitive::kPrimLong);
1908      break;
1909    }
1910
1911    case Instruction::XOR_INT_2ADDR: {
1912      Binop_12x<HXor>(instruction, Primitive::kPrimInt);
1913      break;
1914    }
1915
1916    case Instruction::XOR_LONG_2ADDR: {
1917      Binop_12x<HXor>(instruction, Primitive::kPrimLong);
1918      break;
1919    }
1920
1921    case Instruction::ADD_INT_LIT16: {
1922      Binop_22s<HAdd>(instruction, false);
1923      break;
1924    }
1925
1926    case Instruction::AND_INT_LIT16: {
1927      Binop_22s<HAnd>(instruction, false);
1928      break;
1929    }
1930
1931    case Instruction::OR_INT_LIT16: {
1932      Binop_22s<HOr>(instruction, false);
1933      break;
1934    }
1935
1936    case Instruction::XOR_INT_LIT16: {
1937      Binop_22s<HXor>(instruction, false);
1938      break;
1939    }
1940
1941    case Instruction::RSUB_INT: {
1942      Binop_22s<HSub>(instruction, true);
1943      break;
1944    }
1945
1946    case Instruction::MUL_INT_LIT16: {
1947      Binop_22s<HMul>(instruction, false);
1948      break;
1949    }
1950
1951    case Instruction::ADD_INT_LIT8: {
1952      Binop_22b<HAdd>(instruction, false);
1953      break;
1954    }
1955
1956    case Instruction::AND_INT_LIT8: {
1957      Binop_22b<HAnd>(instruction, false);
1958      break;
1959    }
1960
1961    case Instruction::OR_INT_LIT8: {
1962      Binop_22b<HOr>(instruction, false);
1963      break;
1964    }
1965
1966    case Instruction::XOR_INT_LIT8: {
1967      Binop_22b<HXor>(instruction, false);
1968      break;
1969    }
1970
1971    case Instruction::RSUB_INT_LIT8: {
1972      Binop_22b<HSub>(instruction, true);
1973      break;
1974    }
1975
1976    case Instruction::MUL_INT_LIT8: {
1977      Binop_22b<HMul>(instruction, false);
1978      break;
1979    }
1980
1981    case Instruction::DIV_INT_LIT16:
1982    case Instruction::DIV_INT_LIT8: {
1983      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1984                         dex_pc, Primitive::kPrimInt, true, true);
1985      break;
1986    }
1987
1988    case Instruction::REM_INT_LIT16:
1989    case Instruction::REM_INT_LIT8: {
1990      BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(),
1991                         dex_pc, Primitive::kPrimInt, true, false);
1992      break;
1993    }
1994
1995    case Instruction::SHL_INT_LIT8: {
1996      Binop_22b<HShl>(instruction, false);
1997      break;
1998    }
1999
2000    case Instruction::SHR_INT_LIT8: {
2001      Binop_22b<HShr>(instruction, false);
2002      break;
2003    }
2004
2005    case Instruction::USHR_INT_LIT8: {
2006      Binop_22b<HUShr>(instruction, false);
2007      break;
2008    }
2009
2010    case Instruction::NEW_INSTANCE: {
2011      uint16_t type_index = instruction.VRegB_21c();
2012      if (compiler_driver_->IsStringTypeIndex(type_index, dex_file_)) {
2013        // Turn new-instance of string into a const 0.
2014        int32_t register_index = instruction.VRegA();
2015        HNullConstant* constant = graph_->GetNullConstant();
2016        UpdateLocal(register_index, constant);
2017      } else {
2018        QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
2019            ? kQuickAllocObjectWithAccessCheck
2020            : kQuickAllocObject;
2021
2022        current_block_->AddInstruction(new (arena_) HNewInstance(dex_pc, type_index, entrypoint));
2023        UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
2024      }
2025      break;
2026    }
2027
2028    case Instruction::NEW_ARRAY: {
2029      uint16_t type_index = instruction.VRegC_22c();
2030      HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt);
2031      QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
2032          ? kQuickAllocArrayWithAccessCheck
2033          : kQuickAllocArray;
2034      current_block_->AddInstruction(
2035          new (arena_) HNewArray(length, dex_pc, type_index, entrypoint));
2036      UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
2037      break;
2038    }
2039
2040    case Instruction::FILLED_NEW_ARRAY: {
2041      uint32_t number_of_vreg_arguments = instruction.VRegA_35c();
2042      uint32_t type_index = instruction.VRegB_35c();
2043      uint32_t args[5];
2044      instruction.GetVarArgs(args);
2045      BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0);
2046      break;
2047    }
2048
2049    case Instruction::FILLED_NEW_ARRAY_RANGE: {
2050      uint32_t number_of_vreg_arguments = instruction.VRegA_3rc();
2051      uint32_t type_index = instruction.VRegB_3rc();
2052      uint32_t register_index = instruction.VRegC_3rc();
2053      BuildFilledNewArray(
2054          dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index);
2055      break;
2056    }
2057
2058    case Instruction::FILL_ARRAY_DATA: {
2059      BuildFillArrayData(instruction, dex_pc);
2060      break;
2061    }
2062
2063    case Instruction::MOVE_RESULT:
2064    case Instruction::MOVE_RESULT_WIDE:
2065    case Instruction::MOVE_RESULT_OBJECT:
2066      if (latest_result_ == nullptr) {
2067        // Only dead code can lead to this situation, where the verifier
2068        // does not reject the method.
2069      } else {
2070        UpdateLocal(instruction.VRegA(), latest_result_);
2071        latest_result_ = nullptr;
2072      }
2073      break;
2074
2075    case Instruction::CMP_LONG: {
2076      Binop_23x_cmp(instruction, Primitive::kPrimLong, HCompare::kNoBias, dex_pc);
2077      break;
2078    }
2079
2080    case Instruction::CMPG_FLOAT: {
2081      Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kGtBias, dex_pc);
2082      break;
2083    }
2084
2085    case Instruction::CMPG_DOUBLE: {
2086      Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kGtBias, dex_pc);
2087      break;
2088    }
2089
2090    case Instruction::CMPL_FLOAT: {
2091      Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kLtBias, dex_pc);
2092      break;
2093    }
2094
2095    case Instruction::CMPL_DOUBLE: {
2096      Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kLtBias, dex_pc);
2097      break;
2098    }
2099
2100    case Instruction::NOP:
2101      break;
2102
2103    case Instruction::IGET:
2104    case Instruction::IGET_WIDE:
2105    case Instruction::IGET_OBJECT:
2106    case Instruction::IGET_BOOLEAN:
2107    case Instruction::IGET_BYTE:
2108    case Instruction::IGET_CHAR:
2109    case Instruction::IGET_SHORT: {
2110      if (!BuildInstanceFieldAccess(instruction, dex_pc, false)) {
2111        return false;
2112      }
2113      break;
2114    }
2115
2116    case Instruction::IPUT:
2117    case Instruction::IPUT_WIDE:
2118    case Instruction::IPUT_OBJECT:
2119    case Instruction::IPUT_BOOLEAN:
2120    case Instruction::IPUT_BYTE:
2121    case Instruction::IPUT_CHAR:
2122    case Instruction::IPUT_SHORT: {
2123      if (!BuildInstanceFieldAccess(instruction, dex_pc, true)) {
2124        return false;
2125      }
2126      break;
2127    }
2128
2129    case Instruction::SGET:
2130    case Instruction::SGET_WIDE:
2131    case Instruction::SGET_OBJECT:
2132    case Instruction::SGET_BOOLEAN:
2133    case Instruction::SGET_BYTE:
2134    case Instruction::SGET_CHAR:
2135    case Instruction::SGET_SHORT: {
2136      if (!BuildStaticFieldAccess(instruction, dex_pc, false)) {
2137        return false;
2138      }
2139      break;
2140    }
2141
2142    case Instruction::SPUT:
2143    case Instruction::SPUT_WIDE:
2144    case Instruction::SPUT_OBJECT:
2145    case Instruction::SPUT_BOOLEAN:
2146    case Instruction::SPUT_BYTE:
2147    case Instruction::SPUT_CHAR:
2148    case Instruction::SPUT_SHORT: {
2149      if (!BuildStaticFieldAccess(instruction, dex_pc, true)) {
2150        return false;
2151      }
2152      break;
2153    }
2154
2155#define ARRAY_XX(kind, anticipated_type)                                          \
2156    case Instruction::AGET##kind: {                                               \
2157      BuildArrayAccess(instruction, dex_pc, false, anticipated_type);         \
2158      break;                                                                      \
2159    }                                                                             \
2160    case Instruction::APUT##kind: {                                               \
2161      BuildArrayAccess(instruction, dex_pc, true, anticipated_type);          \
2162      break;                                                                      \
2163    }
2164
2165    ARRAY_XX(, Primitive::kPrimInt);
2166    ARRAY_XX(_WIDE, Primitive::kPrimLong);
2167    ARRAY_XX(_OBJECT, Primitive::kPrimNot);
2168    ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean);
2169    ARRAY_XX(_BYTE, Primitive::kPrimByte);
2170    ARRAY_XX(_CHAR, Primitive::kPrimChar);
2171    ARRAY_XX(_SHORT, Primitive::kPrimShort);
2172
2173    case Instruction::ARRAY_LENGTH: {
2174      HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot);
2175      // No need for a temporary for the null check, it is the only input of the following
2176      // instruction.
2177      object = new (arena_) HNullCheck(object, dex_pc);
2178      current_block_->AddInstruction(object);
2179      current_block_->AddInstruction(new (arena_) HArrayLength(object));
2180      UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction());
2181      break;
2182    }
2183
2184    case Instruction::CONST_STRING: {
2185      current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_21c(), dex_pc));
2186      UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
2187      break;
2188    }
2189
2190    case Instruction::CONST_STRING_JUMBO: {
2191      current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_31c(), dex_pc));
2192      UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction());
2193      break;
2194    }
2195
2196    case Instruction::CONST_CLASS: {
2197      uint16_t type_index = instruction.VRegB_21c();
2198      bool type_known_final;
2199      bool type_known_abstract;
2200      bool dont_use_is_referrers_class;
2201      // `CanAccessTypeWithoutChecks` will tell whether the method being
2202      // built is trying to access its own class, so that the generated
2203      // code can optimize for this case. However, the optimization does not
2204      // work for inlining, so we use `IsOutermostCompilingClass` instead.
2205      bool can_access = compiler_driver_->CanAccessTypeWithoutChecks(
2206          dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index,
2207          &type_known_final, &type_known_abstract, &dont_use_is_referrers_class);
2208      if (!can_access) {
2209        MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType);
2210        return false;
2211      }
2212      current_block_->AddInstruction(
2213          new (arena_) HLoadClass(type_index, IsOutermostCompilingClass(type_index), dex_pc));
2214      UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
2215      break;
2216    }
2217
2218    case Instruction::MOVE_EXCEPTION: {
2219      current_block_->AddInstruction(new (arena_) HLoadException());
2220      UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction());
2221      break;
2222    }
2223
2224    case Instruction::THROW: {
2225      HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot);
2226      current_block_->AddInstruction(new (arena_) HThrow(exception, dex_pc));
2227      // A throw instruction must branch to the exit block.
2228      current_block_->AddSuccessor(exit_block_);
2229      // We finished building this block. Set the current block to null to avoid
2230      // adding dead instructions to it.
2231      current_block_ = nullptr;
2232      break;
2233    }
2234
2235    case Instruction::INSTANCE_OF: {
2236      uint8_t destination = instruction.VRegA_22c();
2237      uint8_t reference = instruction.VRegB_22c();
2238      uint16_t type_index = instruction.VRegC_22c();
2239      if (!BuildTypeCheck(instruction, destination, reference, type_index, dex_pc)) {
2240        return false;
2241      }
2242      break;
2243    }
2244
2245    case Instruction::CHECK_CAST: {
2246      uint8_t reference = instruction.VRegA_21c();
2247      uint16_t type_index = instruction.VRegB_21c();
2248      if (!BuildTypeCheck(instruction, -1, reference, type_index, dex_pc)) {
2249        return false;
2250      }
2251      break;
2252    }
2253
2254    case Instruction::MONITOR_ENTER: {
2255      current_block_->AddInstruction(new (arena_) HMonitorOperation(
2256          LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
2257          HMonitorOperation::kEnter,
2258          dex_pc));
2259      break;
2260    }
2261
2262    case Instruction::MONITOR_EXIT: {
2263      current_block_->AddInstruction(new (arena_) HMonitorOperation(
2264          LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot),
2265          HMonitorOperation::kExit,
2266          dex_pc));
2267      break;
2268    }
2269
2270    case Instruction::PACKED_SWITCH: {
2271      BuildPackedSwitch(instruction, dex_pc);
2272      break;
2273    }
2274
2275    case Instruction::SPARSE_SWITCH: {
2276      BuildSparseSwitch(instruction, dex_pc);
2277      break;
2278    }
2279
2280    default:
2281      VLOG(compiler) << "Did not compile "
2282                     << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
2283                     << " because of unhandled instruction "
2284                     << instruction.Name();
2285      MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction);
2286      return false;
2287  }
2288  return true;
2289}  // NOLINT(readability/fn_size)
2290
2291HLocal* HGraphBuilder::GetLocalAt(int register_index) const {
2292  return locals_.Get(register_index);
2293}
2294
2295void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const {
2296  HLocal* local = GetLocalAt(register_index);
2297  current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction));
2298}
2299
2300HInstruction* HGraphBuilder::LoadLocal(int register_index, Primitive::Type type) const {
2301  HLocal* local = GetLocalAt(register_index);
2302  current_block_->AddInstruction(new (arena_) HLoadLocal(local, type));
2303  return current_block_->GetLastInstruction();
2304}
2305
2306}  // namespace art
2307