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