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