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