1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* 2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project 3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License. 6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at 7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * http://www.apache.org/licenses/LICENSE-2.0 9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software 11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and 14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License. 15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h" 184f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h" 2092cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray#include "gc_map_builder.h" 2196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h" 228d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h" 235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h" 245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h" 25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h" 262730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h" 270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h" 280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h" 292e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko#include "vmap_table.h" 300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 31e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art { 32e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace { 3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */ 3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It> 3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name, 3806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko const Signature& signature, uint32_t size, It first) { 3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (size != 0) { 40107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers std::string line(StringPrintf("\n %s %s%s_%s_table[%u] = {", table_name, 4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko descriptor, name, signature.ToString().c_str(), size)); 4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::replace(line.begin(), line.end(), ';', '_'); 4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t i = 0; i != size; ++i) { 4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko line = StringPrintf(" {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc()); 4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++first; 4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) <<" };\n\n"; 5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} 5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} // anonymous namespace 5406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 552ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) { 564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool res = false; 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.is_const) { 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.wide) { 59ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe // For wide registers, check whether we're the high partner. In that case we need to switch 60ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe // to the lower one for the correct value. 61ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe if (rl_src.high_word) { 62ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe rl_src.high_word = false; 63ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe rl_src.s_reg_low--; 64ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe rl_src.orig_sreg--; 65ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe } 664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 67ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); 684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 69ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 73ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); 744ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 75ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); 764ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 774ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 784ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 794ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 804ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 814ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 822ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) { 83b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!inst->flags.use_def_invalid); 848dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko inst->u.m.def_mask = &kEncodeAll; 851fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC); 868dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll)); 8702031b185b4653e6c72e21f7a51238b903f6d638buzbee} 8802031b185b4653e6c72e21f7a51238b903f6d638buzbee 893c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampevoid Mir2Lir::MarkSafepointPCAfter(LIR* after) { 903c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK(!after->flags.use_def_invalid); 913c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe after->u.m.def_mask = &kEncodeAll; 923c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe // As NewLIR0 uses Append, we need to create the LIR by hand. 933c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe LIR* safepoint_pc = RawLIR(current_dalvik_offset_, kPseudoSafepointPC); 943c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe if (after->next == nullptr) { 953c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK_EQ(after, last_lir_insn_); 963c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe AppendLIR(safepoint_pc); 973c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } else { 983c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe InsertLIRAfter(after, safepoint_pc); 993c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } 1003c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll)); 1013c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe} 1023c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 103252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */ 104252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) { 105252254b130067cd7a5071865e793966871ae0246buzbee if (UNLIKELY(lir == first_lir_insn_)) { 106252254b130067cd7a5071865e793966871ae0246buzbee first_lir_insn_ = lir->next; 107252254b130067cd7a5071865e793966871ae0246buzbee if (lir->next != NULL) { 108252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = NULL; 109252254b130067cd7a5071865e793966871ae0246buzbee } else { 110252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir->next == NULL); 111252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir == last_lir_insn_); 112252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = NULL; 113252254b130067cd7a5071865e793966871ae0246buzbee } 114252254b130067cd7a5071865e793966871ae0246buzbee } else if (lir == last_lir_insn_) { 115252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = lir->prev; 116252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = NULL; 117252254b130067cd7a5071865e793966871ae0246buzbee } else if ((lir->prev != NULL) && (lir->next != NULL)) { 118252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = lir->next; 119252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = lir->prev; 120252254b130067cd7a5071865e793966871ae0246buzbee } 121252254b130067cd7a5071865e793966871ae0246buzbee} 122252254b130067cd7a5071865e793966871ae0246buzbee 123cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */ 124df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) { 125fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop = true; 126252254b130067cd7a5071865e793966871ae0246buzbee if (!cu_->verbose) { 127252254b130067cd7a5071865e793966871ae0246buzbee UnlinkLIR(lir); 128252254b130067cd7a5071865e793966871ae0246buzbee } 129cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee} 130cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee 1312ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) { 1321fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE)); 133b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 1348dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko // TODO: Avoid the extra Arena allocation! 1358dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko const ResourceMask** mask_ptr; 1368dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ResourceMask mask; 137fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_load) { 138b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.use_mask; 139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 140b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.def_mask; 141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1428dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask = **mask_ptr; 143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Clear out the memref flags */ 1448dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.ClearBits(kEncodeMem); 145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* ..and then add back the one we need */ 146fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee switch (mem_type) { 1478dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kLiteral: 148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(is_load); 1498dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kLiteral); 150a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1518dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kDalvikReg: 1528dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kDalvikReg); 153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1548dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kHeapRef: 1558dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kHeapRef); 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1578dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kMustNotAlias: 158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Currently only loads can be marked as kMustNotAlias */ 1591fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE)); 1608dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kMustNotAlias); 161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 162a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 163fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(FATAL) << "Oat: invalid memref kind - " << mem_type; 164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1658dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko *mask_ptr = mask_cache_.GetMask(mask); 16631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 16731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 16831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 169b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack. 17031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 1711fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, 1722ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is64bit) { 1738dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK((is_load ? lir->u.m.use_mask : lir->u.m.def_mask)->Intersection(kEncodeMem).Equals( 1748dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko kEncodeDalvikReg)); 17531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit 178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * access. 179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 180b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit); 18131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 18231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 18331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 1845de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros 1855de3494e4297c0d480409da3fecee39173f1d4e1buzbee */ 1865de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X) 1875de3494e4297c0d480409da3fecee39173f1d4e1buzbee 1885de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */ 1892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) { 190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset = lir->offset; 191a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int dest = lir->operands[0]; 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops)); 193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Handle pseudo-ops individually, and all regular insns as a group */ 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (lir->opcode) { 196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodEntry: 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- method entry " 1981fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodExit: 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- Method_Exit"; 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoBarrier: 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- BARRIER"; 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEntryBlock: 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest; 208a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoDalvikByteCodeBoundary: 2104ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (lir->operands[0] == 0) { 2110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 2120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string")); 2134ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- dalvik offset: 0x" << std::hex 2150b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << lir->dalvik_offset << " @ " 2160b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0])); 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoExitBlock: 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest; 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoPseudoAlign4: 222fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex 223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << offset << "): .align4"; 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEHBlockLabel: 226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Exception_Handling:"; 227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoTargetLabel: 229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoNormalBlockLabel: 230cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":"; 231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoThrowTarget: 233cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":"; 234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 235a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoIntrinsicRetry: 236cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":"; 237a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoSuspendTarget: 239cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":"; 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 2418320f3867c02bae9bef6cdab267820cb7b412781buzbee case kPseudoSafepointPC: 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 2438320f3867c02bae9bef6cdab267820cb7b412781buzbee break; 244a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee case kPseudoExportedPC: 245fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 246a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee break; 247a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoCaseLabel: 248cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x" 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << lir->operands[0] << "|" << std::dec << 250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->operands[0]; 251a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 253fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lir->flags.is_nop && !dump_nop) { 254a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2561fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode), 25702031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 2581fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode), 25902031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 260107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers LOG(INFO) << StringPrintf("%5p: %-9s%s%s", 261107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers base_addr + offset, 262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op_name.c_str(), op_operands.c_str(), 263fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop ? "(nop)" : ""); 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 268b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) { 2698dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.use_mask, "use")); 270a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 271b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) { 2728dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.def_mask, "def")); 273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2745de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2755de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2762ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() { 277da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps(); 278fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_regs; i++) { 2791fd3346740dfb7f47be9922312b68a4227fada96buzbee PromotionMap v_reg_map = promotion_map_[i]; 280a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf; 281fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (v_reg_map.fp_location == kLocPhysReg) { 282b5860fb459f1ed71f39d8a87b45bee6727d79fe8buzbee StringAppendF(&buf, " : s%d", RegStorage::RegNum(v_reg_map.fp_reg)); 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2849c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee 285a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf3; 2861fd3346740dfb7f47be9922312b68a4227fada96buzbee if (i < cu_->num_dalvik_registers) { 287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee StringAppendF(&buf3, "%02d", i); 2881fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (i == mir_graph_->GetMethodSReg()) { 289a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf3 = "Method*"; 290a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2911fd3346740dfb7f47be9922312b68a4227fada96buzbee StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers); 2925de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 293a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 294a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(), 295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee v_reg_map.core_location == kLocPhysReg ? 296fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee "r" : "SP+", v_reg_map.core_location == kLocPhysReg ? 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee v_reg_map.core_reg : SRegOffset(i), 298a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.c_str()); 299a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 3005de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3015de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3027a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbeevoid Mir2Lir::UpdateLIROffsets() { 3037a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee // Only used for code listings. 3047a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee size_t offset = 0; 3057a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) { 3067a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee lir->offset = offset; 3077a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) { 3087a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += GetInsnSize(lir); 3097a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } else if (lir->opcode == kPseudoPseudoAlign4) { 3107a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += (offset & 0x2); 3117a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 3127a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 3137a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee} 3147a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee 3155de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */ 3162ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() { 317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Dumping LIR insns for " 3181fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 319fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lir_insn; 3201fd3346740dfb7f47be9922312b68a4227fada96buzbee int insns_size = cu_->code_item->insns_size_in_code_units_; 3211fd3346740dfb7f47be9922312b68a4227fada96buzbee 3221fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs; 3231fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Ins : " << cu_->num_ins; 3241fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Outs : " << cu_->num_outs; 3251fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "CoreSpills : " << num_core_spills_; 3261fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "FPSpills : " << num_fp_spills_; 327da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru LOG(INFO) << "CompilerTemps : " << mir_graph_->GetNumUsedCompilerTemps(); 3281fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Frame size : " << frame_size_; 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "code size is " << total_size_ << 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee " bytes, Dalvik size is " << insns_size * 2; 331a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "expansion factor: " 3321fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2); 3331fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpPromotionMap(); 3347a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee UpdateLIROffsets(); 3351fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) { 3361fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir_insn, 0); 337a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 3381fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) { 339fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset, 340fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir_insn->operands[0]); 341a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 342a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 343a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee const DexFile::MethodId& method_id = 3441fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->dex_file->GetMethodId(cu_->method_idx); 345d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const Signature signature = cu_->dex_file->GetMethodSignature(method_id); 346d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* name = cu_->dex_file->GetMethodName(method_id); 347d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id)); 348a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 349a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee // Dump mapping tables 35006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!encoded_mapping_table_.empty()) { 35106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 35206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, 35306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.PcToDexSize(), table.PcToDexBegin()); 35406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, 35506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.DexToPcSize(), table.DexToPcBegin()); 35606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 3575de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3585de3494e4297c0d480409da3fecee39173f1d4e1buzbee 35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match 36131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0). 36231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 3632ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) { 364fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 365fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta) 366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return data_target; 367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 368a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 369a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 37031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 37131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 37231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */ 3732ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) { 374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool lo_match = false; 375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lo_target = NULL; 376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lo_match && (data_target->operands[0] == val_hi)) { 3784ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee // Record high word in case we need to expand this later. 3794ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee lo_target->operands[1] = val_hi; 380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return lo_target; 38131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 382fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = false; 383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (data_target->operands[0] == val_lo) { 384fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = true; 385fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_target = data_target; 386a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 387fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 388a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 389a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 39031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 39131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 392a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko/* Search the existing constants in the literal pool for an exact method match */ 393a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir MarkoLIR* Mir2Lir::ScanLiteralPoolMethod(LIR* data_target, const MethodReference& method) { 394a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko while (data_target) { 395a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko if (static_cast<uint32_t>(data_target->operands[0]) == method.dex_method_index && 396a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko UnwrapPointer(data_target->operands[1]) == method.dex_file) { 397a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko return data_target; 398a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko } 399a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = data_target->next; 400a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko } 401a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko return nullptr; 402a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko} 403a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko 40431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 40531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or 40631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams. 40731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 40831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4094ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */ 4102ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) { 411a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Add the constant to the literal pool */ 412fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (constant_list_p) { 41383cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocData)); 414fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->operands[0] = value; 415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->next = *constant_list_p; 416fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *constant_list_p = new_value; 417b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_ += sizeof(value); 418fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return new_value; 419a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 420a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 42131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 42231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 42331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */ 4242ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) { 4251fd3346740dfb7f47be9922312b68a4227fada96buzbee AddWordData(constant_list_p, val_hi); 4261fd3346740dfb7f47be9922312b68a4227fada96buzbee return AddWordData(constant_list_p, val_lo); 42731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 42831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4292da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void Push32(std::vector<uint8_t>&buf, int data) { 430df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back(data & 0xff); 431df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 8) & 0xff); 432df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 16) & 0xff); 433df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 24) & 0xff); 434e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 435e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 4362da882315a61072664f7ce3c212307342e907207Andreas Gampe// Push 8 bytes on 64-bit target systems; 4 on 32-bit target systems. 4372da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void PushPointer(std::vector<uint8_t>&buf, const void* pointer, bool target64) { 4382da882315a61072664f7ce3c212307342e907207Andreas Gampe uint64_t data = reinterpret_cast<uintptr_t>(pointer); 4392da882315a61072664f7ce3c212307342e907207Andreas Gampe if (target64) { 4402da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, data & 0xFFFFFFFF); 4412da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, (data >> 32) & 0xFFFFFFFF); 4420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } else { 4432da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, static_cast<uint32_t>(data)); 4440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 4450d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 4460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 447aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) { 448a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (buf.size() < offset) { 449a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.push_back(0); 450a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 451e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 452e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 453e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */ 4542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() { 4551fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, data_offset_); 4561fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_lir = literal_list_; 457fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 4582da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, data_lir->operands[0]); 459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 461a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Push code and method literals, record offsets for the compiler to patch. 4621fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = code_literal_list_; 463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 46449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 46549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 46649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4671fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddCodePatch(cu_->dex_file, 4688b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4698b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4708b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 47149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 47249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 47349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4748b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 47549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 47749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 478fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 479137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers } 4801fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = method_literal_list_; 481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 48249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 48349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 48449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4851fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddMethodPatch(cu_->dex_file, 4868b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4878b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4888b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 48949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 49049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 49149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4928b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 49349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 49549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 497a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 498be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // Push class literals. 499be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = class_literal_list_; 500be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi while (data_lir != NULL) { 50149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 502be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->compiler_driver->AddClassPatch(cu_->dex_file, 503be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->class_def_idx, 504be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->method_idx, 50549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 506be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi code_buffer_.size()); 50749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::TypeId& target_method_id = cu_->dex_file->GetTypeId(target_method_idx); 508be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // unique value based on target to ensure code deduplication works 50949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 510be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = NEXT_LIR(data_lir); 511be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi } 512807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier // Push the string literals. 513807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier data_lir = string_literal_list_; 514807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier while (data_lir != nullptr) { 515807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier uint32_t string_idx = data_lir->operands[0]; 516807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier cu_->compiler_driver->AddStringPatch(cu_->dex_file, 517807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier cu_->class_def_idx, 518807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier cu_->method_idx, 519807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier string_idx, 520807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier code_buffer_.size()); 521807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier const auto& target_string_id = cu_->dex_file->GetStringId(string_idx); 522807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier // unique value based on target to ensure code deduplication works 523807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier PushPointer(code_buffer_, &target_string_id, cu_->target64); 524807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier data_lir = NEXT_LIR(data_lir); 525807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier } 526e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 527e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 528e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */ 5292ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() { 530862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 531a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 532862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 533fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5341fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 535a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * For Arm, our reference point is the address of the bx 537a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * instruction that does the launch, so we have to subtract 538a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the auto pc-advance. For other targets the reference point 539a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * is a label, so we can use the offset as-is. 540a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 541fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bx_offset = INVALID_OFFSET; 5421fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (cu_->instruction_set) { 543b046e16d8b8da318d6055f9308950131f1255e08buzbee case kThumb2: 544b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(tab_rec->anchor->flags.fixup != kFixupNone); 545fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset + 4; 546b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 547b046e16d8b8da318d6055f9308950131f1255e08buzbee case kX86: 5486a58cb16d803c9a7b3a75ccac8be19dd9d4e520dDmitry Petrochenko case kX86_64: 549fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = 0; 550b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 551e45fb9e7976c8462b94a58ad60b006b0eacec49fMatteo Franchin case kArm64: 552b046e16d8b8da318d6055f9308950131f1255e08buzbee case kMips: 553fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset; 554b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 5551fd3346740dfb7f47be9922312b68a4227fada96buzbee default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set; 556b046e16d8b8da318d6055f9308950131f1255e08buzbee } 5571fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 558fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset; 559a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 560fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 5610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2])); 562fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5641fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 565a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] key: 0x" 566a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << keys[elems] << ", disp: 0x" 567a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 568e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5692da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, keys[elems]); 5702da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, 571fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->targets[elems]->offset - bx_offset); 572a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 573a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 574fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 575a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 576fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 577fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5781fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 579a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] disp: 0x" 580a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 581e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5822da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, tab_rec->targets[elems]->offset - bx_offset); 583a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 584e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 585a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 586e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 587e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 588e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */ 5892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() { 590862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 591a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 592862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 593fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5941fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 595fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < (tab_rec->size + 1) / 2; i++) { 596df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back(tab_rec->table[i] & 0xFF); 597df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF); 598e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 599a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 600e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 601e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 6020d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) { 60302c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; lir != NULL; lir = lir->next) { 604a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->offset = offset; 605a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset += 4; 606a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 607a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 608e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 609e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 610ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogersstatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset, 611ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int element_size) { 6120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Align to natural pointer size. 613660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe offset = RoundUp(offset, element_size); 6140d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee for (; lir != NULL; lir = lir->next) { 6150d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->offset = offset; 6160d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset += element_size; 6170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 6180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee return offset; 6190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 6200d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 6216459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry 6222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() { 62306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 62406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::vector<uint32_t> dex_pcs; 62506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.reserve(table.DexToPcSize()); 62606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) { 62706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.push_back(it.DexPc()); 62806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 62906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_. 63006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::sort(dex_pcs.begin(), dex_pcs.end()); 63106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 6326459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee bool success = true; 63306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko auto it = dex_pcs.begin(), end = dex_pcs.end(); 63406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t dex_pc : mir_graph_->catches_) { 63506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko while (it != end && *it < dex_pc) { 63606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it; 63706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 6386459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 6396459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 64006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (it == end || *it > dex_pc) { 64106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc; 6426459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 64306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } else { 64406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 6456459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6466459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6476459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee if (!success) { 6481fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 6491fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: " 65006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko << table.DexToPcSize(); 6516459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6526459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee return success; 6536459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee} 6546459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee 655311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 6562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() { 6571e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_data_size = 0u; 6581e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_entries = 0u; 6591e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_offset = 0u; 6601e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_dalvik_offset = 0u; 6611e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_data_size = 0u; 6621e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_entries = 0u; 6631e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_offset = 0u; 6641e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_dalvik_offset = 0u; 6651fd3346740dfb7f47be9922312b68a4227fada96buzbee for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 666fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 6671e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_entries += 1; 6681e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 6691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset); 6701e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6711e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 6721e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = tgt_lir->offset; 6731e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 674a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee } 675fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 6761e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_entries += 1; 6771e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 6781e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset); 6791e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6801e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 6811e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_offset = tgt_lir->offset; 6821e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 683e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 684a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6851e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6861e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t total_entries = pc2dex_entries + dex2pc_entries; 6871e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries); 6881e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size; 68906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko encoded_mapping_table_.resize(data_size); 69006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos = &encoded_mapping_table_[0]; 69106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, total_entries); 69206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries); 69306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size); 69406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos2 = write_pos + pc2dex_data_size; 6951e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6961e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = 0u; 6971e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = 0u; 69806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = 0u; 69906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = 0u; 70006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 70106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 70206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 70306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset); 70406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) - 70506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 70606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_offset = tgt_lir->offset; 70706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 70806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 70906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 71006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 71106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset); 71206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) - 71306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 71406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = tgt_lir->offset; 71506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 71606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 7171e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko } 71806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), 71906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko hdr_data_size + pc2dex_data_size); 72006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size); 7211e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 72296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (kIsDebugBuild) { 72306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(VerifyCatchEntries()); 72406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 72596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // Verify the encoded table holds the expected data. 72606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 72796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.TotalSize(), total_entries); 72896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.PcToDexSize(), pc2dex_entries); 7291e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it = table.PcToDexBegin(); 7301e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it2 = table.DexToPcBegin(); 73106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 73206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 73306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it.NativePcOffset()); 73406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc()); 73506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 73606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 73706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 73806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it2.NativePcOffset()); 73906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc()); 74006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it2; 74106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 74296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 74306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(it == table.PcToDexEnd()); 7441e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko CHECK(it2 == table.DexToPcEnd()); 745311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 746e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 747e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7481fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() { 74906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(!encoded_mapping_table_.empty()); 75006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable mapping_table(&encoded_mapping_table_[0]); 7510c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t max_native_offset = 0; 75206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 75306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 7540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers if (native_offset > max_native_offset) { 7550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers max_native_offset = native_offset; 7560c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7570c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 75851c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReference method_ref(cu_->dex_file, cu_->method_idx); 7592730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko const std::vector<uint8_t>& gc_map_raw = 7602730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap(); 7612730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]); 7622730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize()); 7630c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Compute native offset to references size. 76492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray GcMapBuilder native_gc_map_builder(&native_gc_map_, 76592cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray mapping_table.PcToDexSize(), 76692cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray max_native_offset, dex_gc_map.RegWidth()); 7670c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 76806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 76906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 77006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t dex_pc = it.DexPc(); 7710c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false); 772f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc << 773f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison ": " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 774a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee native_gc_map_builder.AddEntry(native_offset, references); 7750c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 77625fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier 77725fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier // Maybe not necessary, but this could help prevent errors where we access the verified method 77825fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier // after it has been deleted. 77925fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier mir_graph_->GetCurrentDexCompilationUnit()->ClearVerifiedMethod(); 7800c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers} 7810c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 782e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */ 7830d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) { 7841fd3346740dfb7f47be9922312b68a4227fada96buzbee offset = AssignLiteralOffsetCommon(literal_list_, offset); 785ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int ptr_size = GetInstructionSetPointerSize(cu_->instruction_set); 786ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size); 787ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size); 788ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size); 789807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier offset = AssignLiteralPointerOffsetCommon(string_literal_list_, offset, ptr_size); 790a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 791e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 792e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) { 794862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 795a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 7960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 797fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 798fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 800fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * (sizeof(int) * 2); 801a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 802fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 803a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 804fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * sizeof(int); 805e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 806a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 808e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 809e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 8100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) { 811862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 812a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 813862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 814fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 815fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 816fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->size; 817a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // word align 818660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe offset = RoundUp(offset, 4); 819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 821e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 822e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 82331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik 825b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block 826b48819db07f9a0992a72173380c24249d7fc648abuzbee * label. The selected label will be used to fix up the case 827252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase. All resource flags 828252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion. KeyVal is just there for debugging. 82931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 8300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) { 831252254b130067cd7a5071865e793966871ae0246buzbee LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id]; 832b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* res = boundary_lir; 833b48819db07f9a0992a72173380c24249d7fc648abuzbee if (cu_->verbose) { 834b48819db07f9a0992a72173380c24249d7fc648abuzbee // Only pay the expense if we're pretty-printing. 83583cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR)); 836b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->dalvik_offset = vaddr; 837b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->opcode = kPseudoCaseLabel; 838b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->operands[0] = keyVal; 839b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->flags.fixup = kFixupLabel; 840b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!new_label->flags.use_def_invalid); 8418dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko new_label->u.m.def_mask = &kEncodeAll; 842b48819db07f9a0992a72173380c24249d7fc648abuzbee InsertLIRAfter(boundary_lir, new_label); 843b48819db07f9a0992a72173380c24249d7fc648abuzbee res = new_label; 844b48819db07f9a0992a72173380c24249d7fc648abuzbee } 845b48819db07f9a0992a72173380c24249d7fc648abuzbee return res; 84631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 849fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 8510d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]); 852a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 853fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8551fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key); 856a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 85731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8590d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 860fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 862a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 865a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8661fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]); 867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 86831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() { 871862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 872a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 873862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable *tab_rec = iterator.Next(); 874fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 875fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) { 8761fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkPackedCaseLabels(tab_rec); 877fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 8781fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkSparseCaseLabels(tab_rec); 879a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 880a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Invalid switch table"; 88131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 882a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 88331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 88431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8852ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) { 886a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sparse switch data format: 888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0200 magic value 889a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table; > 0 890a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 891a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 892a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 893a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (2+size*4) 16-bit code units. 894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 895eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 896a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 899a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Sparse switch table - ident:0x" << std::hex << ident 900a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << ", entries: " << std::dec << entries; 901a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 902a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Key[" << keys[i] << "] -> 0x" << std::hex << targets[i]; 903a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 90431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 90531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 9062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) { 907a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 908a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Packed switch data format: 909a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0100 magic value 910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table 911a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int first_key first (and lowest) switch case value 912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 914a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (4+size*2) 16-bit code units. 915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 916eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 9170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]); 918a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 919fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 920a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident 921fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee << ", entries: " << std::dec << entries << ", low_key: " << low_key; 922a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 923fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << " Key[" << (i + low_key) << "] -> 0x" << std::hex 924a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << targets[i]; 925a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 92631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 927e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 928252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */ 9290d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) { 9300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 9310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str))); 932d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee} 933e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 9342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) { 935e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee bool is_taken; 936e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee switch (opcode) { 937e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQ: is_taken = (src1 == src2); break; 938e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NE: is_taken = (src1 != src2); break; 939e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LT: is_taken = (src1 < src2); break; 940e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GE: is_taken = (src1 >= src2); break; 941e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GT: is_taken = (src1 > src2); break; 942e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LE: is_taken = (src1 <= src2); break; 943e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQZ: is_taken = (src1 == 0); break; 944e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NEZ: is_taken = (src1 != 0); break; 945e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LTZ: is_taken = (src1 < 0); break; 946e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GEZ: is_taken = (src1 >= 0); break; 947e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GTZ: is_taken = (src1 > 0); break; 948e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LEZ: is_taken = (src1 <= 0); break; 949e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee default: 950e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee LOG(FATAL) << "Unexpected opcode " << opcode; 951e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee is_taken = false; 952e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee } 953e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return is_taken; 954e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 955e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 9564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1 9571fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) { 9584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee ConditionCode res; 9594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee switch (before) { 9604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondEq: res = kCondEq; break; 9614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondNe: res = kCondNe; break; 9624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLt: res = kCondGt; break; 9634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGt: res = kCondLt; break; 9644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLe: res = kCondGe; break; 9654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGe: res = kCondLe; break; 9664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee default: 9674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res = static_cast<ConditionCode>(0); 9684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LOG(FATAL) << "Unexpected ccode " << before; 9694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 9714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 9724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 973a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir MarkoConditionCode Mir2Lir::NegateComparison(ConditionCode before) { 974a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko ConditionCode res; 975a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko switch (before) { 976a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondEq: res = kCondNe; break; 977a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondNe: res = kCondEq; break; 978a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLt: res = kCondGe; break; 979a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGt: res = kCondLe; break; 980a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLe: res = kCondGt; break; 981a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGe: res = kCondLt; break; 982a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko default: 983a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko res = static_cast<ConditionCode>(0); 984a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko LOG(FATAL) << "Unexpected ccode " << before; 985a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko } 986a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko return res; 987a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko} 988a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko 989862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc 990862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 9916282dc12440a2072dc06a616160027ff21bd895eIan Rogers : Backend(arena), 9926282dc12440a2072dc06a616160027ff21bd895eIan Rogers literal_list_(NULL), 9931fd3346740dfb7f47be9922312b68a4227fada96buzbee method_literal_list_(NULL), 994be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi class_literal_list_(NULL), 995807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier string_literal_list_(NULL), 9961fd3346740dfb7f47be9922312b68a4227fada96buzbee code_literal_list_(NULL), 997b48819db07f9a0992a72173380c24249d7fc648abuzbee first_fixup_(NULL), 9981fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 9991fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_(mir_graph), 1000862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee switch_tables_(arena, 4, kGrowableArraySwitchTables), 1001862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee fill_array_data_(arena, 4, kGrowableArrayFillArrayData), 1002bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee tempreg_info_(arena, 20, kGrowableArrayMisc), 1003091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reginfo_map_(arena, RegStorage::kMaxRegs, kGrowableArrayMisc), 10040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee pointer_storage_(arena, 128, kGrowableArrayMisc), 10051fd3346740dfb7f47be9922312b68a4227fada96buzbee data_offset_(0), 10061fd3346740dfb7f47be9922312b68a4227fada96buzbee total_size_(0), 10071fd3346740dfb7f47be9922312b68a4227fada96buzbee block_label_list_(NULL), 1008d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee promotion_map_(NULL), 1009862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee current_dalvik_offset_(0), 1010b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_(0), 1011862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee reg_pool_(NULL), 10121fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_(0), 10138081d2b8d7a743729557051d0294e040e61c747aVladimir Marko core_vmap_table_(mir_graph->GetArena()->Adapter()), 10148081d2b8d7a743729557051d0294e040e61c747aVladimir Marko fp_vmap_table_(mir_graph->GetArena()->Adapter()), 10151fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_(0), 10161fd3346740dfb7f47be9922312b68a4227fada96buzbee num_fp_spills_(0), 10171fd3346740dfb7f47be9922312b68a4227fada96buzbee frame_size_(0), 10181fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_(0), 10191fd3346740dfb7f47be9922312b68a4227fada96buzbee fp_spill_mask_(0), 10201fd3346740dfb7f47be9922312b68a4227fada96buzbee first_lir_insn_(NULL), 1021bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison last_lir_insn_(NULL), 10228dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko slow_paths_(arena, 32, kGrowableArraySlowPaths), 10238dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mem_ref_type_(ResourceMask::kHeapRef), 10248dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask_cache_(arena) { 10250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Reserve pointer id 0 for NULL. 10260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee size_t null_idx = WrapPointer(NULL); 10270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_idx, 0U); 10281fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10291fd3346740dfb7f47be9922312b68a4227fada96buzbee 10301fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() { 1031a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("RegisterAllocation"); 10321fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitializeRegAlloc(); // Needs to happen after SSA naming 10331fd3346740dfb7f47be9922312b68a4227fada96buzbee 10341fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Allocate Registers using simple local allocation scheme */ 10351fd3346740dfb7f47be9922312b68a4227fada96buzbee SimpleRegAlloc(); 10361fd3346740dfb7f47be9922312b68a4227fada96buzbee 10373bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* First try the custom light codegen for special cases. */ 10385816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr); 10393bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru bool special_worked = cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file) 10405816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko ->GenSpecial(this, cu_->method_idx); 10411fd3346740dfb7f47be9922312b68a4227fada96buzbee 10423bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* Take normal path for converting MIR to LIR only if the special codegen did not succeed. */ 10433bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (special_worked == false) { 10441fd3346740dfb7f47be9922312b68a4227fada96buzbee MethodMIR2LIR(); 10451fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10461fd3346740dfb7f47be9922312b68a4227fada96buzbee 10471fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Method is not empty */ 10481fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_) { 10491fd3346740dfb7f47be9922312b68a4227fada96buzbee // mark the targets of switch statement case labels 10501fd3346740dfb7f47be9922312b68a4227fada96buzbee ProcessSwitchTables(); 10511fd3346740dfb7f47be9922312b68a4227fada96buzbee 10521fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Convert LIR into machine code. */ 10531fd3346740dfb7f47be9922312b68a4227fada96buzbee AssembleLIR(); 10541fd3346740dfb7f47be9922312b68a4227fada96buzbee 1055b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee if ((cu_->enable_debug & (1 << kDebugCodegenDump)) != 0) { 10561fd3346740dfb7f47be9922312b68a4227fada96buzbee CodegenDump(); 10571fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10581fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10591fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10601fd3346740dfb7f47be9922312b68a4227fada96buzbee 10611fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() { 10622e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Combine vmap tables - core regs, then fp regs - into vmap_table. 10632e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko Leb128EncodingVector vmap_encoder; 10641fd3346740dfb7f47be9922312b68a4227fada96buzbee if (frame_size_ > 0) { 10652e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Prefix the encoded data with its size. 10662e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size(); 10672e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.Reserve(size + 1u); // All values are likely to be one byte in ULEB128 (<128). 10682e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(size); 10692e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Core regs may have been inserted out of order - sort first. 10702e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); 10712e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { 10722e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Copy, stripping out the phys register sort key. 10732e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned( 10742e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment)); 10752e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10762e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Push a marker to take place of lr. 10772e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker); 1078c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov if (cu_->instruction_set == kThumb2) { 1079c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // fp regs already sorted. 1080c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { 1081c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment); 1082c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } 1083c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } else { 1084c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // For other platforms regs may have been inserted out of order - sort first. 1085c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov std::sort(fp_vmap_table_.begin(), fp_vmap_table_.end()); 1086c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov for (size_t i = 0 ; i < fp_vmap_table_.size(); ++i) { 1087c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // Copy, stripping out the phys register sort key. 1088c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov vmap_encoder.PushBackUnsigned( 1089c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov ~(-1 << VREG_NUM_WIDTH) & (fp_vmap_table_[i] + VmapTable::kEntryAdjustment)); 1090c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } 10912e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10921fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10938194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(core_spill_mask_), 0); 10948194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(fp_spill_mask_), 0); 10952e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(core_vmap_table_.size(), 0u); 10962e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(fp_vmap_table_.size(), 0u); 10972e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(0u); // Size is 0. 10981fd3346740dfb7f47be9922312b68a4227fada96buzbee } 1099ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 1100700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<std::vector<uint8_t>> cfi_info(ReturnCallFrameInformation()); 110162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe ArrayRef<const uint8_t> cfi_ref; 110262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe if (cfi_info.get() != nullptr) { 110362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe cfi_ref = ArrayRef<const uint8_t>(*cfi_info); 110462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe } 110562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe return CompiledMethod::SwapAllocCompiledMethod( 110662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe cu_->compiler_driver, cu_->instruction_set, 110762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe ArrayRef<const uint8_t>(code_buffer_), 110862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe frame_size_, core_spill_mask_, fp_spill_mask_, 110962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe ArrayRef<const uint8_t>(encoded_mapping_table_), 111062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe ArrayRef<const uint8_t>(vmap_encoder.GetData()), 111162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe ArrayRef<const uint8_t>(native_gc_map_), 111262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe cfi_ref); 11131fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11141fd3346740dfb7f47be9922312b68a4227fada96buzbee 1115da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const { 1116da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Chose a reasonably small value in order to contain stack growth. 1117da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Backends that are smarter about spill region can return larger values. 1118da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru const size_t max_compiler_temps = 10; 1119da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return max_compiler_temps; 1120da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1121da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 1122da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() { 1123da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // By default assume that the Mir2Lir will need one slot for each temporary. 1124da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // If the backend can better determine temps that have non-overlapping ranges and 1125da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // temps that do not need spilled, it can actually provide a small region. 1126da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t)); 1127da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1128da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 11291fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() { 11301fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Figure out the frame size */ 1131f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko uint32_t size = num_core_spills_ * GetBytesPerGprSpillLocation(cu_->instruction_set) 1132f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + num_fp_spills_ * GetBytesPerFprSpillLocation(cu_->instruction_set) 1133f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + sizeof(uint32_t) // Filler. 1134f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + (cu_->num_regs + cu_->num_outs) * sizeof(uint32_t) 1135f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + GetNumBytesForCompilerTempSpillRegion(); 11361fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Align and set */ 1137660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe return RoundUp(size, kStackAlignment); 11381fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11391fd3346740dfb7f47be9922312b68a4227fada96buzbee 11401fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11411fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation 11421fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit 11431fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11442ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) { 11451fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_ == NULL) { 11461fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(last_lir_insn_ == NULL); 11471fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = first_lir_insn_ = lir; 11481fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = lir->next = NULL; 11491fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 11501fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_->next = lir; 11511fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = last_lir_insn_; 11521fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->next = NULL; 11531fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = lir; 11541fd3346740dfb7f47be9922312b68a4227fada96buzbee } 11551fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11561fd3346740dfb7f47be9922312b68a4227fada96buzbee 11571fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11581fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the 11591fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 11601fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11611fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir 11621fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11632ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) { 11641fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(current_lir->prev != NULL); 11651fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR *prev_lir = current_lir->prev; 11661fd3346740dfb7f47be9922312b68a4227fada96buzbee 11671fd3346740dfb7f47be9922312b68a4227fada96buzbee prev_lir->next = new_lir; 11681fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = prev_lir; 11691fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir; 11701fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->prev = new_lir; 11711fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11721fd3346740dfb7f47be9922312b68a4227fada96buzbee 11731fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11741fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the 11753c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe * last instruction. 11761fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11771fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next 11781fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11792ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) { 11801fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = current_lir; 11811fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir->next; 11821fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->next = new_lir; 11831fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next->prev = new_lir; 11841fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11851fd3346740dfb7f47be9922312b68a4227fada96buzbee 11864708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) { 11874708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (x & (x - 1)) == 0; 11884708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11894708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11904708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'. 11914708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) { 11924708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell int bit_posn = 0; 11934708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 0xf) == 0) { 11944708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn += 4; 11954708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 4; 11964708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11974708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 1) == 0) { 11984708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn++; 11994708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 1; 12004708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 12014708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return bit_posn; 12024708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 12034708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 12044708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) { 12054708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_src.wide); 12064708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_dest.wide); 12074708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1); 12084708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 12094708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 12102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, 121169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison int offset, int check_value, LIR* target, LIR** compare) { 1212766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell // Handle this for architectures that can't compare to memory. 121369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison LIR* inst = Load32Disp(base_reg, offset, temp_reg); 121469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (compare != nullptr) { 121569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison *compare = inst; 121669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 1217766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target); 1218766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 1219766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 1220766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 1221bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allisonvoid Mir2Lir::AddSlowPath(LIRSlowPath* slowpath) { 1222bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison slow_paths_.Insert(slowpath); 1223bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison} 122455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 122549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadCodeAddress(const MethodReference& target_method, InvokeType type, 122649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 1227a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko LIR* data_target = ScanLiteralPoolMethod(code_literal_list_, target_method); 122855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 1229a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = AddWordData(&code_literal_list_, target_method.dex_method_index); 123049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 1231a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have 1232a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // the same method invoked with kVirtual, kSuper and kInterface but the class linker will 1233a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // resolve these invokes to the same method, so we don't care which one we record here. 123449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 123555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1236a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads a code pointer. Code from oat file can be mapped anywhere. 1237a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu LIR* load_pc_rel = OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target); 123855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 123955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 124055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 124155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 124249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type, 124349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 1244a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko LIR* data_target = ScanLiteralPoolMethod(method_literal_list_, target_method); 124555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 1246a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = AddWordData(&method_literal_list_, target_method.dex_method_index); 124749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 1248a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have 1249a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // the same method invoked with kVirtual, kSuper and kInterface but the class linker will 1250a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // resolve these invokes to the same method, so we don't care which one we record here. 125149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 125255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1253a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads an ArtMethod pointer, which is a reference as it lives in the heap. 1254ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); 125555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 125655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 125755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 125855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 125955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendellvoid Mir2Lir::LoadClassType(uint32_t type_idx, SpecialTargetRegister symbolic_reg) { 126055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell // Use the literal pool and a PC-relative load from a data word. 126155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0); 126255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == nullptr) { 126355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell data_target = AddWordData(&class_literal_list_, type_idx); 126455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1265a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads a Class pointer, which is a reference as it lives in the heap. 1266ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); 126755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 126855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 126955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 1270807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartiervoid Mir2Lir::LoadString(uint32_t string_idx, RegStorage target_reg) { 1271807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier // Use the literal pool and a PC-relative load from a data word. 1272807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier LIR* data_target = ScanLiteralPool(string_literal_list_, string_idx, 0); 1273807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier if (data_target == nullptr) { 1274807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier data_target = AddWordData(&string_literal_list_, string_idx); 1275807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier } 1276807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier // Loads a Class pointer, which is a reference as it lives in the heap. 1277807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier LIR* load_pc_rel = OpPcRelLoad(target_reg, data_target); 1278807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier AppendLIR(load_pc_rel); 1279807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier} 1280807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier 1281ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstd::vector<uint8_t>* Mir2Lir::ReturnCallFrameInformation() { 1282ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Default case is to do nothing. 1283ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell return nullptr; 1284ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 1285ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 12862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) { 1287091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.location == kLocPhysReg) { 128885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(!loc.reg.Is32Bit()); 1289091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.reg.IsPair()) { 129085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow()); 129185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh()); 129285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_lo->SetIsWide(false); 129385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_hi->SetIsWide(false); 129485089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.reg = info_lo->GetReg(); 1295091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } else { 129685089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info = GetRegInfo(loc.reg); 129785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask); 129885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(info_new != nullptr); 129985089dd28a39dd20f42ac258398b2a08668f9ef1buzbee if (info->IsLive() && (info->SReg() == loc.s_reg_low)) { 130085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info->MarkDead(); 130185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_new->MarkLive(loc.s_reg_low); 130285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee } 130385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.reg = info_new->GetReg(); 1304091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } 130585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(loc.reg.Valid()); 13062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee } 130785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.wide = false; 13082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return loc; 13092700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee} 13102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee 1311d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendellvoid Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) { 1312d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell LOG(FATAL) << "Unknown MIR opcode not supported on this architecture"; 1313d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell} 1314d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 13157934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 1316