codegen_util.cc revision f29a4244bbc278843237f0ae242de077e093b580
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" 2092cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray#include "gc_map_builder.h" 2196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h" 228d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h" 235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h" 245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h" 25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h" 262730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h" 270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h" 280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h" 292e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko#include "vmap_table.h" 300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 31e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art { 32e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace { 3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */ 3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It> 3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name, 3806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko const Signature& signature, uint32_t size, It first) { 3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (size != 0) { 40107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers std::string line(StringPrintf("\n %s %s%s_%s_table[%u] = {", table_name, 4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko descriptor, name, signature.ToString().c_str(), size)); 4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::replace(line.begin(), line.end(), ';', '_'); 4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t i = 0; i != size; ++i) { 4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko line = StringPrintf(" {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc()); 4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++first; 4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) <<" };\n\n"; 5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} 5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} // anonymous namespace 5406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 552ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) { 564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool res = false; 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.is_const) { 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.wide) { 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 601fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); 614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 621fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 661fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 681fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); 694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 744ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 752ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) { 76b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!inst->flags.use_def_invalid); 77b48819db07f9a0992a72173380c24249d7fc648abuzbee inst->u.m.def_mask = ENCODE_ALL; 781fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC); 79b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK_EQ(safepoint_pc->u.m.def_mask, ENCODE_ALL); 8002031b185b4653e6c72e21f7a51238b903f6d638buzbee} 8102031b185b4653e6c72e21f7a51238b903f6d638buzbee 82252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */ 83252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) { 84252254b130067cd7a5071865e793966871ae0246buzbee if (UNLIKELY(lir == first_lir_insn_)) { 85252254b130067cd7a5071865e793966871ae0246buzbee first_lir_insn_ = lir->next; 86252254b130067cd7a5071865e793966871ae0246buzbee if (lir->next != NULL) { 87252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = NULL; 88252254b130067cd7a5071865e793966871ae0246buzbee } else { 89252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir->next == NULL); 90252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir == last_lir_insn_); 91252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = NULL; 92252254b130067cd7a5071865e793966871ae0246buzbee } 93252254b130067cd7a5071865e793966871ae0246buzbee } else if (lir == last_lir_insn_) { 94252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = lir->prev; 95252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = NULL; 96252254b130067cd7a5071865e793966871ae0246buzbee } else if ((lir->prev != NULL) && (lir->next != NULL)) { 97252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = lir->next; 98252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = lir->prev; 99252254b130067cd7a5071865e793966871ae0246buzbee } 100252254b130067cd7a5071865e793966871ae0246buzbee} 101252254b130067cd7a5071865e793966871ae0246buzbee 102cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */ 103df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) { 104fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop = true; 105252254b130067cd7a5071865e793966871ae0246buzbee if (!cu_->verbose) { 106252254b130067cd7a5071865e793966871ae0246buzbee UnlinkLIR(lir); 107252254b130067cd7a5071865e793966871ae0246buzbee } 108cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee} 109cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee 1102ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) { 111fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint64_t *mask_ptr; 112f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom uint64_t mask = ENCODE_MEM; 1131fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE)); 114b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 115fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_load) { 116b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.use_mask; 117a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 118b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.def_mask; 119a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 120a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Clear out the memref flags */ 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr &= ~mask; 122a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* ..and then add back the one we need */ 123fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee switch (mem_type) { 124a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kLiteral: 125fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(is_load); 126fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_LITERAL; 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kDalvikReg: 129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_DALVIK_REG; 130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kHeapRef: 132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_HEAP_REF; 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kMustNotAlias: 135a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Currently only loads can be marked as kMustNotAlias */ 1361fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE)); 137fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_MUST_NOT_ALIAS; 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 140fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(FATAL) << "Oat: invalid memref kind - " << mem_type; 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 14231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 14331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 14431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 145b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack. 14631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 1471fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, 1482ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is64bit) { 1491fd3346740dfb7f47be9922312b68a4227fada96buzbee SetMemRefType(lir, is_load, kDalvikReg); 15031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 152fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit 153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * access. 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 155b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit); 15631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 15731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 15831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 1595de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros 1605de3494e4297c0d480409da3fecee39173f1d4e1buzbee */ 1615de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X) 1625de3494e4297c0d480409da3fecee39173f1d4e1buzbee 1635de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */ 1642ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) { 165a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset = lir->offset; 166a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int dest = lir->operands[0]; 1671fd3346740dfb7f47be9922312b68a4227fada96buzbee const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops)); 168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Handle pseudo-ops individually, and all regular insns as a group */ 170a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (lir->opcode) { 171a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodEntry: 172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- method entry " 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodExit: 176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- Method_Exit"; 177a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoBarrier: 179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- BARRIER"; 180a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEntryBlock: 182a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest; 183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 184a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoDalvikByteCodeBoundary: 1854ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (lir->operands[0] == 0) { 1860d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 1870d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string")); 1884ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- dalvik offset: 0x" << std::hex 1900b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << lir->dalvik_offset << " @ " 1910b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0])); 192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoExitBlock: 194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest; 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoPseudoAlign4: 197fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex 198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << offset << "): .align4"; 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEHBlockLabel: 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Exception_Handling:"; 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoTargetLabel: 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoNormalBlockLabel: 205cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":"; 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoThrowTarget: 208cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":"; 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoIntrinsicRetry: 211cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":"; 212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoSuspendTarget: 214cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":"; 215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 2168320f3867c02bae9bef6cdab267820cb7b412781buzbee case kPseudoSafepointPC: 217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 2188320f3867c02bae9bef6cdab267820cb7b412781buzbee break; 219a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee case kPseudoExportedPC: 220fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 221a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee break; 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoCaseLabel: 223cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x" 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << lir->operands[0] << "|" << std::dec << 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->operands[0]; 226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 228fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lir->flags.is_nop && !dump_nop) { 229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2311fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode), 23202031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 2331fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode), 23402031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 235107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers LOG(INFO) << StringPrintf("%5p: %-9s%s%s", 236107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers base_addr + offset, 237a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op_name.c_str(), op_operands.c_str(), 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop ? "(nop)" : ""); 239a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 241a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 243b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) { 244b48819db07f9a0992a72173380c24249d7fc648abuzbee DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.use_mask, "use")); 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 246b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) { 247b48819db07f9a0992a72173380c24249d7fc648abuzbee DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.def_mask, "def")); 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2495de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2505de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2512ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() { 252da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps(); 253fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_regs; i++) { 2541fd3346740dfb7f47be9922312b68a4227fada96buzbee PromotionMap v_reg_map = promotion_map_[i]; 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf; 256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (v_reg_map.fp_location == kLocPhysReg) { 257091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee StringAppendF(&buf, " : s%d", RegStorage::RegNum(v_reg_map.FpReg)); 258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2599c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee 260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf3; 2611fd3346740dfb7f47be9922312b68a4227fada96buzbee if (i < cu_->num_dalvik_registers) { 262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee StringAppendF(&buf3, "%02d", i); 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (i == mir_graph_->GetMethodSReg()) { 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf3 = "Method*"; 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2661fd3346740dfb7f47be9922312b68a4227fada96buzbee StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers); 2675de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 269a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(), 270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee v_reg_map.core_location == kLocPhysReg ? 271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee "r" : "SP+", v_reg_map.core_location == kLocPhysReg ? 2721fd3346740dfb7f47be9922312b68a4227fada96buzbee v_reg_map.core_reg : SRegOffset(i), 273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.c_str()); 274a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2755de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2765de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2777a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbeevoid Mir2Lir::UpdateLIROffsets() { 2787a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee // Only used for code listings. 2797a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee size_t offset = 0; 2807a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) { 2817a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee lir->offset = offset; 2827a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) { 2837a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += GetInsnSize(lir); 2847a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } else if (lir->opcode == kPseudoPseudoAlign4) { 2857a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += (offset & 0x2); 2867a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 2877a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 2887a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee} 2897a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee 2905de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */ 2912ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() { 292a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Dumping LIR insns for " 2931fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 294fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lir_insn; 2951fd3346740dfb7f47be9922312b68a4227fada96buzbee int insns_size = cu_->code_item->insns_size_in_code_units_; 2961fd3346740dfb7f47be9922312b68a4227fada96buzbee 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs; 2981fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Ins : " << cu_->num_ins; 2991fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Outs : " << cu_->num_outs; 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "CoreSpills : " << num_core_spills_; 3011fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "FPSpills : " << num_fp_spills_; 302da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru LOG(INFO) << "CompilerTemps : " << mir_graph_->GetNumUsedCompilerTemps(); 3031fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Frame size : " << frame_size_; 3041fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "code size is " << total_size_ << 305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee " bytes, Dalvik size is " << insns_size * 2; 306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "expansion factor: " 3071fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2); 3081fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpPromotionMap(); 3097a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee UpdateLIROffsets(); 3101fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) { 3111fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir_insn, 0); 312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 3131fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) { 314fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset, 315fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir_insn->operands[0]); 316a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 318a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee const DexFile::MethodId& method_id = 3191fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->dex_file->GetMethodId(cu_->method_idx); 320d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const Signature signature = cu_->dex_file->GetMethodSignature(method_id); 321d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* name = cu_->dex_file->GetMethodName(method_id); 322d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id)); 323a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 324a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee // Dump mapping tables 32506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!encoded_mapping_table_.empty()) { 32606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 32706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, 32806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.PcToDexSize(), table.PcToDexBegin()); 32906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, 33006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.DexToPcSize(), table.DexToPcBegin()); 33106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 3325de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3335de3494e4297c0d480409da3fecee39173f1d4e1buzbee 33431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 33531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match 33631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0). 33731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 3382ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) { 339fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 340fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta) 341fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return data_target; 342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 343a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 344a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 34531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 34631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 34731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */ 3482ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) { 349fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool lo_match = false; 350fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lo_target = NULL; 351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 352fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lo_match && (data_target->operands[0] == val_hi)) { 3534ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee // Record high word in case we need to expand this later. 3544ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee lo_target->operands[1] = val_hi; 355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return lo_target; 35631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 357fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = false; 358fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (data_target->operands[0] == val_lo) { 359fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = true; 360fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_target = data_target; 361a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 362fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 363a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 364a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 36531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 36631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 36731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 36831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or 36931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams. 37031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 37131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 3724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */ 3732ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) { 374a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Add the constant to the literal pool */ 375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (constant_list_p) { 37683cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocData)); 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->operands[0] = value; 378fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->next = *constant_list_p; 379fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *constant_list_p = new_value; 380b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_ += sizeof(value); 381fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return new_value; 382a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 383a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 38431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 38531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 38631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */ 3872ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) { 3881fd3346740dfb7f47be9922312b68a4227fada96buzbee AddWordData(constant_list_p, val_hi); 3891fd3346740dfb7f47be9922312b68a4227fada96buzbee return AddWordData(constant_list_p, val_lo); 39031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 39131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 3922da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void Push32(std::vector<uint8_t>&buf, int data) { 393df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back(data & 0xff); 394df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 8) & 0xff); 395df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 16) & 0xff); 396df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 24) & 0xff); 397e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 398e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3992da882315a61072664f7ce3c212307342e907207Andreas Gampe// Push 8 bytes on 64-bit target systems; 4 on 32-bit target systems. 4002da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void PushPointer(std::vector<uint8_t>&buf, const void* pointer, bool target64) { 4012da882315a61072664f7ce3c212307342e907207Andreas Gampe uint64_t data = reinterpret_cast<uintptr_t>(pointer); 4022da882315a61072664f7ce3c212307342e907207Andreas Gampe if (target64) { 4032da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, data & 0xFFFFFFFF); 4042da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, (data >> 32) & 0xFFFFFFFF); 4050d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } else { 4062da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, static_cast<uint32_t>(data)); 4070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 4080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 4090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 410aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) { 411a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (buf.size() < offset) { 412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.push_back(0); 413a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 414e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 415e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 416e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */ 4172ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() { 4181fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, data_offset_); 4191fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_lir = literal_list_; 420fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 4212da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, data_lir->operands[0]); 422fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 423a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 424a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Push code and method literals, record offsets for the compiler to patch. 4251fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = code_literal_list_; 426fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 42749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 42849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 42949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4301fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddCodePatch(cu_->dex_file, 4318b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4328b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4338b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 43449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 43549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 43649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4378b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 43849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 44049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 441fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 442137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers } 4431fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = method_literal_list_; 444fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 44549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 44649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 44749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4481fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddMethodPatch(cu_->dex_file, 4498b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4508b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4518b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 45249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 45349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 45449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4558b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 45649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4570d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 45849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 461be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // Push class literals. 462be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = class_literal_list_; 463be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi while (data_lir != NULL) { 46449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 465be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->compiler_driver->AddClassPatch(cu_->dex_file, 466be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->class_def_idx, 467be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->method_idx, 46849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 469be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi code_buffer_.size()); 47049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::TypeId& target_method_id = cu_->dex_file->GetTypeId(target_method_idx); 471be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // unique value based on target to ensure code deduplication works 47249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 473be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = NEXT_LIR(data_lir); 474be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi } 475e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 476e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 477e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */ 4782ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() { 479862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 480a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 481862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 482fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 4831fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 484a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 485a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * For Arm, our reference point is the address of the bx 486a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * instruction that does the launch, so we have to subtract 487a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the auto pc-advance. For other targets the reference point 488a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * is a label, so we can use the offset as-is. 489a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bx_offset = INVALID_OFFSET; 4911fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (cu_->instruction_set) { 492b046e16d8b8da318d6055f9308950131f1255e08buzbee case kThumb2: 493b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(tab_rec->anchor->flags.fixup != kFixupNone); 494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset + 4; 495b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 496b046e16d8b8da318d6055f9308950131f1255e08buzbee case kX86: 4976a58cb16d803c9a7b3a75ccac8be19dd9d4e520dDmitry Petrochenko case kX86_64: 498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = 0; 499b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 500b046e16d8b8da318d6055f9308950131f1255e08buzbee case kMips: 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset; 502b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 5031fd3346740dfb7f47be9922312b68a4227fada96buzbee default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set; 504b046e16d8b8da318d6055f9308950131f1255e08buzbee } 5051fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 506fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset; 507a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 508fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 5090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2])); 510fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 511fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5121fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 513a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] key: 0x" 514a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << keys[elems] << ", disp: 0x" 515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 516e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5172da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, keys[elems]); 5182da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, 519fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->targets[elems]->offset - bx_offset); 520a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 521a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 522fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 523a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 524fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 525fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5261fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 527a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] disp: 0x" 528a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 529e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5302da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, tab_rec->targets[elems]->offset - bx_offset); 531a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 532e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 533a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 534e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 535e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 536e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */ 5372ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() { 538862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 539a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 540862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 541fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5421fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 543fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < (tab_rec->size + 1) / 2; i++) { 544df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back(tab_rec->table[i] & 0xFF); 545df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF); 546e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 547a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 548e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 549e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 5500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) { 55102c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; lir != NULL; lir = lir->next) { 552a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->offset = offset; 553a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset += 4; 554a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 555a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 556e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 557e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 558ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogersstatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset, 559ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int element_size) { 5600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Align to natural pointer size. 5610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset = (offset + (element_size - 1)) & ~(element_size - 1); 5620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee for (; lir != NULL; lir = lir->next) { 5630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->offset = offset; 5640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset += element_size; 5650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 5660d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee return offset; 5670d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 5680d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 5696459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry 5702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() { 57106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 57206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::vector<uint32_t> dex_pcs; 57306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.reserve(table.DexToPcSize()); 57406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) { 57506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.push_back(it.DexPc()); 57606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 57706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_. 57806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::sort(dex_pcs.begin(), dex_pcs.end()); 57906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5806459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee bool success = true; 58106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko auto it = dex_pcs.begin(), end = dex_pcs.end(); 58206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t dex_pc : mir_graph_->catches_) { 58306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko while (it != end && *it < dex_pc) { 58406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it; 58506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 5866459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 5876459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 58806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (it == end || *it > dex_pc) { 58906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc; 5906459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 59106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } else { 59206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 5936459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 5946459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 5956459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee if (!success) { 5961fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 5971fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: " 59806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko << table.DexToPcSize(); 5996459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6006459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee return success; 6016459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee} 6026459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee 603311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 6042ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() { 6051e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_data_size = 0u; 6061e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_entries = 0u; 6071e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_offset = 0u; 6081e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_dalvik_offset = 0u; 6091e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_data_size = 0u; 6101e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_entries = 0u; 6111e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_offset = 0u; 6121e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_dalvik_offset = 0u; 6131fd3346740dfb7f47be9922312b68a4227fada96buzbee for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 614fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 6151e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_entries += 1; 6161e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 6171e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset); 6181e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6191e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 6201e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = tgt_lir->offset; 6211e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 622a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee } 623fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 6241e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_entries += 1; 6251e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 6261e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset); 6271e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6281e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 6291e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_offset = tgt_lir->offset; 6301e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 631e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 632a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6331e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6341e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t total_entries = pc2dex_entries + dex2pc_entries; 6351e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries); 6361e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size; 63706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko encoded_mapping_table_.resize(data_size); 63806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos = &encoded_mapping_table_[0]; 63906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, total_entries); 64006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries); 64106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size); 64206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos2 = write_pos + pc2dex_data_size; 6431e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6441e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = 0u; 6451e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = 0u; 64606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = 0u; 64706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = 0u; 64806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 64906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 65006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 65106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset); 65206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) - 65306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 65406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_offset = tgt_lir->offset; 65506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 65606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 65706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 65806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 65906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset); 66006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) - 66106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 66206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = tgt_lir->offset; 66306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 66406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 6651e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko } 66606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), 66706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko hdr_data_size + pc2dex_data_size); 66806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size); 6691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 67096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (kIsDebugBuild) { 67106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(VerifyCatchEntries()); 67206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 67396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // Verify the encoded table holds the expected data. 67406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 67596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.TotalSize(), total_entries); 67696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.PcToDexSize(), pc2dex_entries); 6771e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it = table.PcToDexBegin(); 6781e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it2 = table.DexToPcBegin(); 67906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 68006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 68106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it.NativePcOffset()); 68206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc()); 68306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 68406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 68506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 68606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it2.NativePcOffset()); 68706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc()); 68806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it2; 68906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 69096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 69106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(it == table.PcToDexEnd()); 6921e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko CHECK(it2 == table.DexToPcEnd()); 693311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 694e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 695e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 6961fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() { 69706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(!encoded_mapping_table_.empty()); 69806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable mapping_table(&encoded_mapping_table_[0]); 6990c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t max_native_offset = 0; 70006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 70106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 7020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers if (native_offset > max_native_offset) { 7030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers max_native_offset = native_offset; 7040c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 70651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReference method_ref(cu_->dex_file, cu_->method_idx); 7072730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko const std::vector<uint8_t>& gc_map_raw = 7082730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap(); 7092730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]); 7102730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize()); 7110c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Compute native offset to references size. 71292cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray GcMapBuilder native_gc_map_builder(&native_gc_map_, 71392cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray mapping_table.PcToDexSize(), 71492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray max_native_offset, dex_gc_map.RegWidth()); 7150c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 71606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 71706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 71806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t dex_pc = it.DexPc(); 7190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false); 720f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc << 721f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison ": " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 722a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee native_gc_map_builder.AddEntry(native_offset, references); 7230c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7240c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers} 7250c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 726e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */ 7270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) { 7281fd3346740dfb7f47be9922312b68a4227fada96buzbee offset = AssignLiteralOffsetCommon(literal_list_, offset); 729ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int ptr_size = GetInstructionSetPointerSize(cu_->instruction_set); 730ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size); 731ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size); 732ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size); 733a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 734e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 735e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) { 737862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 738a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 7390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 740fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 741fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 742fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 743fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * (sizeof(int) * 2); 744a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 745fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 746a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 747fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * sizeof(int); 748e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 749a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 750a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 751e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 752e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7530d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) { 754862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 755a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 756862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 757fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 758fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 759fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->size; 760a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // word align 761a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset = (offset + 3) & ~3; 762a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 763a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 764e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 765e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 76631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 76731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik 768b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block 769b48819db07f9a0992a72173380c24249d7fc648abuzbee * label. The selected label will be used to fix up the case 770252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase. All resource flags 771252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion. KeyVal is just there for debugging. 77231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 7730d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) { 774252254b130067cd7a5071865e793966871ae0246buzbee LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id]; 775b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* res = boundary_lir; 776b48819db07f9a0992a72173380c24249d7fc648abuzbee if (cu_->verbose) { 777b48819db07f9a0992a72173380c24249d7fc648abuzbee // Only pay the expense if we're pretty-printing. 77883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR)); 779b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->dalvik_offset = vaddr; 780b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->opcode = kPseudoCaseLabel; 781b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->operands[0] = keyVal; 782b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->flags.fixup = kFixupLabel; 783b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!new_label->flags.use_def_invalid); 784b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->u.m.def_mask = ENCODE_ALL; 785b48819db07f9a0992a72173380c24249d7fc648abuzbee InsertLIRAfter(boundary_lir, new_label); 786b48819db07f9a0992a72173380c24249d7fc648abuzbee res = new_label; 787b48819db07f9a0992a72173380c24249d7fc648abuzbee } 788b48819db07f9a0992a72173380c24249d7fc648abuzbee return res; 78931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 79031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 7910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 792fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 7930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 7940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]); 795a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 796fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 797a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 7981fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key); 799a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 80031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 80131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8020d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 803fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 805a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8060d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 808a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8091fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]); 810a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 81131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 81231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8132ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() { 814862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 815a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 816862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable *tab_rec = iterator.Next(); 817fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 818fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) { 8191fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkPackedCaseLabels(tab_rec); 820fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 8211fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkSparseCaseLabels(tab_rec); 822a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 823a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Invalid switch table"; 82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 825a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 82631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 82731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8282ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) { 829a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 830a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sparse switch data format: 831a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0200 magic value 832a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table; > 0 833a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 834a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 835a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 836a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (2+size*4) 16-bit code units. 837a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 838eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 839a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 842a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Sparse switch table - ident:0x" << std::hex << ident 843a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << ", entries: " << std::dec << entries; 844a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 845a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Key[" << keys[i] << "] -> 0x" << std::hex << targets[i]; 846a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 84831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8492ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) { 850a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 851a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Packed switch data format: 852a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0100 magic value 853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table 854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int first_key first (and lowest) switch case value 855a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 856a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 857a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (4+size*2) 16-bit code units. 858a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 859eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 8600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]); 861a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 862fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 863a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident 864fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee << ", entries: " << std::dec << entries << ", low_key: " << low_key; 865a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 866fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << " Key[" << (i + low_key) << "] -> 0x" << std::hex 867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << targets[i]; 868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 870e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 871252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */ 8720d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) { 8730d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 8740d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str))); 875d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee} 876e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 8772ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) { 878e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee bool is_taken; 879e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee switch (opcode) { 880e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQ: is_taken = (src1 == src2); break; 881e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NE: is_taken = (src1 != src2); break; 882e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LT: is_taken = (src1 < src2); break; 883e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GE: is_taken = (src1 >= src2); break; 884e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GT: is_taken = (src1 > src2); break; 885e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LE: is_taken = (src1 <= src2); break; 886e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQZ: is_taken = (src1 == 0); break; 887e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NEZ: is_taken = (src1 != 0); break; 888e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LTZ: is_taken = (src1 < 0); break; 889e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GEZ: is_taken = (src1 >= 0); break; 890e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GTZ: is_taken = (src1 > 0); break; 891e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LEZ: is_taken = (src1 <= 0); break; 892e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee default: 893e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee LOG(FATAL) << "Unexpected opcode " << opcode; 894e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee is_taken = false; 895e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee } 896e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return is_taken; 897e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 898e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 8994ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1 9001fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) { 9014ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee ConditionCode res; 9024ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee switch (before) { 9034ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondEq: res = kCondEq; break; 9044ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondNe: res = kCondNe; break; 9054ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLt: res = kCondGt; break; 9064ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGt: res = kCondLt; break; 9074ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLe: res = kCondGe; break; 9084ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGe: res = kCondLe; break; 9094ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee default: 9104ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res = static_cast<ConditionCode>(0); 9114ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LOG(FATAL) << "Unexpected ccode " << before; 9124ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9134ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 9144ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 9154ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 916a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir MarkoConditionCode Mir2Lir::NegateComparison(ConditionCode before) { 917a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko ConditionCode res; 918a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko switch (before) { 919a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondEq: res = kCondNe; break; 920a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondNe: res = kCondEq; break; 921a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLt: res = kCondGe; break; 922a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGt: res = kCondLe; break; 923a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLe: res = kCondGt; break; 924a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGe: res = kCondLt; break; 925a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko default: 926a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko res = static_cast<ConditionCode>(0); 927a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko LOG(FATAL) << "Unexpected ccode " << before; 928a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko } 929a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko return res; 930a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko} 931a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko 932862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc 933862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 9346282dc12440a2072dc06a616160027ff21bd895eIan Rogers : Backend(arena), 9356282dc12440a2072dc06a616160027ff21bd895eIan Rogers literal_list_(NULL), 9361fd3346740dfb7f47be9922312b68a4227fada96buzbee method_literal_list_(NULL), 937be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi class_literal_list_(NULL), 9381fd3346740dfb7f47be9922312b68a4227fada96buzbee code_literal_list_(NULL), 939b48819db07f9a0992a72173380c24249d7fc648abuzbee first_fixup_(NULL), 9401fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 9411fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_(mir_graph), 942862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee switch_tables_(arena, 4, kGrowableArraySwitchTables), 943862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee fill_array_data_(arena, 4, kGrowableArrayFillArrayData), 944bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee tempreg_info_(arena, 20, kGrowableArrayMisc), 945091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reginfo_map_(arena, RegStorage::kMaxRegs, kGrowableArrayMisc), 9460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee pointer_storage_(arena, 128, kGrowableArrayMisc), 9471fd3346740dfb7f47be9922312b68a4227fada96buzbee data_offset_(0), 9481fd3346740dfb7f47be9922312b68a4227fada96buzbee total_size_(0), 9491fd3346740dfb7f47be9922312b68a4227fada96buzbee block_label_list_(NULL), 950d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee promotion_map_(NULL), 951862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee current_dalvik_offset_(0), 952b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_(0), 953862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee reg_pool_(NULL), 9541fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_(0), 9551fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_(0), 9561fd3346740dfb7f47be9922312b68a4227fada96buzbee num_fp_spills_(0), 9571fd3346740dfb7f47be9922312b68a4227fada96buzbee frame_size_(0), 9581fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_(0), 9591fd3346740dfb7f47be9922312b68a4227fada96buzbee fp_spill_mask_(0), 9601fd3346740dfb7f47be9922312b68a4227fada96buzbee first_lir_insn_(NULL), 961bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison last_lir_insn_(NULL), 962bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison slow_paths_(arena, 32, kGrowableArraySlowPaths) { 9630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Reserve pointer id 0 for NULL. 9640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee size_t null_idx = WrapPointer(NULL); 9650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_idx, 0U); 9661fd3346740dfb7f47be9922312b68a4227fada96buzbee} 9671fd3346740dfb7f47be9922312b68a4227fada96buzbee 9681fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() { 969a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("RegisterAllocation"); 9701fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitializeRegAlloc(); // Needs to happen after SSA naming 9711fd3346740dfb7f47be9922312b68a4227fada96buzbee 9721fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Allocate Registers using simple local allocation scheme */ 9731fd3346740dfb7f47be9922312b68a4227fada96buzbee SimpleRegAlloc(); 9741fd3346740dfb7f47be9922312b68a4227fada96buzbee 9753bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* First try the custom light codegen for special cases. */ 9765816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr); 9773bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru bool special_worked = cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file) 9785816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko ->GenSpecial(this, cu_->method_idx); 9791fd3346740dfb7f47be9922312b68a4227fada96buzbee 9803bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* Take normal path for converting MIR to LIR only if the special codegen did not succeed. */ 9813bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (special_worked == false) { 9821fd3346740dfb7f47be9922312b68a4227fada96buzbee MethodMIR2LIR(); 9831fd3346740dfb7f47be9922312b68a4227fada96buzbee } 9841fd3346740dfb7f47be9922312b68a4227fada96buzbee 9851fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Method is not empty */ 9861fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_) { 9871fd3346740dfb7f47be9922312b68a4227fada96buzbee // mark the targets of switch statement case labels 9881fd3346740dfb7f47be9922312b68a4227fada96buzbee ProcessSwitchTables(); 9891fd3346740dfb7f47be9922312b68a4227fada96buzbee 9901fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Convert LIR into machine code. */ 9911fd3346740dfb7f47be9922312b68a4227fada96buzbee AssembleLIR(); 9921fd3346740dfb7f47be9922312b68a4227fada96buzbee 9931fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 9941fd3346740dfb7f47be9922312b68a4227fada96buzbee CodegenDump(); 9951fd3346740dfb7f47be9922312b68a4227fada96buzbee } 9961fd3346740dfb7f47be9922312b68a4227fada96buzbee } 9971fd3346740dfb7f47be9922312b68a4227fada96buzbee} 9981fd3346740dfb7f47be9922312b68a4227fada96buzbee 9991fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() { 10002e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Combine vmap tables - core regs, then fp regs - into vmap_table. 10012e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko Leb128EncodingVector vmap_encoder; 10021fd3346740dfb7f47be9922312b68a4227fada96buzbee if (frame_size_ > 0) { 10032e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Prefix the encoded data with its size. 10042e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size(); 10052e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.Reserve(size + 1u); // All values are likely to be one byte in ULEB128 (<128). 10062e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(size); 10072e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Core regs may have been inserted out of order - sort first. 10082e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); 10092e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { 10102e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Copy, stripping out the phys register sort key. 10112e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned( 10122e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment)); 10132e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10142e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Push a marker to take place of lr. 10152e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker); 10162e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // fp regs already sorted. 10172e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { 10182e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment); 10192e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10201fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10218194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(core_spill_mask_), 0); 10228194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(fp_spill_mask_), 0); 10232e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(core_vmap_table_.size(), 0u); 10242e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(fp_vmap_table_.size(), 0u); 10252e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(0u); // Size is 0. 10261fd3346740dfb7f47be9922312b68a4227fada96buzbee } 1027ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 1028ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell UniquePtr<std::vector<uint8_t> > cfi_info(ReturnCallFrameInformation()); 10291fd3346740dfb7f47be9922312b68a4227fada96buzbee CompiledMethod* result = 1030193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier new CompiledMethod(*cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_, 103106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko core_spill_mask_, fp_spill_mask_, encoded_mapping_table_, 1032d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison vmap_encoder.GetData(), native_gc_map_, cfi_info.get()); 10331fd3346740dfb7f47be9922312b68a4227fada96buzbee return result; 10341fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10351fd3346740dfb7f47be9922312b68a4227fada96buzbee 1036da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const { 1037da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Chose a reasonably small value in order to contain stack growth. 1038da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Backends that are smarter about spill region can return larger values. 1039da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru const size_t max_compiler_temps = 10; 1040da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return max_compiler_temps; 1041da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1042da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 1043da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() { 1044da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // By default assume that the Mir2Lir will need one slot for each temporary. 1045da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // If the backend can better determine temps that have non-overlapping ranges and 1046da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // temps that do not need spilled, it can actually provide a small region. 1047da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t)); 1048da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1049da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 10501fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() { 10511fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Figure out the frame size */ 10521fd3346740dfb7f47be9922312b68a4227fada96buzbee static const uint32_t kAlignMask = kStackAlignment - 1; 1053f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko uint32_t size = num_core_spills_ * GetBytesPerGprSpillLocation(cu_->instruction_set) 1054f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + num_fp_spills_ * GetBytesPerFprSpillLocation(cu_->instruction_set) 1055f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + sizeof(uint32_t) // Filler. 1056f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + (cu_->num_regs + cu_->num_outs) * sizeof(uint32_t) 1057f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + GetNumBytesForCompilerTempSpillRegion(); 10581fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Align and set */ 10591fd3346740dfb7f47be9922312b68a4227fada96buzbee return (size + kAlignMask) & ~(kAlignMask); 10601fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10611fd3346740dfb7f47be9922312b68a4227fada96buzbee 10621fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 10631fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation 10641fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit 10651fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 10662ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) { 10671fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_ == NULL) { 10681fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(last_lir_insn_ == NULL); 10691fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = first_lir_insn_ = lir; 10701fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = lir->next = NULL; 10711fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10721fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_->next = lir; 10731fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = last_lir_insn_; 10741fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->next = NULL; 10751fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = lir; 10761fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10771fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10781fd3346740dfb7f47be9922312b68a4227fada96buzbee 10791fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 10801fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the 10811fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 10821fd3346740dfb7f47be9922312b68a4227fada96buzbee * 10831fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir 10841fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 10852ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) { 10861fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(current_lir->prev != NULL); 10871fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR *prev_lir = current_lir->prev; 10881fd3346740dfb7f47be9922312b68a4227fada96buzbee 10891fd3346740dfb7f47be9922312b68a4227fada96buzbee prev_lir->next = new_lir; 10901fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = prev_lir; 10911fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir; 10921fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->prev = new_lir; 10931fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10941fd3346740dfb7f47be9922312b68a4227fada96buzbee 10951fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 10961fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the 10971fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 10981fd3346740dfb7f47be9922312b68a4227fada96buzbee * 10991fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next 11001fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11012ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) { 11021fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = current_lir; 11031fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir->next; 11041fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->next = new_lir; 11051fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next->prev = new_lir; 11061fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11071fd3346740dfb7f47be9922312b68a4227fada96buzbee 11084708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) { 11094708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (x & (x - 1)) == 0; 11104708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11114708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11124708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'. 11134708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) { 11144708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell int bit_posn = 0; 11154708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 0xf) == 0) { 11164708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn += 4; 11174708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 4; 11184708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11194708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 1) == 0) { 11204708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn++; 11214708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 1; 11224708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11234708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return bit_posn; 11244708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11254708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11264708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) { 11274708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_src.wide); 11284708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_dest.wide); 11294708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1); 11304708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11314708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11322700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, 1133766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell int offset, int check_value, LIR* target) { 1134766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell // Handle this for architectures that can't compare to memory. 1135695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee Load32Disp(base_reg, offset, temp_reg); 1136766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target); 1137766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 1138766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 1139766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 1140bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allisonvoid Mir2Lir::AddSlowPath(LIRSlowPath* slowpath) { 1141bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison slow_paths_.Insert(slowpath); 1142bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison} 114355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 114449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadCodeAddress(const MethodReference& target_method, InvokeType type, 114549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 114649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao int target_method_idx = target_method.dex_method_index; 114749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao LIR* data_target = ScanLiteralPool(code_literal_list_, target_method_idx, 0); 114855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 114949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target = AddWordData(&code_literal_list_, target_method_idx); 115049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 115149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 115255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 115355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg), data_target); 115455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 115555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 115655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 115755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 115849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type, 115949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 116049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao int target_method_idx = target_method.dex_method_index; 116149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao LIR* data_target = ScanLiteralPool(method_literal_list_, target_method_idx, 0); 116255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 116349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target = AddWordData(&method_literal_list_, target_method_idx); 116449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 116549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 116655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 116755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg), data_target); 116855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 116955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 117055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 117155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 117255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendellvoid Mir2Lir::LoadClassType(uint32_t type_idx, SpecialTargetRegister symbolic_reg) { 117355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell // Use the literal pool and a PC-relative load from a data word. 117455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0); 117555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == nullptr) { 117655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell data_target = AddWordData(&class_literal_list_, type_idx); 117755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 117855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg), data_target); 117955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 118055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 118155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 1182ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstd::vector<uint8_t>* Mir2Lir::ReturnCallFrameInformation() { 1183ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Default case is to do nothing. 1184ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell return nullptr; 1185ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 1186ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 11872700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) { 11882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee loc.wide = false; 1189091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.location == kLocPhysReg) { 1190091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.reg.IsPair()) { 1191091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee loc.reg = loc.reg.GetLow(); 1192091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } else { 1193091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // FIXME: temp workaround. 1194091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Issue here: how do we narrow to a 32-bit value in 64-bit container? 1195091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // Probably the wrong thing to narrow the RegStorage container here. That 1196091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // should be a target decision. At the RegLocation level, we're only 1197091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // modifying the view of the Dalvik value - this is orthogonal to the storage 1198091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // container size. Consider this a temp workaround. 1199091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(loc.reg.IsDouble()); 1200091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee loc.reg = loc.reg.DoubleToLowSingle(); 1201091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } 12022700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee } 12032700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return loc; 12042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee} 12052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee 12067934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 1207