codegen_util.cc revision d69835d841cb7663faaa2f1996e73e8c0b3f6d76
1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* 2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project 3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License. 6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at 7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * http://www.apache.org/licenses/LICENSE-2.0 9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software 11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and 14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License. 15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h" 184f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h" 2096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h" 218d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h" 225816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h" 235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h" 24c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h" 252730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h" 260c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h" 270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h" 280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 29e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art { 30e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace { 3206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */ 3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It> 3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name, 3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko const Signature& signature, uint32_t size, It first) { 3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (size != 0) { 38107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers std::string line(StringPrintf("\n %s %s%s_%s_table[%u] = {", table_name, 3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko descriptor, name, signature.ToString().c_str(), size)); 4006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::replace(line.begin(), line.end(), ';', '_'); 4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t i = 0; i != size; ++i) { 4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko line = StringPrintf(" {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc()); 4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++first; 4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) <<" };\n\n"; 4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} 5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} // anonymous namespace 5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) { 544ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool res = false; 554ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.is_const) { 564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.wide) { 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 581fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 601fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); 614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 641fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 661fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) { 74b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!inst->flags.use_def_invalid); 75b48819db07f9a0992a72173380c24249d7fc648abuzbee inst->u.m.def_mask = ENCODE_ALL; 761fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC); 77b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK_EQ(safepoint_pc->u.m.def_mask, ENCODE_ALL); 7802031b185b4653e6c72e21f7a51238b903f6d638buzbee} 7902031b185b4653e6c72e21f7a51238b903f6d638buzbee 809b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogersbool Mir2Lir::FastInstance(uint32_t field_idx, bool is_put, int* field_offset, bool* is_volatile) { 811fd3346740dfb7f47be9922312b68a4227fada96buzbee return cu_->compiler_driver->ComputeInstanceFieldInfo( 829b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogers field_idx, mir_graph_->GetCurrentDexCompilationUnit(), is_put, field_offset, is_volatile); 8302031b185b4653e6c72e21f7a51238b903f6d638buzbee} 8402031b185b4653e6c72e21f7a51238b903f6d638buzbee 85252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */ 86252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) { 87252254b130067cd7a5071865e793966871ae0246buzbee if (UNLIKELY(lir == first_lir_insn_)) { 88252254b130067cd7a5071865e793966871ae0246buzbee first_lir_insn_ = lir->next; 89252254b130067cd7a5071865e793966871ae0246buzbee if (lir->next != NULL) { 90252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = NULL; 91252254b130067cd7a5071865e793966871ae0246buzbee } else { 92252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir->next == NULL); 93252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir == last_lir_insn_); 94252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = NULL; 95252254b130067cd7a5071865e793966871ae0246buzbee } 96252254b130067cd7a5071865e793966871ae0246buzbee } else if (lir == last_lir_insn_) { 97252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = lir->prev; 98252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = NULL; 99252254b130067cd7a5071865e793966871ae0246buzbee } else if ((lir->prev != NULL) && (lir->next != NULL)) { 100252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = lir->next; 101252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = lir->prev; 102252254b130067cd7a5071865e793966871ae0246buzbee } 103252254b130067cd7a5071865e793966871ae0246buzbee} 104252254b130067cd7a5071865e793966871ae0246buzbee 105cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */ 106df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) { 107fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop = true; 108252254b130067cd7a5071865e793966871ae0246buzbee if (!cu_->verbose) { 109252254b130067cd7a5071865e793966871ae0246buzbee UnlinkLIR(lir); 110252254b130067cd7a5071865e793966871ae0246buzbee } 111cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee} 112cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee 1132ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) { 114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint64_t *mask_ptr; 115f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom uint64_t mask = ENCODE_MEM; 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE)); 117b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 118fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_load) { 119b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.use_mask; 120a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 121b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.def_mask; 122a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Clear out the memref flags */ 124fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr &= ~mask; 125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* ..and then add back the one we need */ 126fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee switch (mem_type) { 127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kLiteral: 128fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(is_load); 129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_LITERAL; 130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kDalvikReg: 132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_DALVIK_REG; 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kHeapRef: 135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_HEAP_REF; 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kMustNotAlias: 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Currently only loads can be marked as kMustNotAlias */ 1391fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE)); 140fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *mask_ptr |= ENCODE_MUST_NOT_ALIAS; 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 143fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(FATAL) << "Oat: invalid memref kind - " << mem_type; 144a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 14531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 14631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 14731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 148b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack. 14931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 1501fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, 1512ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is64bit) { 1521fd3346740dfb7f47be9922312b68a4227fada96buzbee SetMemRefType(lir, is_load, kDalvikReg); 15331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * access. 157a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 158b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit); 15931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 16031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 16131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 1625de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros 1635de3494e4297c0d480409da3fecee39173f1d4e1buzbee */ 1645de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X) 1655de3494e4297c0d480409da3fecee39173f1d4e1buzbee 1665de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */ 1672ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) { 168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset = lir->offset; 169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int dest = lir->operands[0]; 1701fd3346740dfb7f47be9922312b68a4227fada96buzbee const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops)); 171a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Handle pseudo-ops individually, and all regular insns as a group */ 173a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (lir->opcode) { 174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodEntry: 175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- method entry " 1761fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 177a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodExit: 179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- Method_Exit"; 180a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoBarrier: 182a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- BARRIER"; 183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 184a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEntryBlock: 185a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest; 186a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 187a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoDalvikByteCodeBoundary: 1884ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (lir->operands[0] == 0) { 1890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 1900d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string")); 1914ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- dalvik offset: 0x" << std::hex 1930b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << lir->dalvik_offset << " @ " 1940b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0])); 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoExitBlock: 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest; 198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoPseudoAlign4: 200fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << offset << "): .align4"; 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEHBlockLabel: 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Exception_Handling:"; 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoTargetLabel: 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoNormalBlockLabel: 208cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":"; 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoThrowTarget: 211cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":"; 212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoIntrinsicRetry: 214cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":"; 215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoSuspendTarget: 217cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":"; 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 2198320f3867c02bae9bef6cdab267820cb7b412781buzbee case kPseudoSafepointPC: 220fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 2218320f3867c02bae9bef6cdab267820cb7b412781buzbee break; 222a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee case kPseudoExportedPC: 223fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 224a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee break; 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoCaseLabel: 226cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x" 227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << lir->operands[0] << "|" << std::dec << 228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->operands[0]; 229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lir->flags.is_nop && !dump_nop) { 232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 233a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2341fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode), 23502031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 2361fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode), 23702031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 238107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers LOG(INFO) << StringPrintf("%5p: %-9s%s%s", 239107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers base_addr + offset, 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op_name.c_str(), op_operands.c_str(), 241fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop ? "(nop)" : ""); 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 243a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 246b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) { 247b48819db07f9a0992a72173380c24249d7fc648abuzbee DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.use_mask, "use")); 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 249b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) { 250b48819db07f9a0992a72173380c24249d7fc648abuzbee DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.def_mask, "def")); 251a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2525de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2535de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() { 255da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps(); 256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_regs; i++) { 2571fd3346740dfb7f47be9922312b68a4227fada96buzbee PromotionMap v_reg_map = promotion_map_[i]; 258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf; 259fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (v_reg_map.fp_location == kLocPhysReg) { 2601fd3346740dfb7f47be9922312b68a4227fada96buzbee StringAppendF(&buf, " : s%d", v_reg_map.FpReg & FpRegMask()); 261a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2629c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee 263a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf3; 2641fd3346740dfb7f47be9922312b68a4227fada96buzbee if (i < cu_->num_dalvik_registers) { 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee StringAppendF(&buf3, "%02d", i); 2661fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (i == mir_graph_->GetMethodSReg()) { 267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf3 = "Method*"; 268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers); 2705de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 272a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(), 273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee v_reg_map.core_location == kLocPhysReg ? 274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee "r" : "SP+", v_reg_map.core_location == kLocPhysReg ? 2751fd3346740dfb7f47be9922312b68a4227fada96buzbee v_reg_map.core_reg : SRegOffset(i), 276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.c_str()); 277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2785de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2795de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2805de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */ 2812ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() { 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Dumping LIR insns for " 2831fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lir_insn; 2851fd3346740dfb7f47be9922312b68a4227fada96buzbee int insns_size = cu_->code_item->insns_size_in_code_units_; 2861fd3346740dfb7f47be9922312b68a4227fada96buzbee 2871fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs; 2881fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Ins : " << cu_->num_ins; 2891fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Outs : " << cu_->num_outs; 2901fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "CoreSpills : " << num_core_spills_; 2911fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "FPSpills : " << num_fp_spills_; 292da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru LOG(INFO) << "CompilerTemps : " << mir_graph_->GetNumUsedCompilerTemps(); 2931fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Frame size : " << frame_size_; 2941fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "code size is " << total_size_ << 295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee " bytes, Dalvik size is " << insns_size * 2; 296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "expansion factor: " 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2); 2981fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpPromotionMap(); 2991fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) { 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir_insn, 0); 301a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 3021fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) { 303fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset, 304fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir_insn->operands[0]); 305a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 307a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee const DexFile::MethodId& method_id = 3081fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->dex_file->GetMethodId(cu_->method_idx); 309d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const Signature signature = cu_->dex_file->GetMethodSignature(method_id); 310d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* name = cu_->dex_file->GetMethodName(method_id); 311d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id)); 312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 313a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee // Dump mapping tables 31406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!encoded_mapping_table_.empty()) { 31506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 31606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, 31706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.PcToDexSize(), table.PcToDexBegin()); 31806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, 31906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.DexToPcSize(), table.DexToPcBegin()); 32006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 3215de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3225de3494e4297c0d480409da3fecee39173f1d4e1buzbee 32331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 32431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match 32531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0). 32631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 3272ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) { 328fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta) 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return data_target; 331fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 332a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 333a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 33431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 33531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 33631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */ 3372ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) { 338fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool lo_match = false; 339fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lo_target = NULL; 340fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 341fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lo_match && (data_target->operands[0] == val_hi)) { 3424ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee // Record high word in case we need to expand this later. 3434ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee lo_target->operands[1] = val_hi; 344fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return lo_target; 34531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 346fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = false; 347fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (data_target->operands[0] == val_lo) { 348fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = true; 349fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_target = data_target; 350a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 352a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 353a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 35431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 35531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 35631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 35731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or 35831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams. 35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 3614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */ 3622ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) { 363a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Add the constant to the literal pool */ 364fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (constant_list_p) { 365f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocData)); 366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->operands[0] = value; 367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->next = *constant_list_p; 368fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *constant_list_p = new_value; 369b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_ += sizeof(value); 370fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return new_value; 371a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 372a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 37331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 37431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 37531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */ 3762ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) { 3771fd3346740dfb7f47be9922312b68a4227fada96buzbee AddWordData(constant_list_p, val_hi); 3781fd3346740dfb7f47be9922312b68a4227fada96buzbee return AddWordData(constant_list_p, val_lo); 37931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 38031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 381aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void PushWord(std::vector<uint8_t>&buf, int data) { 382df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back(data & 0xff); 383df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 8) & 0xff); 384df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 16) & 0xff); 385df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 24) & 0xff); 386e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 387e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee// Push 8 bytes on 64-bit systems; 4 on 32-bit systems. 3890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic void PushPointer(std::vector<uint8_t>&buf, void const* pointer) { 3900d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee uintptr_t data = reinterpret_cast<uintptr_t>(pointer); 3910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (sizeof(void*) == sizeof(uint64_t)) { 3920d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee PushWord(buf, (data >> (sizeof(void*) * 4)) & 0xFFFFFFFF); 3930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee PushWord(buf, data & 0xFFFFFFFF); 3940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } else { 3950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee PushWord(buf, data); 3960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 3970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 3980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 399aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) { 400a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (buf.size() < offset) { 401a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.push_back(0); 402a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 403e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 404e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 405e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */ 4062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() { 4071fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, data_offset_); 4081fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_lir = literal_list_; 409fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 4101fd3346740dfb7f47be9922312b68a4227fada96buzbee PushWord(code_buffer_, data_lir->operands[0]); 411fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 413a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Push code and method literals, record offsets for the compiler to patch. 4141fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = code_literal_list_; 415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 416fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint32_t target = data_lir->operands[0]; 4171fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddCodePatch(cu_->dex_file, 4188b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4198b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4208b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 4218b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers target, 4228b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers static_cast<InvokeType>(data_lir->operands[1]), 4238b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 4241fd3346740dfb7f47be9922312b68a4227fada96buzbee const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target); 4250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 4260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee PushPointer(code_buffer_, &id); 427fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 428137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers } 4291fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = method_literal_list_; 430fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee uint32_t target = data_lir->operands[0]; 4321fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddMethodPatch(cu_->dex_file, 4338b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4348b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4358b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 4368b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers target, 4378b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers static_cast<InvokeType>(data_lir->operands[1]), 4388b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 4391fd3346740dfb7f47be9922312b68a4227fada96buzbee const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target); 4400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 4410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee PushPointer(code_buffer_, &id); 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 443a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 444be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // Push class literals. 445be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = class_literal_list_; 446be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi while (data_lir != NULL) { 447be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi uint32_t target = data_lir->operands[0]; 448be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->compiler_driver->AddClassPatch(cu_->dex_file, 449be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->class_def_idx, 450be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->method_idx, 451be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi target, 452be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi code_buffer_.size()); 453be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi const DexFile::TypeId& id = cu_->dex_file->GetTypeId(target); 454be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // unique value based on target to ensure code deduplication works 455be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi PushPointer(code_buffer_, &id); 456be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = NEXT_LIR(data_lir); 457be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi } 458e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 459e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 460e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */ 4612ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() { 462862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 463a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 464862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 4661fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 467a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 468a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * For Arm, our reference point is the address of the bx 469a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * instruction that does the launch, so we have to subtract 470a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the auto pc-advance. For other targets the reference point 471a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * is a label, so we can use the offset as-is. 472a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bx_offset = INVALID_OFFSET; 4741fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (cu_->instruction_set) { 475b046e16d8b8da318d6055f9308950131f1255e08buzbee case kThumb2: 476b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(tab_rec->anchor->flags.fixup != kFixupNone); 477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset + 4; 478b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 479b046e16d8b8da318d6055f9308950131f1255e08buzbee case kX86: 480fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = 0; 481b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 482b046e16d8b8da318d6055f9308950131f1255e08buzbee case kMips: 483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset; 484b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 4851fd3346740dfb7f47be9922312b68a4227fada96buzbee default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set; 486b046e16d8b8da318d6055f9308950131f1255e08buzbee } 4871fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset; 489a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 4910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2])); 492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 493fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 4941fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 495a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] key: 0x" 496a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << keys[elems] << ", disp: 0x" 497a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 498e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 4991fd3346740dfb7f47be9922312b68a4227fada96buzbee PushWord(code_buffer_, keys[elems]); 5001fd3346740dfb7f47be9922312b68a4227fada96buzbee PushWord(code_buffer_, 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->targets[elems]->offset - bx_offset); 502a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 503a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 504fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 505a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 506fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 507fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5081fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 509a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] disp: 0x" 510a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 511e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5121fd3346740dfb7f47be9922312b68a4227fada96buzbee PushWord(code_buffer_, tab_rec->targets[elems]->offset - bx_offset); 513a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 514e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 516e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 517e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 518e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */ 5192ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() { 520862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 521a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 522862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 523fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5241fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 525fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < (tab_rec->size + 1) / 2; i++) { 526df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back(tab_rec->table[i] & 0xFF); 527df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF); 528e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 529a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 530e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 531e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 5320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) { 53302c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; lir != NULL; lir = lir->next) { 534a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->offset = offset; 535a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset += 4; 536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 537a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 538e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 539e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 5400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset) { 5410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee unsigned int element_size = sizeof(void*); 5420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Align to natural pointer size. 5430d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset = (offset + (element_size - 1)) & ~(element_size - 1); 5440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee for (; lir != NULL; lir = lir->next) { 5450d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->offset = offset; 5460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset += element_size; 5470d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 5480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee return offset; 5490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 5500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 5516459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry 5522ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() { 55306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 55406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::vector<uint32_t> dex_pcs; 55506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.reserve(table.DexToPcSize()); 55606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) { 55706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.push_back(it.DexPc()); 55806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 55906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_. 56006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::sort(dex_pcs.begin(), dex_pcs.end()); 56106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5626459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee bool success = true; 56306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko auto it = dex_pcs.begin(), end = dex_pcs.end(); 56406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t dex_pc : mir_graph_->catches_) { 56506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko while (it != end && *it < dex_pc) { 56606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it; 56706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 5686459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 5696459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 57006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (it == end || *it > dex_pc) { 57106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc; 5726459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 57306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } else { 57406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 5756459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 5766459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 5776459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee if (!success) { 5781fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 5791fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: " 58006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko << table.DexToPcSize(); 5816459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 5826459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee return success; 5836459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee} 5846459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee 585311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() { 5871e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_data_size = 0u; 5881e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_entries = 0u; 5891e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_offset = 0u; 5901e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_dalvik_offset = 0u; 5911e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_data_size = 0u; 5921e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_entries = 0u; 5931e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_offset = 0u; 5941e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_dalvik_offset = 0u; 5951fd3346740dfb7f47be9922312b68a4227fada96buzbee for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 596fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 5971e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_entries += 1; 5981e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 5991e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset); 6001e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6011e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 6021e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = tgt_lir->offset; 6031e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 604a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee } 605fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 6061e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_entries += 1; 6071e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 6081e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset); 6091e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6101e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 6111e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_offset = tgt_lir->offset; 6121e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 613e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 614a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6151e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6161e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t total_entries = pc2dex_entries + dex2pc_entries; 6171e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries); 6181e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size; 61906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko encoded_mapping_table_.resize(data_size); 62006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos = &encoded_mapping_table_[0]; 62106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, total_entries); 62206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries); 62306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size); 62406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos2 = write_pos + pc2dex_data_size; 6251e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6261e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = 0u; 6271e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = 0u; 62806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = 0u; 62906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = 0u; 63006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 63106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 63206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 63306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset); 63406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) - 63506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 63606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_offset = tgt_lir->offset; 63706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 63806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 63906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 64006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 64106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset); 64206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) - 64306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 64406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = tgt_lir->offset; 64506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 64606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 6471e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko } 64806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), 64906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko hdr_data_size + pc2dex_data_size); 65006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size); 6511e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 65296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (kIsDebugBuild) { 65306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(VerifyCatchEntries()); 65406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 65596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // Verify the encoded table holds the expected data. 65606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 65796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.TotalSize(), total_entries); 65896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.PcToDexSize(), pc2dex_entries); 6591e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it = table.PcToDexBegin(); 6601e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it2 = table.DexToPcBegin(); 66106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 66206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 66306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it.NativePcOffset()); 66406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc()); 66506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 66606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 66706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 66806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it2.NativePcOffset()); 66906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc()); 67006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it2; 67106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 67296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 67306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(it == table.PcToDexEnd()); 6741e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko CHECK(it2 == table.DexToPcEnd()); 675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 676e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 677e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 6780c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogersclass NativePcToReferenceMapBuilder { 6790c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers public: 6800c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers NativePcToReferenceMapBuilder(std::vector<uint8_t>* table, 6810c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t entries, uint32_t max_native_offset, 6820c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t references_width) : entries_(entries), 6830c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers references_width_(references_width), in_use_(entries), 6840c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers table_(table) { 6850c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Compute width in bytes needed to hold max_native_offset. 6860c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers native_offset_width_ = 0; 6870c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers while (max_native_offset != 0) { 6880c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers native_offset_width_++; 6890c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers max_native_offset >>= 8; 6900c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 6910c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Resize table and set up header. 6920c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers table->resize((EntryWidth() * entries) + sizeof(uint32_t)); 693000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers CHECK_LT(native_offset_width_, 1U << 3); 694000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers (*table)[0] = native_offset_width_ & 7; 695000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers CHECK_LT(references_width_, 1U << 13); 696000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers (*table)[0] |= (references_width_ << 3) & 0xFF; 697000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers (*table)[1] = (references_width_ >> 5) & 0xFF; 6980c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers CHECK_LT(entries, 1U << 16); 6990c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers (*table)[2] = entries & 0xFF; 7000c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers (*table)[3] = (entries >> 8) & 0xFF; 7010c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers void AddEntry(uint32_t native_offset, const uint8_t* references) { 7040c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t table_index = TableIndex(native_offset); 7050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers while (in_use_[table_index]) { 7060c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers table_index = (table_index + 1) % entries_; 7070c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7080c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers in_use_[table_index] = true; 7090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee SetCodeOffset(table_index, native_offset); 7100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(native_offset, GetCodeOffset(table_index)); 7110c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers SetReferences(table_index, references); 7120c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7130c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7140c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers private: 7150c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t TableIndex(uint32_t native_offset) { 7160c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return NativePcOffsetToReferenceMap::Hash(native_offset) % entries_; 7170c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7180c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee uint32_t GetCodeOffset(size_t table_index) { 7200c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t native_offset = 0; 7210c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 7220c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers for (size_t i = 0; i < native_offset_width_; i++) { 7230c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers native_offset |= (*table_)[table_offset + i] << (i * 8); 7240c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7250c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return native_offset; 7260c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7280d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee void SetCodeOffset(size_t table_index, uint32_t native_offset) { 7290c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 7300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers for (size_t i = 0; i < native_offset_width_; i++) { 7310c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers (*table_)[table_offset + i] = (native_offset >> (i * 8)) & 0xFF; 7320c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7330c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7340c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7350c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers void SetReferences(size_t table_index, const uint8_t* references) { 7360c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t); 7370c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers memcpy(&(*table_)[table_offset + native_offset_width_], references, references_width_); 7380c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7390c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7400c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t EntryWidth() const { 7410c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return native_offset_width_ + references_width_; 7420c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7430c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7440c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Number of entries in the table. 7450c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const size_t entries_; 7460c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Number of bytes used to encode the reference bitmap. 7470c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const size_t references_width_; 7480c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Number of bytes used to encode a native offset. 7490c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t native_offset_width_; 7500c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Entries that are in use. 7510c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers std::vector<bool> in_use_; 7520c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // The table we're building. 7530c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers std::vector<uint8_t>* const table_; 7540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers}; 7550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 7561fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() { 75706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(!encoded_mapping_table_.empty()); 75806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable mapping_table(&encoded_mapping_table_[0]); 7590c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t max_native_offset = 0; 76006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 76106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 7620c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers if (native_offset > max_native_offset) { 7630c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers max_native_offset = native_offset; 7640c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7650c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 76651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReference method_ref(cu_->dex_file, cu_->method_idx); 7672730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko const std::vector<uint8_t>& gc_map_raw = 7682730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap(); 7692730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]); 7702730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize()); 7710c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Compute native offset to references size. 7721fd3346740dfb7f47be9922312b68a4227fada96buzbee NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_, 77306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko mapping_table.PcToDexSize(), 77406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko max_native_offset, dex_gc_map.RegWidth()); 7750c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 77606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 77706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 77806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t dex_pc = it.DexPc(); 7790c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false); 780a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc; 781a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee native_gc_map_builder.AddEntry(native_offset, references); 7820c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7830c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers} 7840c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 785e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */ 7860d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) { 7871fd3346740dfb7f47be9922312b68a4227fada96buzbee offset = AssignLiteralOffsetCommon(literal_list_, offset); 7880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset); 7890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset); 790be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset); 791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 792e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 793e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) { 795862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 796a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 7970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 798fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 800fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 801fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * (sizeof(int) * 2); 802a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 803fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 804a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 805fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * sizeof(int); 806e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 808a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 809e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 810e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 8110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) { 812862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 813a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 814862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 815fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 816fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 817fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->size; 818a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // word align 819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset = (offset + 3) & ~3; 820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 821a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 822e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 823e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 82531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik 826b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block 827b48819db07f9a0992a72173380c24249d7fc648abuzbee * label. The selected label will be used to fix up the case 828252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase. All resource flags 829252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion. KeyVal is just there for debugging. 83031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 8310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) { 832252254b130067cd7a5071865e793966871ae0246buzbee LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id]; 833b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* res = boundary_lir; 834b48819db07f9a0992a72173380c24249d7fc648abuzbee if (cu_->verbose) { 835b48819db07f9a0992a72173380c24249d7fc648abuzbee // Only pay the expense if we're pretty-printing. 836b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocLIR)); 837b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->dalvik_offset = vaddr; 838b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->opcode = kPseudoCaseLabel; 839b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->operands[0] = keyVal; 840b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->flags.fixup = kFixupLabel; 841b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!new_label->flags.use_def_invalid); 842b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->u.m.def_mask = ENCODE_ALL; 843b48819db07f9a0992a72173380c24249d7fc648abuzbee InsertLIRAfter(boundary_lir, new_label); 844b48819db07f9a0992a72173380c24249d7fc648abuzbee res = new_label; 845b48819db07f9a0992a72173380c24249d7fc648abuzbee } 846b48819db07f9a0992a72173380c24249d7fc648abuzbee return res; 84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 84831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 850fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8510d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 8520d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]); 853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 854fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 855a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8561fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key); 857a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 85931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 861fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 863a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 866a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8671fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]); 868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 87031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8712ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() { 872862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 873a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 874862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable *tab_rec = iterator.Next(); 875fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 876fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) { 8771fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkPackedCaseLabels(tab_rec); 878fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 8791fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkSparseCaseLabels(tab_rec); 880a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 881a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Invalid switch table"; 88231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 883a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 88431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 88531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) { 887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sparse switch data format: 889a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0200 magic value 890a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table; > 0 891a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 892a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 893a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (2+size*4) 16-bit code units. 895a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 896eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 897a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8990d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 900a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Sparse switch table - ident:0x" << std::hex << ident 901a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << ", entries: " << std::dec << entries; 902a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 903a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Key[" << keys[i] << "] -> 0x" << std::hex << targets[i]; 904a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 90531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 90631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 9072ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) { 908a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 909a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Packed switch data format: 910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0100 magic value 911a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table 912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int first_key first (and lowest) switch case value 913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 914a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (4+size*2) 16-bit code units. 916a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 917eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 9180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]); 919a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 920fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 921a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident 922fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee << ", entries: " << std::dec << entries << ", low_key: " << low_key; 923a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 924fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << " Key[" << (i + low_key) << "] -> 0x" << std::hex 925a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << targets[i]; 926a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 92731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 928e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 929252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */ 9300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) { 9310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 9320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str))); 933d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee} 934e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 9352ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) { 936e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee bool is_taken; 937e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee switch (opcode) { 938e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQ: is_taken = (src1 == src2); break; 939e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NE: is_taken = (src1 != src2); break; 940e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LT: is_taken = (src1 < src2); break; 941e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GE: is_taken = (src1 >= src2); break; 942e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GT: is_taken = (src1 > src2); break; 943e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LE: is_taken = (src1 <= src2); break; 944e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQZ: is_taken = (src1 == 0); break; 945e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NEZ: is_taken = (src1 != 0); break; 946e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LTZ: is_taken = (src1 < 0); break; 947e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GEZ: is_taken = (src1 >= 0); break; 948e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GTZ: is_taken = (src1 > 0); break; 949e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LEZ: is_taken = (src1 <= 0); break; 950e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee default: 951e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee LOG(FATAL) << "Unexpected opcode " << opcode; 952e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee is_taken = false; 953e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee } 954e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return is_taken; 955e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 956e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 9574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1 9581fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) { 9594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee ConditionCode res; 9604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee switch (before) { 9614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondEq: res = kCondEq; break; 9624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondNe: res = kCondNe; break; 9634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLt: res = kCondGt; break; 9644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGt: res = kCondLt; break; 9654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLe: res = kCondGe; break; 9664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGe: res = kCondLe; break; 9674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee default: 9684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res = static_cast<ConditionCode>(0); 9694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LOG(FATAL) << "Unexpected ccode " << before; 9704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 9724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 9734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 974862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc 975862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 9766282dc12440a2072dc06a616160027ff21bd895eIan Rogers : Backend(arena), 9776282dc12440a2072dc06a616160027ff21bd895eIan Rogers literal_list_(NULL), 9781fd3346740dfb7f47be9922312b68a4227fada96buzbee method_literal_list_(NULL), 979be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi class_literal_list_(NULL), 9801fd3346740dfb7f47be9922312b68a4227fada96buzbee code_literal_list_(NULL), 981b48819db07f9a0992a72173380c24249d7fc648abuzbee first_fixup_(NULL), 9821fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 9831fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_(mir_graph), 984862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee switch_tables_(arena, 4, kGrowableArraySwitchTables), 985862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee fill_array_data_(arena, 4, kGrowableArrayFillArrayData), 986862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee throw_launchpads_(arena, 2048, kGrowableArrayThrowLaunchPads), 987862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee suspend_launchpads_(arena, 4, kGrowableArraySuspendLaunchPads), 988862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee intrinsic_launchpads_(arena, 2048, kGrowableArrayMisc), 989bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee tempreg_info_(arena, 20, kGrowableArrayMisc), 990bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee reginfo_map_(arena, 64, kGrowableArrayMisc), 9910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee pointer_storage_(arena, 128, kGrowableArrayMisc), 9921fd3346740dfb7f47be9922312b68a4227fada96buzbee data_offset_(0), 9931fd3346740dfb7f47be9922312b68a4227fada96buzbee total_size_(0), 9941fd3346740dfb7f47be9922312b68a4227fada96buzbee block_label_list_(NULL), 995d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee promotion_map_(NULL), 996862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee current_dalvik_offset_(0), 997b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_(0), 998862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee reg_pool_(NULL), 9991fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_(0), 10001fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_(0), 10011fd3346740dfb7f47be9922312b68a4227fada96buzbee num_fp_spills_(0), 10021fd3346740dfb7f47be9922312b68a4227fada96buzbee frame_size_(0), 10031fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_(0), 10041fd3346740dfb7f47be9922312b68a4227fada96buzbee fp_spill_mask_(0), 10051fd3346740dfb7f47be9922312b68a4227fada96buzbee first_lir_insn_(NULL), 10065816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko last_lir_insn_(NULL) { 10070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Reserve pointer id 0 for NULL. 10080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee size_t null_idx = WrapPointer(NULL); 10090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_idx, 0U); 10101fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10111fd3346740dfb7f47be9922312b68a4227fada96buzbee 10121fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() { 1013a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("RegisterAllocation"); 10141fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitializeRegAlloc(); // Needs to happen after SSA naming 10151fd3346740dfb7f47be9922312b68a4227fada96buzbee 10161fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Allocate Registers using simple local allocation scheme */ 10171fd3346740dfb7f47be9922312b68a4227fada96buzbee SimpleRegAlloc(); 10181fd3346740dfb7f47be9922312b68a4227fada96buzbee 10195816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko /* 10205816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko * Custom codegen for special cases. If for any reason the 10215115473c81ec855a5646a5f755afb26aa7f2b1e9Vladimir Marko * special codegen doesn't succeed, first_lir_insn_ will be 10225816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko * set to NULL; 10235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko */ 10245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko // TODO: Clean up GenSpecial() and return true only if special implementation is emitted. 10255816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko // Currently, GenSpecial() returns IsSpecial() but doesn't check after SpecialMIR2LIR(). 10265816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr); 10275816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file) 10285816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko ->GenSpecial(this, cu_->method_idx); 10291fd3346740dfb7f47be9922312b68a4227fada96buzbee 10301fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Convert MIR to LIR, etc. */ 10311fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_ == NULL) { 10321fd3346740dfb7f47be9922312b68a4227fada96buzbee MethodMIR2LIR(); 10331fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10341fd3346740dfb7f47be9922312b68a4227fada96buzbee 10351fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Method is not empty */ 10361fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_) { 10371fd3346740dfb7f47be9922312b68a4227fada96buzbee // mark the targets of switch statement case labels 10381fd3346740dfb7f47be9922312b68a4227fada96buzbee ProcessSwitchTables(); 10391fd3346740dfb7f47be9922312b68a4227fada96buzbee 10401fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Convert LIR into machine code. */ 10411fd3346740dfb7f47be9922312b68a4227fada96buzbee AssembleLIR(); 10421fd3346740dfb7f47be9922312b68a4227fada96buzbee 10431fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 10441fd3346740dfb7f47be9922312b68a4227fada96buzbee CodegenDump(); 10451fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10461fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10471fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10481fd3346740dfb7f47be9922312b68a4227fada96buzbee 10491fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() { 10501fd3346740dfb7f47be9922312b68a4227fada96buzbee // Combine vmap tables - core regs, then fp regs - into vmap_table 105196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers std::vector<uint16_t> raw_vmap_table; 10521fd3346740dfb7f47be9922312b68a4227fada96buzbee // Core regs may have been inserted out of order - sort first 10531fd3346740dfb7f47be9922312b68a4227fada96buzbee std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); 1054193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { 10551fd3346740dfb7f47be9922312b68a4227fada96buzbee // Copy, stripping out the phys register sort key 105696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers raw_vmap_table.push_back(~(-1 << VREG_NUM_WIDTH) & core_vmap_table_[i]); 10571fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10581fd3346740dfb7f47be9922312b68a4227fada96buzbee // If we have a frame, push a marker to take place of lr 10591fd3346740dfb7f47be9922312b68a4227fada96buzbee if (frame_size_ > 0) { 106096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers raw_vmap_table.push_back(INVALID_VREG); 10611fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10621fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(__builtin_popcount(core_spill_mask_), 0); 10631fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ(__builtin_popcount(fp_spill_mask_), 0); 10641fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10651fd3346740dfb7f47be9922312b68a4227fada96buzbee // Combine vmap tables - core regs, then fp regs. fp regs already sorted 10661fd3346740dfb7f47be9922312b68a4227fada96buzbee for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { 106796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers raw_vmap_table.push_back(fp_vmap_table_[i]); 106896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 10691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko Leb128EncodingVector vmap_encoder; 107096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // Prefix the encoded data with its size. 10711e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko vmap_encoder.PushBackUnsigned(raw_vmap_table.size()); 1072193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier for (uint16_t cur : raw_vmap_table) { 10731e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko vmap_encoder.PushBackUnsigned(cur); 10741fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10751fd3346740dfb7f47be9922312b68a4227fada96buzbee CompiledMethod* result = 1076193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier new CompiledMethod(*cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_, 107706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko core_spill_mask_, fp_spill_mask_, encoded_mapping_table_, 1078193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier vmap_encoder.GetData(), native_gc_map_); 10791fd3346740dfb7f47be9922312b68a4227fada96buzbee return result; 10801fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10811fd3346740dfb7f47be9922312b68a4227fada96buzbee 1082da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const { 1083da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Chose a reasonably small value in order to contain stack growth. 1084da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Backends that are smarter about spill region can return larger values. 1085da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru const size_t max_compiler_temps = 10; 1086da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return max_compiler_temps; 1087da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1088da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 1089da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() { 1090da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // By default assume that the Mir2Lir will need one slot for each temporary. 1091da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // If the backend can better determine temps that have non-overlapping ranges and 1092da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // temps that do not need spilled, it can actually provide a small region. 1093da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t)); 1094da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1095da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 10961fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() { 10971fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Figure out the frame size */ 10981fd3346740dfb7f47be9922312b68a4227fada96buzbee static const uint32_t kAlignMask = kStackAlignment - 1; 1099da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru uint32_t size = ((num_core_spills_ + num_fp_spills_ + 1100da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 1 /* filler word */ + cu_->num_regs + cu_->num_outs) 1101da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru * sizeof(uint32_t)) + 1102da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru GetNumBytesForCompilerTempSpillRegion(); 11031fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Align and set */ 11041fd3346740dfb7f47be9922312b68a4227fada96buzbee return (size + kAlignMask) & ~(kAlignMask); 11051fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11061fd3346740dfb7f47be9922312b68a4227fada96buzbee 11071fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11081fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation 11091fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit 11101fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11112ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) { 11121fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_ == NULL) { 11131fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(last_lir_insn_ == NULL); 11141fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = first_lir_insn_ = lir; 11151fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = lir->next = NULL; 11161fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 11171fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_->next = lir; 11181fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = last_lir_insn_; 11191fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->next = NULL; 11201fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = lir; 11211fd3346740dfb7f47be9922312b68a4227fada96buzbee } 11221fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11231fd3346740dfb7f47be9922312b68a4227fada96buzbee 11241fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11251fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the 11261fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 11271fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11281fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir 11291fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11302ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) { 11311fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(current_lir->prev != NULL); 11321fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR *prev_lir = current_lir->prev; 11331fd3346740dfb7f47be9922312b68a4227fada96buzbee 11341fd3346740dfb7f47be9922312b68a4227fada96buzbee prev_lir->next = new_lir; 11351fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = prev_lir; 11361fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir; 11371fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->prev = new_lir; 11381fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11391fd3346740dfb7f47be9922312b68a4227fada96buzbee 11401fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11411fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the 11421fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 11431fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11441fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next 11451fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11462ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) { 11471fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = current_lir; 11481fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir->next; 11491fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->next = new_lir; 11501fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next->prev = new_lir; 11511fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11521fd3346740dfb7f47be9922312b68a4227fada96buzbee 11534708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) { 11544708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (x & (x - 1)) == 0; 11554708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11564708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11574708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'. 11584708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) { 11594708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell int bit_posn = 0; 11604708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 0xf) == 0) { 11614708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn += 4; 11624708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 4; 11634708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11644708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 1) == 0) { 11654708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn++; 11664708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 1; 11674708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11684708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return bit_posn; 11694708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11704708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11714708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) { 11724708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_src.wide); 11734708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_dest.wide); 11744708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1); 11754708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11764708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 1177766e9295d2c34cd1846d81610c9045b5d5093dddMark MendellLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, int temp_reg, int base_reg, 1178766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell int offset, int check_value, LIR* target) { 1179766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell // Handle this for architectures that can't compare to memory. 1180766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LoadWordDisp(base_reg, offset, temp_reg); 1181766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target); 1182766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 1183766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 1184766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 11857934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 1186