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