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