12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 17193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#ifndef ART_COMPILER_COMPILED_METHOD_H_ 18193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#define ART_COMPILER_COMPILED_METHOD_H_ 193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 21cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko#include <iosfwd> 22265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include <string> 233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include <vector> 243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h" 2680afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 27e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light#include "base/length_prefixed_array.h" 28f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko#include "method_reference.h" 29f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko#include "utils/array_ref.h" 303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromnamespace art { 323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 33193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartierclass CompilerDriver; 3435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoclass CompiledMethodStorage; 35193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 36598c513a2737d872e22ea8bcedec61b92deff357Logan Chienclass CompiledCode { 37598c513a2737d872e22ea8bcedec61b92deff357Logan Chien public: 38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // For Quick to supply an code blob 39193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 4035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const uint8_t>& quick_code); 41e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 42e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier virtual ~CompiledCode(); 43598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 44598c513a2737d872e22ea8bcedec61b92deff357Logan Chien InstructionSet GetInstructionSet() const { 45598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return instruction_set_; 46598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 47598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 4835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko ArrayRef<const uint8_t> GetQuickCode() const { 4935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return GetArray(quick_code_); 50598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 51598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 52ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers bool operator==(const CompiledCode& rhs) const; 53ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 54598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // To align an offset from a page-aligned value to make it suitable 55598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // for code storage. For example on ARM, to ensure that PC relative 56598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // valu computations work out as expected. 57e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier size_t AlignCode(size_t offset) const; 58e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier static size_t AlignCode(size_t offset, InstructionSet instruction_set); 59598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 60598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // returns the difference between the code address and a usable PC. 61598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // mainly to cope with kThumb2 where the lower bit must be set. 62598c513a2737d872e22ea8bcedec61b92deff357Logan Chien size_t CodeDelta() const; 6350abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison static size_t CodeDelta(InstructionSet instruction_set); 64598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 65598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // Returns a pointer suitable for invoking the code at the argument 66598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // code_pointer address. Mainly to cope with kThumb2 where the 67598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // lower bit must be set to indicate Thumb mode. 68598c513a2737d872e22ea8bcedec61b92deff357Logan Chien static const void* CodePointer(const void* code_pointer, 69598c513a2737d872e22ea8bcedec61b92deff357Logan Chien InstructionSet instruction_set); 70598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 7135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko protected: 7235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko template <typename T> 7335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko static ArrayRef<const T> GetArray(const LengthPrefixedArray<T>* array) { 7435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko if (array == nullptr) { 7535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return ArrayRef<const T>(); 7635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko } 7735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko DCHECK_NE(array->size(), 0u); 7835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return ArrayRef<const T>(&array->At(0), array->size()); 7935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko } 8035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko 8135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko CompilerDriver* GetCompilerDriver() { 8235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return compiler_driver_; 8335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko } 84265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 85598c513a2737d872e22ea8bcedec61b92deff357Logan Chien private: 86ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CompilerDriver* const compiler_driver_; 87193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 88598c513a2737d872e22ea8bcedec61b92deff357Logan Chien const InstructionSet instruction_set_; 898227cc1b46f36aed77745ea15de2f435e04c5337Brian Carlstrom 90ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // Used to store the PIC code for Quick. 9135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const LengthPrefixedArray<uint8_t>* const quick_code_; 92598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}; 93598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 94e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass SrcMapElem { 95e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban public: 96e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban uint32_t from_; 97e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban int32_t to_; 9835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}; 99e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban 10035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoinline bool operator<(const SrcMapElem& lhs, const SrcMapElem& rhs) { 10135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko if (lhs.from_ != rhs.from_) { 10235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return lhs.from_ < rhs.from_; 103e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban } 10435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return lhs.to_ < rhs.to_; 10535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko} 10635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko 10735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoinline bool operator==(const SrcMapElem& lhs, const SrcMapElem& rhs) { 10835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return lhs.from_ == rhs.from_ && lhs.to_ == rhs.to_; 10935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko} 110e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban 111e21dc3db191df04c100620965bee4617b3b24397Andreas Gampetemplate <class Allocator> 112e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeclass SrcMap FINAL : public std::vector<SrcMapElem, Allocator> { 113e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban public: 114e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::begin; 115e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using typename std::vector<SrcMapElem, Allocator>::const_iterator; 116e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::empty; 117e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::end; 118e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::resize; 119e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::shrink_to_fit; 120e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe using std::vector<SrcMapElem, Allocator>::size; 121e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 122e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe explicit SrcMap() {} 123e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier explicit SrcMap(const Allocator& alloc) : std::vector<SrcMapElem, Allocator>(alloc) {} 124e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 125e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe template <class InputIt> 126e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe SrcMap(InputIt first, InputIt last, const Allocator& alloc) 127e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe : std::vector<SrcMapElem, Allocator>(first, last, alloc) {} 128e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 1296f7158927fee233255f8e96719c374694b10cad3David Srbecky void push_back(const SrcMapElem& elem) { 130e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban if (!empty()) { 1316f7158927fee233255f8e96719c374694b10cad3David Srbecky // Check that the addresses are inserted in sorted order. 1326f7158927fee233255f8e96719c374694b10cad3David Srbecky DCHECK_GE(elem.from_, this->back().from_); 1336f7158927fee233255f8e96719c374694b10cad3David Srbecky // If two consequitive entries map to the same value, ignore the later. 1346f7158927fee233255f8e96719c374694b10cad3David Srbecky // E.g. for map {{0, 1}, {4, 1}, {8, 2}}, all values in [0,8) map to 1. 1356f7158927fee233255f8e96719c374694b10cad3David Srbecky if (elem.to_ == this->back().to_) { 1366f7158927fee233255f8e96719c374694b10cad3David Srbecky return; 137e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban } 1386f7158927fee233255f8e96719c374694b10cad3David Srbecky } 1396f7158927fee233255f8e96719c374694b10cad3David Srbecky std::vector<SrcMapElem, Allocator>::push_back(elem); 1406f7158927fee233255f8e96719c374694b10cad3David Srbecky } 1416f7158927fee233255f8e96719c374694b10cad3David Srbecky 1426f7158927fee233255f8e96719c374694b10cad3David Srbecky // Returns true and the corresponding "to" value if the mapping is found. 1436f7158927fee233255f8e96719c374694b10cad3David Srbecky // Oterwise returns false and 0. 1446f7158927fee233255f8e96719c374694b10cad3David Srbecky std::pair<bool, int32_t> Find(uint32_t from) const { 1456f7158927fee233255f8e96719c374694b10cad3David Srbecky // Finds first mapping such that lb.from_ >= from. 1466f7158927fee233255f8e96719c374694b10cad3David Srbecky auto lb = std::lower_bound(begin(), end(), SrcMapElem {from, INT32_MIN}); 1476f7158927fee233255f8e96719c374694b10cad3David Srbecky if (lb != end() && lb->from_ == from) { 1486f7158927fee233255f8e96719c374694b10cad3David Srbecky // Found exact match. 1496f7158927fee233255f8e96719c374694b10cad3David Srbecky return std::make_pair(true, lb->to_); 1506f7158927fee233255f8e96719c374694b10cad3David Srbecky } else if (lb != begin()) { 1516f7158927fee233255f8e96719c374694b10cad3David Srbecky // The previous mapping is still in effect. 1526f7158927fee233255f8e96719c374694b10cad3David Srbecky return std::make_pair(true, (--lb)->to_); 1536f7158927fee233255f8e96719c374694b10cad3David Srbecky } else { 1546f7158927fee233255f8e96719c374694b10cad3David Srbecky // Not found because 'from' is smaller than first entry in the map. 1556f7158927fee233255f8e96719c374694b10cad3David Srbecky return std::make_pair(false, 0); 156e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban } 157e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban } 158e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban}; 159e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban 160e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeusing DefaultSrcMap = SrcMap<std::allocator<SrcMapElem>>; 161e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 162f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Markoclass LinkerPatch { 163f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko public: 164ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // Note: We explicitly specify the underlying type of the enum because GCC 165ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // would otherwise select a bigger underlying type and then complain that 166ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // 'art::LinkerPatch::patch_type_' is too small to hold all 167ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // values of 'enum class art::LinkerPatch::Type' 168ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // which is ridiculous given we have only a handful of values here. If we 169ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // choose to squeeze the Type into fewer than 8 bits, we'll have to declare 170ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko // patch_type_ as an uintN_t and do explicit static_cast<>s. 171ef88a1104ac07260e7eee498c6e4e4cc2506b063Vladimir Marko enum class Type : uint8_t { 172db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kRecordPosition, // Just record patch position for patchoat. 173db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kMethod, 174db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kCall, 175db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kCallRelative, // NOTE: Actual patching is instruction_set-dependent. 176db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kType, 177db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kString, 178db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kStringRelative, // NOTE: Actual patching is instruction_set-dependent. 179db8e62dca9232634daecb548bd51f3186004535cVladimir Marko kDexCacheArray, // NOTE: Actual patching is instruction_set-dependent. 180db8e62dca9232634daecb548bd51f3186004535cVladimir Marko }; 181db8e62dca9232634daecb548bd51f3186004535cVladimir Marko 182cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko static LinkerPatch RecordPosition(size_t literal_offset) { 183db8e62dca9232634daecb548bd51f3186004535cVladimir Marko return LinkerPatch(literal_offset, Type::kRecordPosition, /* target_dex_file */ nullptr); 184cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 185cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 186f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko static LinkerPatch MethodPatch(size_t literal_offset, 187f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* target_dex_file, 188f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko uint32_t target_method_idx) { 189db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kMethod, target_dex_file); 19020f85597828194c12be10d3a927999def066555eVladimir Marko patch.method_idx_ = target_method_idx; 19120f85597828194c12be10d3a927999def066555eVladimir Marko return patch; 192f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 193f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 194f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko static LinkerPatch CodePatch(size_t literal_offset, 195f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* target_dex_file, 196f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko uint32_t target_method_idx) { 197db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kCall, target_dex_file); 19820f85597828194c12be10d3a927999def066555eVladimir Marko patch.method_idx_ = target_method_idx; 19920f85597828194c12be10d3a927999def066555eVladimir Marko return patch; 200f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 201f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 202f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko static LinkerPatch RelativeCodePatch(size_t literal_offset, 203f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* target_dex_file, 204f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko uint32_t target_method_idx) { 205db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kCallRelative, target_dex_file); 20620f85597828194c12be10d3a927999def066555eVladimir Marko patch.method_idx_ = target_method_idx; 20720f85597828194c12be10d3a927999def066555eVladimir Marko return patch; 208f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 209f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 210f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko static LinkerPatch TypePatch(size_t literal_offset, 211f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* target_dex_file, 212f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko uint32_t target_type_idx) { 213db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kType, target_dex_file); 21420f85597828194c12be10d3a927999def066555eVladimir Marko patch.type_idx_ = target_type_idx; 21520f85597828194c12be10d3a927999def066555eVladimir Marko return patch; 21620f85597828194c12be10d3a927999def066555eVladimir Marko } 21720f85597828194c12be10d3a927999def066555eVladimir Marko 218cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko static LinkerPatch StringPatch(size_t literal_offset, 219cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko const DexFile* target_dex_file, 220cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t target_string_idx) { 221db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kString, target_dex_file); 222cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko patch.string_idx_ = target_string_idx; 223cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return patch; 224cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 225cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 226cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko static LinkerPatch RelativeStringPatch(size_t literal_offset, 227cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko const DexFile* target_dex_file, 228cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t pc_insn_offset, 229cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t target_string_idx) { 230db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kStringRelative, target_dex_file); 231cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko patch.string_idx_ = target_string_idx; 232cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko patch.pc_insn_offset_ = pc_insn_offset; 233cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return patch; 234cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 235cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 23620f85597828194c12be10d3a927999def066555eVladimir Marko static LinkerPatch DexCacheArrayPatch(size_t literal_offset, 23720f85597828194c12be10d3a927999def066555eVladimir Marko const DexFile* target_dex_file, 23820f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t pc_insn_offset, 23920f85597828194c12be10d3a927999def066555eVladimir Marko size_t element_offset) { 24020f85597828194c12be10d3a927999def066555eVladimir Marko DCHECK(IsUint<32>(element_offset)); 241db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch patch(literal_offset, Type::kDexCacheArray, target_dex_file); 24220f85597828194c12be10d3a927999def066555eVladimir Marko patch.pc_insn_offset_ = pc_insn_offset; 24320f85597828194c12be10d3a927999def066555eVladimir Marko patch.element_offset_ = element_offset; 24420f85597828194c12be10d3a927999def066555eVladimir Marko return patch; 245f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 246f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 247f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko LinkerPatch(const LinkerPatch& other) = default; 248f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko LinkerPatch& operator=(const LinkerPatch& other) = default; 249f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 250f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko size_t LiteralOffset() const { 251f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return literal_offset_; 252f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 253f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 254db8e62dca9232634daecb548bd51f3186004535cVladimir Marko Type GetType() const { 255f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return patch_type_; 256f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 257f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 25820f85597828194c12be10d3a927999def066555eVladimir Marko bool IsPcRelative() const { 259db8e62dca9232634daecb548bd51f3186004535cVladimir Marko switch (GetType()) { 260db8e62dca9232634daecb548bd51f3186004535cVladimir Marko case Type::kCallRelative: 261db8e62dca9232634daecb548bd51f3186004535cVladimir Marko case Type::kStringRelative: 262db8e62dca9232634daecb548bd51f3186004535cVladimir Marko case Type::kDexCacheArray: 263cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return true; 264cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko default: 265cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return false; 266cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 26720f85597828194c12be10d3a927999def066555eVladimir Marko } 26820f85597828194c12be10d3a927999def066555eVladimir Marko 269f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko MethodReference TargetMethod() const { 270db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kMethod || 271db8e62dca9232634daecb548bd51f3186004535cVladimir Marko patch_type_ == Type::kCall || 272db8e62dca9232634daecb548bd51f3186004535cVladimir Marko patch_type_ == Type::kCallRelative); 27320f85597828194c12be10d3a927999def066555eVladimir Marko return MethodReference(target_dex_file_, method_idx_); 274f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 275f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 276f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* TargetTypeDexFile() const { 277db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kType); 278f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return target_dex_file_; 279f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 280f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 281f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko uint32_t TargetTypeIndex() const { 282db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kType); 28320f85597828194c12be10d3a927999def066555eVladimir Marko return type_idx_; 28420f85597828194c12be10d3a927999def066555eVladimir Marko } 28520f85597828194c12be10d3a927999def066555eVladimir Marko 286cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko const DexFile* TargetStringDexFile() const { 287db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kString || patch_type_ == Type::kStringRelative); 288cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return target_dex_file_; 289cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 290cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 291cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t TargetStringIndex() const { 292db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kString || patch_type_ == Type::kStringRelative); 293cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko return string_idx_; 294cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko } 295cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko 29620f85597828194c12be10d3a927999def066555eVladimir Marko const DexFile* TargetDexCacheDexFile() const { 297db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kDexCacheArray); 29820f85597828194c12be10d3a927999def066555eVladimir Marko return target_dex_file_; 29920f85597828194c12be10d3a927999def066555eVladimir Marko } 30020f85597828194c12be10d3a927999def066555eVladimir Marko 30120f85597828194c12be10d3a927999def066555eVladimir Marko size_t TargetDexCacheElementOffset() const { 302db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kDexCacheArray); 30320f85597828194c12be10d3a927999def066555eVladimir Marko return element_offset_; 30420f85597828194c12be10d3a927999def066555eVladimir Marko } 30520f85597828194c12be10d3a927999def066555eVladimir Marko 30620f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t PcInsnOffset() const { 307db8e62dca9232634daecb548bd51f3186004535cVladimir Marko DCHECK(patch_type_ == Type::kStringRelative || patch_type_ == Type::kDexCacheArray); 30820f85597828194c12be10d3a927999def066555eVladimir Marko return pc_insn_offset_; 309f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 310f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 311f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko private: 312db8e62dca9232634daecb548bd51f3186004535cVladimir Marko LinkerPatch(size_t literal_offset, Type patch_type, const DexFile* target_dex_file) 31320f85597828194c12be10d3a927999def066555eVladimir Marko : target_dex_file_(target_dex_file), 31420f85597828194c12be10d3a927999def066555eVladimir Marko literal_offset_(literal_offset), 31520f85597828194c12be10d3a927999def066555eVladimir Marko patch_type_(patch_type) { 31620f85597828194c12be10d3a927999def066555eVladimir Marko cmp1_ = 0u; 31720f85597828194c12be10d3a927999def066555eVladimir Marko cmp2_ = 0u; 31820f85597828194c12be10d3a927999def066555eVladimir Marko // The compiler rejects methods that are too big, so the compiled code 31920f85597828194c12be10d3a927999def066555eVladimir Marko // of a single method really shouln't be anywhere close to 16MiB. 32020f85597828194c12be10d3a927999def066555eVladimir Marko DCHECK(IsUint<24>(literal_offset)); 321f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 322f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 323f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko const DexFile* target_dex_file_; 32420f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t literal_offset_ : 24; // Method code size up to 16MiB. 325db8e62dca9232634daecb548bd51f3186004535cVladimir Marko Type patch_type_ : 8; 32620f85597828194c12be10d3a927999def066555eVladimir Marko union { 32720f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t cmp1_; // Used for relational operators. 32820f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t method_idx_; // Method index for Call/Method patches. 32920f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t type_idx_; // Type index for Type patches. 330cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko uint32_t string_idx_; // String index for String patches. 33120f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t element_offset_; // Element offset in the dex cache arrays. 33235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko static_assert(sizeof(method_idx_) == sizeof(cmp1_), "needed by relational operators"); 33335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko static_assert(sizeof(type_idx_) == sizeof(cmp1_), "needed by relational operators"); 334cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko static_assert(sizeof(string_idx_) == sizeof(cmp1_), "needed by relational operators"); 33535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko static_assert(sizeof(element_offset_) == sizeof(cmp1_), "needed by relational operators"); 33620f85597828194c12be10d3a927999def066555eVladimir Marko }; 33720f85597828194c12be10d3a927999def066555eVladimir Marko union { 33834ed3afc41820c72a3c0ab9770be66b6668aa029Vladimir Marko // Note: To avoid uninitialized padding on 64-bit systems, we use `size_t` for `cmp2_`. 33934ed3afc41820c72a3c0ab9770be66b6668aa029Vladimir Marko // This allows a hashing function to treat an array of linker patches as raw memory. 34034ed3afc41820c72a3c0ab9770be66b6668aa029Vladimir Marko size_t cmp2_; // Used for relational operators. 34120f85597828194c12be10d3a927999def066555eVladimir Marko // Literal offset of the insn loading PC (same as literal_offset if it's the same insn, 34220f85597828194c12be10d3a927999def066555eVladimir Marko // may be different if the PC-relative addressing needs multiple insns). 34320f85597828194c12be10d3a927999def066555eVladimir Marko uint32_t pc_insn_offset_; 34434ed3afc41820c72a3c0ab9770be66b6668aa029Vladimir Marko static_assert(sizeof(pc_insn_offset_) <= sizeof(cmp2_), "needed by relational operators"); 34520f85597828194c12be10d3a927999def066555eVladimir Marko }; 346f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 347f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko friend bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs); 348f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko friend bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs); 349f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko}; 350db8e62dca9232634daecb548bd51f3186004535cVladimir Markostd::ostream& operator<<(std::ostream& os, const LinkerPatch::Type& type); 351f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 352f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Markoinline bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs) { 353f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return lhs.literal_offset_ == rhs.literal_offset_ && 354f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko lhs.patch_type_ == rhs.patch_type_ && 35520f85597828194c12be10d3a927999def066555eVladimir Marko lhs.target_dex_file_ == rhs.target_dex_file_ && 35620f85597828194c12be10d3a927999def066555eVladimir Marko lhs.cmp1_ == rhs.cmp1_ && 35720f85597828194c12be10d3a927999def066555eVladimir Marko lhs.cmp2_ == rhs.cmp2_; 358f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko} 359f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 360f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Markoinline bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs) { 361f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return (lhs.literal_offset_ != rhs.literal_offset_) ? lhs.literal_offset_ < rhs.literal_offset_ 362f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko : (lhs.patch_type_ != rhs.patch_type_) ? lhs.patch_type_ < rhs.patch_type_ 36320f85597828194c12be10d3a927999def066555eVladimir Marko : (lhs.target_dex_file_ != rhs.target_dex_file_) ? lhs.target_dex_file_ < rhs.target_dex_file_ 36420f85597828194c12be10d3a927999def066555eVladimir Marko : (lhs.cmp1_ != rhs.cmp1_) ? lhs.cmp1_ < rhs.cmp1_ 36520f85597828194c12be10d3a927999def066555eVladimir Marko : lhs.cmp2_ < rhs.cmp2_; 366f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko} 367f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 368e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass CompiledMethod FINAL : public CompiledCode { 3693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom public: 370e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe // Constructs a CompiledMethod. 371e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe // Note: Consider using the static allocation methods below that will allocate the CompiledMethod 372e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe // in the swap space. 37372d32629303f8f39362a4099481f48646aed042fIan Rogers CompiledMethod(CompilerDriver* driver, 374193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier InstructionSet instruction_set, 375e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& quick_code, 3763320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const size_t frame_size_in_bytes, 3773320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t core_spill_mask, 3783320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t fp_spill_mask, 37935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const SrcMapElem>& src_mapping_table, 380e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 381e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 382c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const ArrayRef<const LinkerPatch>& patches); 3833320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 384e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier virtual ~CompiledMethod(); 3850c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 386e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe static CompiledMethod* SwapAllocCompiledMethod( 387e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe CompilerDriver* driver, 388e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe InstructionSet instruction_set, 389e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& quick_code, 390e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const size_t frame_size_in_bytes, 391e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const uint32_t core_spill_mask, 392e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const uint32_t fp_spill_mask, 39335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const SrcMapElem>& src_mapping_table, 394e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 395e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 396c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const ArrayRef<const LinkerPatch>& patches); 397e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 398e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe static void ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m); 399e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe 4000c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers size_t GetFrameSizeInBytes() const { 4010c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return frame_size_in_bytes_; 4020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 4030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 4040c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t GetCoreSpillMask() const { 4050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return core_spill_mask_; 4060c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 4070c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 4080c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t GetFpSpillMask() const { 4090c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers return fp_spill_mask_; 4100c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 4113320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 41235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko ArrayRef<const SrcMapElem> GetSrcMappingTable() const { 41335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return GetArray(src_mapping_table_); 414e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban } 415e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban 41635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko ArrayRef<const uint8_t> GetVmapTable() const { 41735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return GetArray(vmap_table_); 4180c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 419e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 42035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko ArrayRef<const uint8_t> GetCFIInfo() const { 42135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return GetArray(cfi_info_); 422ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 423ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 424b207e1473dda1730604a28db2b4fa52f2998aeaeVladimir Marko ArrayRef<const LinkerPatch> GetPatches() const { 42535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return GetArray(patches_); 426f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 427f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 4283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom private: 429a1827042bb46161b452cd720d235fb1cdfefaa76Ian Rogers // For quick code, the size of the activation used by the code. 4300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const size_t frame_size_in_bytes_; 431a1827042bb46161b452cd720d235fb1cdfefaa76Ian Rogers // For quick code, a bit mask describing spilled GPR callee-save registers. 432169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers const uint32_t core_spill_mask_; 433a1827042bb46161b452cd720d235fb1cdfefaa76Ian Rogers // For quick code, a bit mask describing spilled FPR callee-save registers. 434169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers const uint32_t fp_spill_mask_; 4356f7158927fee233255f8e96719c374694b10cad3David Srbecky // For quick code, a set of pairs (PC, DEX) mapping from native PC offset to DEX offset. 43635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const LengthPrefixedArray<SrcMapElem>* const src_mapping_table_; 43796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed. 43835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const LengthPrefixedArray<uint8_t>* const vmap_table_; 439ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // For quick code, a FDE entry for the debug_frame section. 44035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const LengthPrefixedArray<uint8_t>* const cfi_info_; 441f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko // For quick code, linker patches needed by the method. 44235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const LengthPrefixedArray<LinkerPatch>* const patches_; 4433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}; 4443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 4453320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} // namespace art 4463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 447193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#endif // ART_COMPILER_COMPILED_METHOD_H_ 448