codegen_util.cc revision 0d82948094d9a198e01aa95f64012bdedd5b6fc9
1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/*
2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project
3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License.
6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at
7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software
11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and
14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License.
15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */
16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h"
184f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h"
2096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h"
218d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h"
220c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h"
230c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h"
240c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
25e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art {
26e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) {
284ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  bool res = false;
294ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  if (rl_src.is_const) {
304ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    if (rl_src.wide) {
314ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
321fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src));
334ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
341fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src));
354ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
364ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    } else {
374ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
381fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src));
394ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
401fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src));
414ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
424ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    }
434ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
444ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
454ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
464ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
472ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) {
48b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!inst->flags.use_def_invalid);
49b48819db07f9a0992a72173380c24249d7fc648abuzbee  inst->u.m.def_mask = ENCODE_ALL;
501fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC);
51b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK_EQ(safepoint_pc->u.m.def_mask, ENCODE_ALL);
5202031b185b4653e6c72e21f7a51238b903f6d638buzbee}
5302031b185b4653e6c72e21f7a51238b903f6d638buzbee
549b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogersbool Mir2Lir::FastInstance(uint32_t field_idx, bool is_put, int* field_offset, bool* is_volatile) {
551fd3346740dfb7f47be9922312b68a4227fada96buzbee  return cu_->compiler_driver->ComputeInstanceFieldInfo(
569b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogers      field_idx, mir_graph_->GetCurrentDexCompilationUnit(), is_put, field_offset, is_volatile);
5702031b185b4653e6c72e21f7a51238b903f6d638buzbee}
5802031b185b4653e6c72e21f7a51238b903f6d638buzbee
59252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */
60252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) {
61252254b130067cd7a5071865e793966871ae0246buzbee  if (UNLIKELY(lir == first_lir_insn_)) {
62252254b130067cd7a5071865e793966871ae0246buzbee    first_lir_insn_ = lir->next;
63252254b130067cd7a5071865e793966871ae0246buzbee    if (lir->next != NULL) {
64252254b130067cd7a5071865e793966871ae0246buzbee      lir->next->prev = NULL;
65252254b130067cd7a5071865e793966871ae0246buzbee    } else {
66252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir->next == NULL);
67252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir == last_lir_insn_);
68252254b130067cd7a5071865e793966871ae0246buzbee      last_lir_insn_ = NULL;
69252254b130067cd7a5071865e793966871ae0246buzbee    }
70252254b130067cd7a5071865e793966871ae0246buzbee  } else if (lir == last_lir_insn_) {
71252254b130067cd7a5071865e793966871ae0246buzbee    last_lir_insn_ = lir->prev;
72252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = NULL;
73252254b130067cd7a5071865e793966871ae0246buzbee  } else if ((lir->prev != NULL) && (lir->next != NULL)) {
74252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = lir->next;
75252254b130067cd7a5071865e793966871ae0246buzbee    lir->next->prev = lir->prev;
76252254b130067cd7a5071865e793966871ae0246buzbee  }
77252254b130067cd7a5071865e793966871ae0246buzbee}
78252254b130067cd7a5071865e793966871ae0246buzbee
79cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */
80df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) {
81fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  lir->flags.is_nop = true;
82252254b130067cd7a5071865e793966871ae0246buzbee  if (!cu_->verbose) {
83252254b130067cd7a5071865e793966871ae0246buzbee    UnlinkLIR(lir);
84252254b130067cd7a5071865e793966871ae0246buzbee  }
85cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee}
86cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee
872ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) {
88fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  uint64_t *mask_ptr;
89f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom  uint64_t mask = ENCODE_MEM;
901fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE));
91b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!lir->flags.use_def_invalid);
92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (is_load) {
93b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.use_mask;
94a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
95b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.def_mask;
96a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
97a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Clear out the memref flags */
98fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  *mask_ptr &= ~mask;
99a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* ..and then add back the one we need */
100fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  switch (mem_type) {
101a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kLiteral:
102fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK(is_load);
103fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_LITERAL;
104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
105a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kDalvikReg:
106fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_DALVIK_REG;
107a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
108a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kHeapRef:
109fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_HEAP_REF;
110a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
111a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMustNotAlias:
112a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      /* Currently only loads can be marked as kMustNotAlias */
1131fd3346740dfb7f47be9922312b68a4227fada96buzbee      DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE));
114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_MUST_NOT_ALIAS;
115a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
116a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
117fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(FATAL) << "Oat: invalid memref kind - " << mem_type;
118a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
11931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
12031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
12131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack.
12331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
1241fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load,
1252ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                                      bool is64bit) {
1261fd3346740dfb7f47be9922312b68a4227fada96buzbee  SetMemRefType(lir, is_load, kDalvikReg);
12731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee   * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit
130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * access.
131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
132b48819db07f9a0992a72173380c24249d7fc648abuzbee  lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit);
13331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
13431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
13531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
1365de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros
1375de3494e4297c0d480409da3fecee39173f1d4e1buzbee */
1385de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X)
1395de3494e4297c0d480409da3fecee39173f1d4e1buzbee
1405de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */
1412ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int offset = lir->offset;
143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int dest = lir->operands[0];
1441fd3346740dfb7f47be9922312b68a4227fada96buzbee  const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops));
145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
146a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Handle pseudo-ops individually, and all regular insns as a group */
147a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch (lir->opcode) {
148a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodEntry:
149a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- method entry "
1501fd3346740dfb7f47be9922312b68a4227fada96buzbee                << PrettyMethod(cu_->method_idx, *cu_->dex_file);
151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodExit:
153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- Method_Exit";
154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
155a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoBarrier:
156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- BARRIER";
157a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEntryBlock:
159a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoDalvikByteCodeBoundary:
1624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (lir->operands[0] == 0) {
1630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         // NOTE: only used for debug listings.
1640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string"));
1654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
166a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- dalvik offset: 0x" << std::hex
167fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                << lir->dalvik_offset << " @ " << reinterpret_cast<char*>(lir->operands[0]);
168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoExitBlock:
170a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
171a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoPseudoAlign4:
173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex
174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << offset << "): .align4";
175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEHBlockLabel:
177a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "Exception_Handling:";
178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoTargetLabel:
180a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoNormalBlockLabel:
181cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":";
182a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoThrowTarget:
184cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":";
185a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
186a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoIntrinsicRetry:
187cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":";
188a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoSuspendTarget:
190cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":";
191a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
1928320f3867c02bae9bef6cdab267820cb7b412781buzbee    case kPseudoSafepointPC:
193fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
1948320f3867c02bae9bef6cdab267820cb7b412781buzbee      break;
195a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    case kPseudoExportedPC:
196fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
197a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee      break;
198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoCaseLabel:
199cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x"
200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << std::hex << lir->operands[0] << "|" << std::dec <<
201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        lir->operands[0];
202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
204fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      if (lir->flags.is_nop && !dump_nop) {
205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        break;
206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {
2071fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode),
20802031b185b4653e6c72e21f7a51238b903f6d638buzbee                                               lir, base_addr));
2091fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
21002031b185b4653e6c72e21f7a51238b903f6d638buzbee                                                    lir, base_addr));
211a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        LOG(INFO) << StringPrintf("%05x: %-9s%s%s",
212fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                  reinterpret_cast<unsigned int>(base_addr + offset),
213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                  op_name.c_str(), op_operands.c_str(),
214fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                  lir->flags.is_nop ? "(nop)" : "");
215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
219b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) {
220b48819db07f9a0992a72173380c24249d7fc648abuzbee    DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.use_mask, "use"));
221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
222b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) {
223b48819db07f9a0992a72173380c24249d7fc648abuzbee    DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.def_mask, "def"));
224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2255de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
2265de3494e4297c0d480409da3fecee39173f1d4e1buzbee
2272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() {
2281fd3346740dfb7f47be9922312b68a4227fada96buzbee  int num_regs = cu_->num_dalvik_registers + cu_->num_compiler_temps + 1;
229fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_regs; i++) {
2301fd3346740dfb7f47be9922312b68a4227fada96buzbee    PromotionMap v_reg_map = promotion_map_[i];
231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf;
232fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (v_reg_map.fp_location == kLocPhysReg) {
2331fd3346740dfb7f47be9922312b68a4227fada96buzbee      StringAppendF(&buf, " : s%d", v_reg_map.FpReg & FpRegMask());
234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
2359c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee
236a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf3;
2371fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (i < cu_->num_dalvik_registers) {
238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      StringAppendF(&buf3, "%02d", i);
2391fd3346740dfb7f47be9922312b68a4227fada96buzbee    } else if (i == mir_graph_->GetMethodSReg()) {
240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      buf3 = "Method*";
241a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
2421fd3346740dfb7f47be9922312b68a4227fada96buzbee      StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers);
2435de3494e4297c0d480409da3fecee39173f1d4e1buzbee    }
244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
246fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              v_reg_map.core_location == kLocPhysReg ?
247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              "r" : "SP+", v_reg_map.core_location == kLocPhysReg ?
2481fd3346740dfb7f47be9922312b68a4227fada96buzbee                              v_reg_map.core_reg : SRegOffset(i),
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                              buf.c_str());
250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2515de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
2525de3494e4297c0d480409da3fecee39173f1d4e1buzbee
253a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee/* Dump a mapping table */
254d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogersvoid Mir2Lir::DumpMappingTable(const char* table_name, const char* descriptor,
255d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers                               const char* name, const Signature& signature,
2561fd3346740dfb7f47be9922312b68a4227fada96buzbee                               const std::vector<uint32_t>& v) {
257a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  if (v.size() > 0) {
258a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    std::string line(StringPrintf("\n  %s %s%s_%s_table[%zu] = {", table_name,
259d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers                     descriptor, name, signature.ToString().c_str(), v.size()));
260a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    std::replace(line.begin(), line.end(), ';', '_');
261a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    LOG(INFO) << line;
262a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    for (uint32_t i = 0; i < v.size(); i+=2) {
263a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee      line = StringPrintf("    {0x%05x, 0x%04x},", v[i], v[i+1]);
264a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee      LOG(INFO) << line;
265a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    }
266a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    LOG(INFO) <<"  };\n\n";
267a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  }
268a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee}
269a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee
2705de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */
2712ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() {
272a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Dumping LIR insns for "
2731fd3346740dfb7f47be9922312b68a4227fada96buzbee            << PrettyMethod(cu_->method_idx, *cu_->dex_file);
274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lir_insn;
2751fd3346740dfb7f47be9922312b68a4227fada96buzbee  int insns_size = cu_->code_item->insns_size_in_code_units_;
2761fd3346740dfb7f47be9922312b68a4227fada96buzbee
2771fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs;
2781fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Ins          : " << cu_->num_ins;
2791fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Outs         : " << cu_->num_outs;
2801fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "CoreSpills       : " << num_core_spills_;
2811fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "FPSpills       : " << num_fp_spills_;
2821fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "CompilerTemps    : " << cu_->num_compiler_temps;
2831fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Frame size       : " << frame_size_;
2841fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "code size is " << total_size_ <<
285fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    " bytes, Dalvik size is " << insns_size * 2;
286a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "expansion factor: "
2871fd3346740dfb7f47be9922312b68a4227fada96buzbee            << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2);
2881fd3346740dfb7f47be9922312b68a4227fada96buzbee  DumpPromotionMap();
2891fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) {
2901fd3346740dfb7f47be9922312b68a4227fada96buzbee    DumpLIRInsn(lir_insn, 0);
291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2921fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) {
293fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset,
294fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              lir_insn->operands[0]);
295a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
297a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  const DexFile::MethodId& method_id =
2981fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_->dex_file->GetMethodId(cu_->method_idx);
299d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const Signature signature = cu_->dex_file->GetMethodSignature(method_id);
300d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* name = cu_->dex_file->GetMethodName(method_id);
301d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
302a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
303a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  // Dump mapping tables
3041fd3346740dfb7f47be9922312b68a4227fada96buzbee  DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, pc2dex_mapping_table_);
3051fd3346740dfb7f47be9922312b68a4227fada96buzbee  DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, dex2pc_mapping_table_);
3065de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
3075de3494e4297c0d480409da3fecee39173f1d4e1buzbee
30831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
30931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match
31031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0).
31131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
3122ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) {
313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
314fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta)
315fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return data_target;
316fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
318a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
31931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
32031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
32131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */
3222ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) {
323fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  bool lo_match = false;
324fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lo_target = NULL;
325fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
326fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (lo_match && (data_target->operands[0] == val_hi)) {
3274ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      // Record high word in case we need to expand this later.
3284ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      lo_target->operands[1] = val_hi;
329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return lo_target;
33031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
331fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lo_match = false;
332fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (data_target->operands[0] == val_lo) {
333fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_match = true;
334fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_target = data_target;
335a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
336fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
337a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
338a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
33931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
34031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
34131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
34231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or
34331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams.
34431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
34531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
3464ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */
3472ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) {
348a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Add the constant to the literal pool */
349fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (constant_list_p) {
350f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier    LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocData));
351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->operands[0] = value;
352fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->next = *constant_list_p;
353fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    *constant_list_p = new_value;
354b48819db07f9a0992a72173380c24249d7fc648abuzbee    estimated_native_code_size_ += sizeof(value);
355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    return new_value;
356a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
357a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
35831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */
3612ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) {
3621fd3346740dfb7f47be9922312b68a4227fada96buzbee  AddWordData(constant_list_p, val_hi);
3631fd3346740dfb7f47be9922312b68a4227fada96buzbee  return AddWordData(constant_list_p, val_lo);
36431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
36531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
366aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void PushWord(std::vector<uint8_t>&buf, int data) {
367df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back(data & 0xff);
368df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 8) & 0xff);
369df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 16) & 0xff);
370df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 24) & 0xff);
371e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
372e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
3730d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee// Push 8 bytes on 64-bit systems; 4 on 32-bit systems.
3740d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic void PushPointer(std::vector<uint8_t>&buf, void const* pointer) {
3750d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  uintptr_t data = reinterpret_cast<uintptr_t>(pointer);
3760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  if (sizeof(void*) == sizeof(uint64_t)) {
3770d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, (data >> (sizeof(void*) * 4)) & 0xFFFFFFFF);
3780d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, data & 0xFFFFFFFF);
3790d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  } else {
3800d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, data);
3810d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
3820d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
3830d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
384aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
385a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (buf.size() < offset) {
386a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    buf.push_back(0);
387a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
388e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
389e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
390e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */
3912ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() {
3921fd3346740dfb7f47be9922312b68a4227fada96buzbee  AlignBuffer(code_buffer_, data_offset_);
3931fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* data_lir = literal_list_;
394fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
3951fd3346740dfb7f47be9922312b68a4227fada96buzbee    PushWord(code_buffer_, data_lir->operands[0]);
396fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
397a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
398a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Push code and method literals, record offsets for the compiler to patch.
3991fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = code_literal_list_;
400fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
401fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    uint32_t target = data_lir->operands[0];
4021fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddCodePatch(cu_->dex_file,
4038b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->class_def_idx,
4048b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->method_idx,
4058b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->invoke_type,
4068b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       target,
4078b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       static_cast<InvokeType>(data_lir->operands[1]),
4088b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       code_buffer_.size());
4091fd3346740dfb7f47be9922312b68a4227fada96buzbee    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
4100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
4110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushPointer(code_buffer_, &id);
412fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
413137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  }
4141fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = method_literal_list_;
415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
416fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    uint32_t target = data_lir->operands[0];
4171fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddMethodPatch(cu_->dex_file,
4188b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->class_def_idx,
4198b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->method_idx,
4208b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->invoke_type,
4218b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         target,
4228b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         static_cast<InvokeType>(data_lir->operands[1]),
4238b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         code_buffer_.size());
4241fd3346740dfb7f47be9922312b68a4227fada96buzbee    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
4250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
4260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushPointer(code_buffer_, &id);
427fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
428a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
429e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
430e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
431e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */
4322ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() {
433862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
434a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
435862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
436fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
4371fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
438a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /*
439a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * For Arm, our reference point is the address of the bx
440a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * instruction that does the launch, so we have to subtract
441a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * the auto pc-advance.  For other targets the reference point
442a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * is a label, so we can use the offset as-is.
443a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     */
444fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    int bx_offset = INVALID_OFFSET;
4451fd3346740dfb7f47be9922312b68a4227fada96buzbee    switch (cu_->instruction_set) {
446b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kThumb2:
447b48819db07f9a0992a72173380c24249d7fc648abuzbee        DCHECK(tab_rec->anchor->flags.fixup != kFixupNone);
448fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset + 4;
449b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
450b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kX86:
451fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = 0;
452b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
453b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kMips:
454fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset;
455b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
4561fd3346740dfb7f47be9922312b68a4227fada96buzbee      default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set;
457b046e16d8b8da318d6055f9308950131f1255e08buzbee    }
4581fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (cu_->verbose) {
459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
461fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
4620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2]));
463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
4651fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
466a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] key: 0x"
467a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << keys[elems] << ", disp: 0x"
468a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
469e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
4701fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_, keys[elems]);
4711fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_,
472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee          tab_rec->targets[elems]->offset - bx_offset);
473a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
474a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
475fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
476a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
478fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
4791fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
480a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] disp: 0x"
481a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
482e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
4831fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_, tab_rec->targets[elems]->offset - bx_offset);
484a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
485e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
486a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
487e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
488e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
489e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */
4902ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() {
491862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
492a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
493862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
4951fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
497df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back(tab_rec->table[i] & 0xFF);
498df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF);
499e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
500a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
501e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
502e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
5030d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) {
50402c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom  for (; lir != NULL; lir = lir->next) {
505a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    lir->offset = offset;
506a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    offset += 4;
507a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
508a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
509e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
510e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
5110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset) {
5120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  unsigned int element_size = sizeof(void*);
5130d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Align to natural pointer size.
5140d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = (offset + (element_size - 1)) & ~(element_size - 1);
5150d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  for (; lir != NULL; lir = lir->next) {
5160d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    lir->offset = offset;
5170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    offset += element_size;
5180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
5190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  return offset;
5200d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
5210d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
5226459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry
5232ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() {
5246459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  bool success = true;
5251fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (std::set<uint32_t>::const_iterator it = mir_graph_->catches_.begin();
5261fd3346740dfb7f47be9922312b68a4227fada96buzbee       it != mir_graph_->catches_.end(); ++it) {
527fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    uint32_t dex_pc = *it;
5286459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    bool found = false;
5291fd3346740dfb7f47be9922312b68a4227fada96buzbee    for (size_t i = 0; i < dex2pc_mapping_table_.size(); i += 2) {
5301fd3346740dfb7f47be9922312b68a4227fada96buzbee      if (dex_pc == dex2pc_mapping_table_[i+1]) {
5316459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee        found = true;
5326459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee        break;
5336459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      }
5346459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
5356459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    if (!found) {
536fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc;
5376459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
5386459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
5396459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
5406459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  // Now, try in the other direction
5411fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (size_t i = 0; i < dex2pc_mapping_table_.size(); i += 2) {
5421fd3346740dfb7f47be9922312b68a4227fada96buzbee    uint32_t dex_pc = dex2pc_mapping_table_[i+1];
5431fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (mir_graph_->catches_.find(dex_pc) == mir_graph_->catches_.end()) {
544fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << dex_pc;
5456459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
5466459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
5476459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
5486459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  if (!success) {
5491fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
5501fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: "
5511fd3346740dfb7f47be9922312b68a4227fada96buzbee              << dex2pc_mapping_table_.size()/2;
5526459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
5536459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  return success;
5546459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee}
5556459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee
556311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
5572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() {
5581fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
559fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
5601fd3346740dfb7f47be9922312b68a4227fada96buzbee      pc2dex_mapping_table_.push_back(tgt_lir->offset);
5611fd3346740dfb7f47be9922312b68a4227fada96buzbee      pc2dex_mapping_table_.push_back(tgt_lir->dalvik_offset);
562a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    }
563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
5641fd3346740dfb7f47be9922312b68a4227fada96buzbee      dex2pc_mapping_table_.push_back(tgt_lir->offset);
5651fd3346740dfb7f47be9922312b68a4227fada96buzbee      dex2pc_mapping_table_.push_back(tgt_lir->dalvik_offset);
566e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
567a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
568311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
56996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK(VerifyCatchEntries());
57096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  }
57196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  CHECK_EQ(pc2dex_mapping_table_.size() & 1, 0U);
57296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  CHECK_EQ(dex2pc_mapping_table_.size() & 1, 0U);
57396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  uint32_t total_entries = (pc2dex_mapping_table_.size() + dex2pc_mapping_table_.size()) / 2;
57496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  uint32_t pc2dex_entries = pc2dex_mapping_table_.size() / 2;
57596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  encoded_mapping_table_.PushBack(total_entries);
57696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  encoded_mapping_table_.PushBack(pc2dex_entries);
57796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  encoded_mapping_table_.InsertBack(pc2dex_mapping_table_.begin(), pc2dex_mapping_table_.end());
57896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  encoded_mapping_table_.InsertBack(dex2pc_mapping_table_.begin(), dex2pc_mapping_table_.end());
57996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  if (kIsDebugBuild) {
58096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    // Verify the encoded table holds the expected data.
58196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    MappingTable table(&encoded_mapping_table_.GetData()[0]);
58296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.TotalSize(), total_entries);
58396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.PcToDexSize(), pc2dex_entries);
58496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.DexToPcSize(), dex2pc_mapping_table_.size() / 2);
58596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    MappingTable::PcToDexIterator it = table.PcToDexBegin();
58696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    for (uint32_t i = 0; i < pc2dex_mapping_table_.size(); ++i, ++it) {
58796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      CHECK_EQ(pc2dex_mapping_table_.at(i), it.NativePcOffset());
58896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      ++i;
58996faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      CHECK_EQ(pc2dex_mapping_table_.at(i), it.DexPc());
59096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    }
59196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    MappingTable::DexToPcIterator it2 = table.DexToPcBegin();
59296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    for (uint32_t i = 0; i < dex2pc_mapping_table_.size(); ++i, ++it2) {
59396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      CHECK_EQ(dex2pc_mapping_table_.at(i), it2.NativePcOffset());
59496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      ++i;
59596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers      CHECK_EQ(dex2pc_mapping_table_.at(i), it2.DexPc());
59696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    }
597311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
598e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
599e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
6000c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogersclass NativePcToReferenceMapBuilder {
6010c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers public:
6020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  NativePcToReferenceMapBuilder(std::vector<uint8_t>* table,
6030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                size_t entries, uint32_t max_native_offset,
6040c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                size_t references_width) : entries_(entries),
6050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                references_width_(references_width), in_use_(entries),
6060c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                table_(table) {
6070c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    // Compute width in bytes needed to hold max_native_offset.
6080c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    native_offset_width_ = 0;
6090c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    while (max_native_offset != 0) {
6100c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      native_offset_width_++;
6110c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      max_native_offset >>= 8;
6120c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6130c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    // Resize table and set up header.
6140c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    table->resize((EntryWidth() * entries) + sizeof(uint32_t));
615000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    CHECK_LT(native_offset_width_, 1U << 3);
616000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[0] = native_offset_width_ & 7;
617000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    CHECK_LT(references_width_, 1U << 13);
618000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[0] |= (references_width_ << 3) & 0xFF;
619000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[1] = (references_width_ >> 5) & 0xFF;
6200c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    CHECK_LT(entries, 1U << 16);
6210c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    (*table)[2] = entries & 0xFF;
6220c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    (*table)[3] = (entries >> 8) & 0xFF;
6230c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6240c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6250c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  void AddEntry(uint32_t native_offset, const uint8_t* references) {
6260c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_index = TableIndex(native_offset);
6270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    while (in_use_[table_index]) {
6280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      table_index = (table_index + 1) % entries_;
6290c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    in_use_[table_index] = true;
6310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    SetCodeOffset(table_index, native_offset);
6320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    DCHECK_EQ(native_offset, GetCodeOffset(table_index));
6330c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    SetReferences(table_index, references);
6340c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6350c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6360c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers private:
6370c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t TableIndex(uint32_t native_offset) {
6380c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return NativePcOffsetToReferenceMap::Hash(native_offset) % entries_;
6390c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6400c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  uint32_t GetCodeOffset(size_t table_index) {
6420c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    uint32_t native_offset = 0;
6430c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
6440c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    for (size_t i = 0; i < native_offset_width_; i++) {
6450c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      native_offset |= (*table_)[table_offset + i] << (i * 8);
6460c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6470c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return native_offset;
6480c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6490c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  void SetCodeOffset(size_t table_index, uint32_t native_offset) {
6510c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
6520c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    for (size_t i = 0; i < native_offset_width_; i++) {
6530c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      (*table_)[table_offset + i] = (native_offset >> (i * 8)) & 0xFF;
6540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6560c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6570c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  void SetReferences(size_t table_index, const uint8_t* references) {
6580c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
6590c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    memcpy(&(*table_)[table_offset + native_offset_width_], references, references_width_);
6600c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6610c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6620c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t EntryWidth() const {
6630c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return native_offset_width_ + references_width_;
6640c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
6650c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6660c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of entries in the table.
6670c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  const size_t entries_;
6680c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of bytes used to encode the reference bitmap.
6690c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  const size_t references_width_;
6700c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of bytes used to encode a native offset.
6710c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t native_offset_width_;
6720c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Entries that are in use.
6730c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  std::vector<bool> in_use_;
6740c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // The table we're building.
6750c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  std::vector<uint8_t>* const table_;
6760c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers};
6770c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6781fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() {
6791fd3346740dfb7f47be9922312b68a4227fada96buzbee  const std::vector<uint32_t>& mapping_table = pc2dex_mapping_table_;
6800c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  uint32_t max_native_offset = 0;
6810c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  for (size_t i = 0; i < mapping_table.size(); i += 2) {
6820c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    uint32_t native_offset = mapping_table[i + 0];
6830c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    if (native_offset > max_native_offset) {
6840c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      max_native_offset = native_offset;
6850c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6860c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
68751c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom  MethodReference method_ref(cu_->dex_file, cu_->method_idx);
6880c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  const std::vector<uint8_t>* gc_map_raw = verifier::MethodVerifier::GetDexGcMap(method_ref);
6890c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  verifier::DexPcToReferenceMap dex_gc_map(&(*gc_map_raw)[4], gc_map_raw->size() - 4);
6900c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Compute native offset to references size.
6911fd3346740dfb7f47be9922312b68a4227fada96buzbee  NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_,
6920c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                                      mapping_table.size() / 2, max_native_offset,
6930c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                                      dex_gc_map.RegWidth());
6940c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
6950c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  for (size_t i = 0; i < mapping_table.size(); i += 2) {
6960c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    uint32_t native_offset = mapping_table[i + 0];
6970c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    uint32_t dex_pc = mapping_table[i + 1];
6980c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
699a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc;
700a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    native_gc_map_builder.AddEntry(native_offset, references);
7010c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers}
7030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
704e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */
7050d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) {
7061fd3346740dfb7f47be9922312b68a4227fada96buzbee  offset = AssignLiteralOffsetCommon(literal_list_, offset);
7070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset);
7080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset);
709a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
710e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
711e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
7120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) {
713862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
714a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
7150d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
716fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
717fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
718fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
719fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * (sizeof(int) * 2);
720a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
721fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
722a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
723fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * sizeof(int);
724e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
725a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
726a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
727e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
728e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
7290d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) {
730862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
731a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
732862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
733fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
734fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
735fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    offset += tab_rec->size;
736a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // word align
737a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    offset = (offset + 3) & ~3;
738a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
739a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
740e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
741e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
74231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
74331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik
744b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block
745b48819db07f9a0992a72173380c24249d7fc648abuzbee * label.  The selected label will be used to fix up the case
746252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase.  All resource flags
747252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion.  KeyVal is just there for debugging.
74831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
7490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) {
750252254b130067cd7a5071865e793966871ae0246buzbee  LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id];
751b48819db07f9a0992a72173380c24249d7fc648abuzbee  LIR* res = boundary_lir;
752b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (cu_->verbose) {
753b48819db07f9a0992a72173380c24249d7fc648abuzbee    // Only pay the expense if we're pretty-printing.
754b48819db07f9a0992a72173380c24249d7fc648abuzbee    LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocLIR));
755b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->dalvik_offset = vaddr;
756b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->opcode = kPseudoCaseLabel;
757b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->operands[0] = keyVal;
758b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->flags.fixup = kFixupLabel;
759b48819db07f9a0992a72173380c24249d7fc648abuzbee    DCHECK(!new_label->flags.use_def_invalid);
760b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->u.m.def_mask = ENCODE_ALL;
761b48819db07f9a0992a72173380c24249d7fc648abuzbee    InsertLIRAfter(boundary_lir, new_label);
762b48819db07f9a0992a72173380c24249d7fc648abuzbee    res = new_label;
763b48819db07f9a0992a72173380c24249d7fc648abuzbee  }
764b48819db07f9a0992a72173380c24249d7fc648abuzbee  return res;
76531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
76631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
7670d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
768fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
7690d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
7700d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]);
771a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
772fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
773a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
7741fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key);
775a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
77631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
77731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
7780d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
779fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
7800d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
781a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
7820d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
7830d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
784a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
7851fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]);
786a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
78731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
78831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
7892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() {
790862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
792862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable *tab_rec = iterator.Next();
793fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
794fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) {
7951fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkPackedCaseLabels(tab_rec);
796fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
7971fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkSparseCaseLabels(tab_rec);
798a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
799a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(FATAL) << "Invalid switch table";
80031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
801a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
80231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
80331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8042ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) {
805a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
806a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sparse switch data format:
807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0200   magic value
808a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table; > 0
809a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int keys[size]      keys, sorted low-to-high; 32-bit aligned
810a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
811a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
812a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (2+size*4) 16-bit code units.
813a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
814eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
815a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
8160d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
8170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
818a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident
819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee            << ", entries: " << std::dec << entries;
820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
821a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << "  Key[" << keys[i] << "] -> 0x" << std::hex << targets[i];
822a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
82331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8252ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) {
826a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
827a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Packed switch data format:
828a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0100   magic value
829a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table
830a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int first_key       first (and lowest) switch case value
831a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
832a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
833a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (4+size*2) 16-bit code units.
834a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
835eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
8360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]);
837a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
838fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
839a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident
840fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee            << ", entries: " << std::dec << entries << ", low_key: " << low_key;
841a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
842fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << "  Key[" << (i + low_key) << "] -> 0x" << std::hex
843a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee              << targets[i];
844a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
84531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
846e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
847252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */
8480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) {
8490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // NOTE: only used for debug listings.
8500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str)));
851d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee}
852e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
8532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) {
854e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  bool is_taken;
855e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  switch (opcode) {
856e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQ: is_taken = (src1 == src2); break;
857e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NE: is_taken = (src1 != src2); break;
858e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LT: is_taken = (src1 < src2); break;
859e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GE: is_taken = (src1 >= src2); break;
860e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GT: is_taken = (src1 > src2); break;
861e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LE: is_taken = (src1 <= src2); break;
862e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQZ: is_taken = (src1 == 0); break;
863e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NEZ: is_taken = (src1 != 0); break;
864e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LTZ: is_taken = (src1 < 0); break;
865e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GEZ: is_taken = (src1 >= 0); break;
866e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GTZ: is_taken = (src1 > 0); break;
867e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LEZ: is_taken = (src1 <= 0); break;
868e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    default:
869e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      LOG(FATAL) << "Unexpected opcode " << opcode;
870e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      is_taken = false;
871e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  }
872e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  return is_taken;
873e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee}
874e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee
8754ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1
8761fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) {
8774ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  ConditionCode res;
8784ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  switch (before) {
8794ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondEq: res = kCondEq; break;
8804ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondNe: res = kCondNe; break;
8814ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLt: res = kCondGt; break;
8824ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGt: res = kCondLt; break;
8834ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLe: res = kCondGe; break;
8844ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGe: res = kCondLe; break;
8854ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    default:
8864ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      res = static_cast<ConditionCode>(0);
8874ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      LOG(FATAL) << "Unexpected ccode " << before;
8884ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
8894ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
8904ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
8914ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
892862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc
893862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
8946282dc12440a2072dc06a616160027ff21bd895eIan Rogers    : Backend(arena),
8956282dc12440a2072dc06a616160027ff21bd895eIan Rogers      literal_list_(NULL),
8961fd3346740dfb7f47be9922312b68a4227fada96buzbee      method_literal_list_(NULL),
8971fd3346740dfb7f47be9922312b68a4227fada96buzbee      code_literal_list_(NULL),
898b48819db07f9a0992a72173380c24249d7fc648abuzbee      first_fixup_(NULL),
8991fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_(cu),
9001fd3346740dfb7f47be9922312b68a4227fada96buzbee      mir_graph_(mir_graph),
901862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      switch_tables_(arena, 4, kGrowableArraySwitchTables),
902862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      fill_array_data_(arena, 4, kGrowableArrayFillArrayData),
903862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      throw_launchpads_(arena, 2048, kGrowableArrayThrowLaunchPads),
904862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      suspend_launchpads_(arena, 4, kGrowableArraySuspendLaunchPads),
905862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      intrinsic_launchpads_(arena, 2048, kGrowableArrayMisc),
906bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee      tempreg_info_(arena, 20, kGrowableArrayMisc),
907bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee      reginfo_map_(arena, 64, kGrowableArrayMisc),
9080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      pointer_storage_(arena, 128, kGrowableArrayMisc),
9091fd3346740dfb7f47be9922312b68a4227fada96buzbee      data_offset_(0),
9101fd3346740dfb7f47be9922312b68a4227fada96buzbee      total_size_(0),
9111fd3346740dfb7f47be9922312b68a4227fada96buzbee      block_label_list_(NULL),
912862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      current_dalvik_offset_(0),
913b48819db07f9a0992a72173380c24249d7fc648abuzbee      estimated_native_code_size_(0),
914862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      reg_pool_(NULL),
9151fd3346740dfb7f47be9922312b68a4227fada96buzbee      live_sreg_(0),
9161fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_core_spills_(0),
9171fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_fp_spills_(0),
9181fd3346740dfb7f47be9922312b68a4227fada96buzbee      frame_size_(0),
9191fd3346740dfb7f47be9922312b68a4227fada96buzbee      core_spill_mask_(0),
9201fd3346740dfb7f47be9922312b68a4227fada96buzbee      fp_spill_mask_(0),
9211fd3346740dfb7f47be9922312b68a4227fada96buzbee      first_lir_insn_(NULL),
9222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom      last_lir_insn_(NULL) {
9231fd3346740dfb7f47be9922312b68a4227fada96buzbee  promotion_map_ = static_cast<PromotionMap*>
924f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier      (arena_->Alloc((cu_->num_dalvik_registers  + cu_->num_compiler_temps + 1) *
925f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier                      sizeof(promotion_map_[0]), ArenaAllocator::kAllocRegAlloc));
9260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Reserve pointer id 0 for NULL.
9270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  size_t null_idx = WrapPointer(NULL);
9280d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DCHECK_EQ(null_idx, 0U);
9291fd3346740dfb7f47be9922312b68a4227fada96buzbee}
9301fd3346740dfb7f47be9922312b68a4227fada96buzbee
9311fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() {
9321fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompilerInitializeRegAlloc();  // Needs to happen after SSA naming
9331fd3346740dfb7f47be9922312b68a4227fada96buzbee
9341fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Allocate Registers using simple local allocation scheme */
9351fd3346740dfb7f47be9922312b68a4227fada96buzbee  SimpleRegAlloc();
9361fd3346740dfb7f47be9922312b68a4227fada96buzbee
937479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  if (mir_graph_->IsSpecialCase()) {
9381fd3346740dfb7f47be9922312b68a4227fada96buzbee      /*
9391fd3346740dfb7f47be9922312b68a4227fada96buzbee       * Custom codegen for special cases.  If for any reason the
9401fd3346740dfb7f47be9922312b68a4227fada96buzbee       * special codegen doesn't succeed, first_lir_insn_ will
9411fd3346740dfb7f47be9922312b68a4227fada96buzbee       * set to NULL;
9421fd3346740dfb7f47be9922312b68a4227fada96buzbee       */
943479f83c196d5a95e36196eac548dc6019e70a5bebuzbee      SpecialMIR2LIR(mir_graph_->GetSpecialCase());
9441fd3346740dfb7f47be9922312b68a4227fada96buzbee    }
9451fd3346740dfb7f47be9922312b68a4227fada96buzbee
9461fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Convert MIR to LIR, etc. */
9471fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_ == NULL) {
9481fd3346740dfb7f47be9922312b68a4227fada96buzbee    MethodMIR2LIR();
9491fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
9501fd3346740dfb7f47be9922312b68a4227fada96buzbee
9511fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Method is not empty */
9521fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_) {
9531fd3346740dfb7f47be9922312b68a4227fada96buzbee    // mark the targets of switch statement case labels
9541fd3346740dfb7f47be9922312b68a4227fada96buzbee    ProcessSwitchTables();
9551fd3346740dfb7f47be9922312b68a4227fada96buzbee
9561fd3346740dfb7f47be9922312b68a4227fada96buzbee    /* Convert LIR into machine code. */
9571fd3346740dfb7f47be9922312b68a4227fada96buzbee    AssembleLIR();
9581fd3346740dfb7f47be9922312b68a4227fada96buzbee
9591fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (cu_->verbose) {
9601fd3346740dfb7f47be9922312b68a4227fada96buzbee      CodegenDump();
9611fd3346740dfb7f47be9922312b68a4227fada96buzbee    }
9621fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
9631fd3346740dfb7f47be9922312b68a4227fada96buzbee}
9641fd3346740dfb7f47be9922312b68a4227fada96buzbee
9651fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() {
9661fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Combine vmap tables - core regs, then fp regs - into vmap_table
96796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  std::vector<uint16_t> raw_vmap_table;
9681fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Core regs may have been inserted out of order - sort first
9691fd3346740dfb7f47be9922312b68a4227fada96buzbee  std::sort(core_vmap_table_.begin(), core_vmap_table_.end());
970193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) {
9711fd3346740dfb7f47be9922312b68a4227fada96buzbee    // Copy, stripping out the phys register sort key
97296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(~(-1 << VREG_NUM_WIDTH) & core_vmap_table_[i]);
9731fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
9741fd3346740dfb7f47be9922312b68a4227fada96buzbee  // If we have a frame, push a marker to take place of lr
9751fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (frame_size_ > 0) {
97696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(INVALID_VREG);
9771fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
9781fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ(__builtin_popcount(core_spill_mask_), 0);
9791fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ(__builtin_popcount(fp_spill_mask_), 0);
9801fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
9811fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Combine vmap tables - core regs, then fp regs. fp regs already sorted
9821fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) {
98396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(fp_vmap_table_[i]);
98496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  }
98596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  UnsignedLeb128EncodingVector vmap_encoder;
98696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  // Prefix the encoded data with its size.
98796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  vmap_encoder.PushBack(raw_vmap_table.size());
988193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  for (uint16_t cur : raw_vmap_table) {
989193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    vmap_encoder.PushBack(cur);
9901fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
9911fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompiledMethod* result =
992193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      new CompiledMethod(*cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_,
993193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                         core_spill_mask_, fp_spill_mask_, encoded_mapping_table_.GetData(),
994193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                         vmap_encoder.GetData(), native_gc_map_);
9951fd3346740dfb7f47be9922312b68a4227fada96buzbee  return result;
9961fd3346740dfb7f47be9922312b68a4227fada96buzbee}
9971fd3346740dfb7f47be9922312b68a4227fada96buzbee
9981fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() {
9991fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Figure out the frame size */
10001fd3346740dfb7f47be9922312b68a4227fada96buzbee  static const uint32_t kAlignMask = kStackAlignment - 1;
10011fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint32_t size = (num_core_spills_ + num_fp_spills_ +
10021fd3346740dfb7f47be9922312b68a4227fada96buzbee                   1 /* filler word */ + cu_->num_regs + cu_->num_outs +
10031fd3346740dfb7f47be9922312b68a4227fada96buzbee                   cu_->num_compiler_temps + 1 /* cur_method* */)
10041fd3346740dfb7f47be9922312b68a4227fada96buzbee                   * sizeof(uint32_t);
10051fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Align and set */
10061fd3346740dfb7f47be9922312b68a4227fada96buzbee  return (size + kAlignMask) & ~(kAlignMask);
10071fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10081fd3346740dfb7f47be9922312b68a4227fada96buzbee
10091fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
10101fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation
10111fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit
10121fd3346740dfb7f47be9922312b68a4227fada96buzbee */
10132ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) {
10141fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_ == NULL) {
10151fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(last_lir_insn_ == NULL);
10161fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = first_lir_insn_ = lir;
10171fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = lir->next = NULL;
10181fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
10191fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_->next = lir;
10201fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = last_lir_insn_;
10211fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->next = NULL;
10221fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = lir;
10231fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10241fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10251fd3346740dfb7f47be9922312b68a4227fada96buzbee
10261fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
10271fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the
10281fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction.
10291fd3346740dfb7f47be9922312b68a4227fada96buzbee *
10301fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir
10311fd3346740dfb7f47be9922312b68a4227fada96buzbee */
10322ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) {
10331fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(current_lir->prev != NULL);
10341fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR *prev_lir = current_lir->prev;
10351fd3346740dfb7f47be9922312b68a4227fada96buzbee
10361fd3346740dfb7f47be9922312b68a4227fada96buzbee  prev_lir->next = new_lir;
10371fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = prev_lir;
10381fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir;
10391fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->prev = new_lir;
10401fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10411fd3346740dfb7f47be9922312b68a4227fada96buzbee
10421fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
10431fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the
10441fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction.
10451fd3346740dfb7f47be9922312b68a4227fada96buzbee *
10461fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next
10471fd3346740dfb7f47be9922312b68a4227fada96buzbee */
10482ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) {
10491fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = current_lir;
10501fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir->next;
10511fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->next = new_lir;
10521fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next->prev = new_lir;
10531fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10541fd3346740dfb7f47be9922312b68a4227fada96buzbee
10557934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
1056