blob: a4d23870300ecbc30f6b1cafda31662f342a90ac [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian Carlstrom3320cf42011-10-04 14:58:28 -070016
Mathieu Chartier193bad92013-08-29 18:46:00 -070017#ifndef ART_COMPILER_COMPILED_METHOD_H_
18#define ART_COMPILER_COMPILED_METHOD_H_
Brian Carlstrom3320cf42011-10-04 14:58:28 -070019
Ian Rogers700a4022014-05-19 16:49:03 -070020#include <memory>
Brian Carlstrom265091e2013-01-30 14:08:26 -080021#include <string>
Brian Carlstrom3320cf42011-10-04 14:58:28 -070022#include <vector>
23
Ian Rogersd582fa42014-11-05 23:46:43 -080024#include "arch/instruction_set.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010025#include "base/bit_utils.h"
Vladimir Markof4da6752014-08-01 19:04:18 +010026#include "method_reference.h"
Vladimir Markof4da6752014-08-01 19:04:18 +010027#include "utils/array_ref.h"
Andreas Gampee21dc3d2014-12-08 16:59:43 -080028#include "utils/swap_space.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070029
30namespace art {
31
Mathieu Chartier193bad92013-08-29 18:46:00 -070032class CompilerDriver;
33
Logan Chien598c5132012-04-28 22:00:44 +080034class CompiledCode {
35 public:
Brian Carlstrom265091e2013-01-30 14:08:26 -080036 // For Quick to supply an code blob
Mathieu Chartier193bad92013-08-29 18:46:00 -070037 CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080038 const ArrayRef<const uint8_t>& quick_code, bool owns_code_array);
39
40 virtual ~CompiledCode();
Logan Chien598c5132012-04-28 22:00:44 +080041
Logan Chien598c5132012-04-28 22:00:44 +080042 InstructionSet GetInstructionSet() const {
43 return instruction_set_;
44 }
45
Andreas Gampee21dc3d2014-12-08 16:59:43 -080046 const SwapVector<uint8_t>* GetQuickCode() const {
Ian Rogersef7d42f2014-01-06 12:55:46 -080047 return quick_code_;
Logan Chien598c5132012-04-28 22:00:44 +080048 }
49
Ian Rogersef7d42f2014-01-06 12:55:46 -080050 bool operator==(const CompiledCode& rhs) const;
51
Logan Chien598c5132012-04-28 22:00:44 +080052 // To align an offset from a page-aligned value to make it suitable
53 // for code storage. For example on ARM, to ensure that PC relative
54 // valu computations work out as expected.
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080055 size_t AlignCode(size_t offset) const;
56 static size_t AlignCode(size_t offset, InstructionSet instruction_set);
Logan Chien598c5132012-04-28 22:00:44 +080057
58 // returns the difference between the code address and a usable PC.
59 // mainly to cope with kThumb2 where the lower bit must be set.
60 size_t CodeDelta() const;
Dave Allison50abf0a2014-06-23 13:19:59 -070061 static size_t CodeDelta(InstructionSet instruction_set);
Logan Chien598c5132012-04-28 22:00:44 +080062
63 // Returns a pointer suitable for invoking the code at the argument
64 // code_pointer address. Mainly to cope with kThumb2 where the
65 // lower bit must be set to indicate Thumb mode.
66 static const void* CodePointer(const void* code_pointer,
67 InstructionSet instruction_set);
68
Brian Carlstrom265091e2013-01-30 14:08:26 -080069 const std::vector<uint32_t>& GetOatdataOffsetsToCompliledCodeOffset() const;
70 void AddOatdataOffsetToCompliledCodeOffset(uint32_t offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -080071
Logan Chien598c5132012-04-28 22:00:44 +080072 private:
Ian Rogersef7d42f2014-01-06 12:55:46 -080073 CompilerDriver* const compiler_driver_;
Mathieu Chartier193bad92013-08-29 18:46:00 -070074
Logan Chien598c5132012-04-28 22:00:44 +080075 const InstructionSet instruction_set_;
Brian Carlstrom8227cc12013-03-06 14:26:48 -080076
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080077 // If we own the code array (means that we free in destructor).
78 const bool owns_code_array_;
79
Ian Rogersef7d42f2014-01-06 12:55:46 -080080 // Used to store the PIC code for Quick.
Andreas Gampee21dc3d2014-12-08 16:59:43 -080081 SwapVector<uint8_t>* quick_code_;
Brian Carlstrom265091e2013-01-30 14:08:26 -080082
Brian Carlstrom265091e2013-01-30 14:08:26 -080083 // There are offsets from the oatdata symbol to where the offset to
84 // the compiled method will be found. These are computed by the
85 // OatWriter and then used by the ElfWriter to add relocations so
86 // that MCLinker can update the values to the location in the linked .so.
87 std::vector<uint32_t> oatdata_offsets_to_compiled_code_offset_;
Logan Chien598c5132012-04-28 22:00:44 +080088};
89
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070090class SrcMapElem {
91 public:
92 uint32_t from_;
93 int32_t to_;
94
David Srbecky6f715892015-03-30 14:21:42 +010095 // Lexicographical compare.
96 bool operator<(const SrcMapElem& other) const {
97 if (from_ != other.from_) {
98 return from_ < other.from_;
99 }
100 return to_ < other.to_;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700101 }
102};
103
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800104template <class Allocator>
105class SrcMap FINAL : public std::vector<SrcMapElem, Allocator> {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700106 public:
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800107 using std::vector<SrcMapElem, Allocator>::begin;
108 using typename std::vector<SrcMapElem, Allocator>::const_iterator;
109 using std::vector<SrcMapElem, Allocator>::empty;
110 using std::vector<SrcMapElem, Allocator>::end;
111 using std::vector<SrcMapElem, Allocator>::resize;
112 using std::vector<SrcMapElem, Allocator>::shrink_to_fit;
113 using std::vector<SrcMapElem, Allocator>::size;
114
115 explicit SrcMap() {}
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800116 explicit SrcMap(const Allocator& alloc) : std::vector<SrcMapElem, Allocator>(alloc) {}
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800117
118 template <class InputIt>
119 SrcMap(InputIt first, InputIt last, const Allocator& alloc)
120 : std::vector<SrcMapElem, Allocator>(first, last, alloc) {}
121
David Srbecky6f715892015-03-30 14:21:42 +0100122 void push_back(const SrcMapElem& elem) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700123 if (!empty()) {
David Srbecky6f715892015-03-30 14:21:42 +0100124 // Check that the addresses are inserted in sorted order.
125 DCHECK_GE(elem.from_, this->back().from_);
126 // If two consequitive entries map to the same value, ignore the later.
127 // E.g. for map {{0, 1}, {4, 1}, {8, 2}}, all values in [0,8) map to 1.
128 if (elem.to_ == this->back().to_) {
129 return;
130 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700131 }
David Srbecky6f715892015-03-30 14:21:42 +0100132 std::vector<SrcMapElem, Allocator>::push_back(elem);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700133 }
134
David Srbecky6f715892015-03-30 14:21:42 +0100135 // Returns true and the corresponding "to" value if the mapping is found.
136 // Oterwise returns false and 0.
137 std::pair<bool, int32_t> Find(uint32_t from) const {
138 // Finds first mapping such that lb.from_ >= from.
139 auto lb = std::lower_bound(begin(), end(), SrcMapElem {from, INT32_MIN});
140 if (lb != end() && lb->from_ == from) {
141 // Found exact match.
142 return std::make_pair(true, lb->to_);
143 } else if (lb != begin()) {
144 // The previous mapping is still in effect.
145 return std::make_pair(true, (--lb)->to_);
146 } else {
147 // Not found because 'from' is smaller than first entry in the map.
148 return std::make_pair(false, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700149 }
150 }
151};
152
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800153using DefaultSrcMap = SrcMap<std::allocator<SrcMapElem>>;
154using SwapSrcMap = SrcMap<SwapAllocator<SrcMapElem>>;
155
156
Vladimir Markof4da6752014-08-01 19:04:18 +0100157enum LinkerPatchType {
158 kLinkerPatchMethod,
159 kLinkerPatchCall,
160 kLinkerPatchCallRelative, // NOTE: Actual patching is instruction_set-dependent.
161 kLinkerPatchType,
Vladimir Marko20f85592015-03-19 10:07:02 +0000162 kLinkerPatchDexCacheArray, // NOTE: Actual patching is instruction_set-dependent.
Vladimir Markof4da6752014-08-01 19:04:18 +0100163};
164
165class LinkerPatch {
166 public:
167 static LinkerPatch MethodPatch(size_t literal_offset,
168 const DexFile* target_dex_file,
169 uint32_t target_method_idx) {
Vladimir Marko20f85592015-03-19 10:07:02 +0000170 LinkerPatch patch(literal_offset, kLinkerPatchMethod, target_dex_file);
171 patch.method_idx_ = target_method_idx;
172 return patch;
Vladimir Markof4da6752014-08-01 19:04:18 +0100173 }
174
175 static LinkerPatch CodePatch(size_t literal_offset,
176 const DexFile* target_dex_file,
177 uint32_t target_method_idx) {
Vladimir Marko20f85592015-03-19 10:07:02 +0000178 LinkerPatch patch(literal_offset, kLinkerPatchCall, target_dex_file);
179 patch.method_idx_ = target_method_idx;
180 return patch;
Vladimir Markof4da6752014-08-01 19:04:18 +0100181 }
182
183 static LinkerPatch RelativeCodePatch(size_t literal_offset,
184 const DexFile* target_dex_file,
185 uint32_t target_method_idx) {
Vladimir Marko20f85592015-03-19 10:07:02 +0000186 LinkerPatch patch(literal_offset, kLinkerPatchCallRelative, target_dex_file);
187 patch.method_idx_ = target_method_idx;
188 return patch;
Vladimir Markof4da6752014-08-01 19:04:18 +0100189 }
190
191 static LinkerPatch TypePatch(size_t literal_offset,
192 const DexFile* target_dex_file,
193 uint32_t target_type_idx) {
Vladimir Marko20f85592015-03-19 10:07:02 +0000194 LinkerPatch patch(literal_offset, kLinkerPatchType, target_dex_file);
195 patch.type_idx_ = target_type_idx;
196 return patch;
197 }
198
199 static LinkerPatch DexCacheArrayPatch(size_t literal_offset,
200 const DexFile* target_dex_file,
201 uint32_t pc_insn_offset,
202 size_t element_offset) {
203 DCHECK(IsUint<32>(element_offset));
204 LinkerPatch patch(literal_offset, kLinkerPatchDexCacheArray, target_dex_file);
205 patch.pc_insn_offset_ = pc_insn_offset;
206 patch.element_offset_ = element_offset;
207 return patch;
Vladimir Markof4da6752014-08-01 19:04:18 +0100208 }
209
210 LinkerPatch(const LinkerPatch& other) = default;
211 LinkerPatch& operator=(const LinkerPatch& other) = default;
212
213 size_t LiteralOffset() const {
214 return literal_offset_;
215 }
216
217 LinkerPatchType Type() const {
218 return patch_type_;
219 }
220
Vladimir Marko20f85592015-03-19 10:07:02 +0000221 bool IsPcRelative() const {
222 return Type() == kLinkerPatchCallRelative || Type() == kLinkerPatchDexCacheArray;
223 }
224
Vladimir Markof4da6752014-08-01 19:04:18 +0100225 MethodReference TargetMethod() const {
226 DCHECK(patch_type_ == kLinkerPatchMethod ||
227 patch_type_ == kLinkerPatchCall || patch_type_ == kLinkerPatchCallRelative);
Vladimir Marko20f85592015-03-19 10:07:02 +0000228 return MethodReference(target_dex_file_, method_idx_);
Vladimir Markof4da6752014-08-01 19:04:18 +0100229 }
230
231 const DexFile* TargetTypeDexFile() const {
232 DCHECK(patch_type_ == kLinkerPatchType);
233 return target_dex_file_;
234 }
235
236 uint32_t TargetTypeIndex() const {
237 DCHECK(patch_type_ == kLinkerPatchType);
Vladimir Marko20f85592015-03-19 10:07:02 +0000238 return type_idx_;
239 }
240
241 const DexFile* TargetDexCacheDexFile() const {
242 DCHECK(patch_type_ == kLinkerPatchDexCacheArray);
243 return target_dex_file_;
244 }
245
246 size_t TargetDexCacheElementOffset() const {
247 DCHECK(patch_type_ == kLinkerPatchDexCacheArray);
248 return element_offset_;
249 }
250
251 uint32_t PcInsnOffset() const {
252 DCHECK(patch_type_ == kLinkerPatchDexCacheArray);
253 return pc_insn_offset_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100254 }
255
256 private:
Vladimir Marko20f85592015-03-19 10:07:02 +0000257 LinkerPatch(size_t literal_offset, LinkerPatchType patch_type, const DexFile* target_dex_file)
258 : target_dex_file_(target_dex_file),
259 literal_offset_(literal_offset),
260 patch_type_(patch_type) {
261 cmp1_ = 0u;
262 cmp2_ = 0u;
263 // The compiler rejects methods that are too big, so the compiled code
264 // of a single method really shouln't be anywhere close to 16MiB.
265 DCHECK(IsUint<24>(literal_offset));
Vladimir Markof4da6752014-08-01 19:04:18 +0100266 }
267
Vladimir Markof4da6752014-08-01 19:04:18 +0100268 const DexFile* target_dex_file_;
Vladimir Marko20f85592015-03-19 10:07:02 +0000269 uint32_t literal_offset_ : 24; // Method code size up to 16MiB.
270 LinkerPatchType patch_type_ : 8;
271 union {
272 uint32_t cmp1_; // Used for relational operators.
273 uint32_t method_idx_; // Method index for Call/Method patches.
274 uint32_t type_idx_; // Type index for Type patches.
275 uint32_t element_offset_; // Element offset in the dex cache arrays.
276 };
277 union {
278 uint32_t cmp2_; // Used for relational operators.
279 // Literal offset of the insn loading PC (same as literal_offset if it's the same insn,
280 // may be different if the PC-relative addressing needs multiple insns).
281 uint32_t pc_insn_offset_;
282 static_assert(sizeof(pc_insn_offset_) == sizeof(cmp2_), "needed by relational operators");
283 };
Vladimir Markof4da6752014-08-01 19:04:18 +0100284
285 friend bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs);
286 friend bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs);
287};
288
289inline bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs) {
290 return lhs.literal_offset_ == rhs.literal_offset_ &&
291 lhs.patch_type_ == rhs.patch_type_ &&
Vladimir Marko20f85592015-03-19 10:07:02 +0000292 lhs.target_dex_file_ == rhs.target_dex_file_ &&
293 lhs.cmp1_ == rhs.cmp1_ &&
294 lhs.cmp2_ == rhs.cmp2_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100295}
296
297inline bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs) {
298 return (lhs.literal_offset_ != rhs.literal_offset_) ? lhs.literal_offset_ < rhs.literal_offset_
299 : (lhs.patch_type_ != rhs.patch_type_) ? lhs.patch_type_ < rhs.patch_type_
Vladimir Marko20f85592015-03-19 10:07:02 +0000300 : (lhs.target_dex_file_ != rhs.target_dex_file_) ? lhs.target_dex_file_ < rhs.target_dex_file_
301 : (lhs.cmp1_ != rhs.cmp1_) ? lhs.cmp1_ < rhs.cmp1_
302 : lhs.cmp2_ < rhs.cmp2_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100303}
304
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700305class CompiledMethod FINAL : public CompiledCode {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700306 public:
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800307 // Constructs a CompiledMethod.
308 // Note: Consider using the static allocation methods below that will allocate the CompiledMethod
309 // in the swap space.
Ian Rogers72d32622014-05-06 16:20:11 -0700310 CompiledMethod(CompilerDriver* driver,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700311 InstructionSet instruction_set,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800312 const ArrayRef<const uint8_t>& quick_code,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700313 const size_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700314 const uint32_t core_spill_mask,
315 const uint32_t fp_spill_mask,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800316 DefaultSrcMap* src_mapping_table,
317 const ArrayRef<const uint8_t>& mapping_table,
318 const ArrayRef<const uint8_t>& vmap_table,
319 const ArrayRef<const uint8_t>& native_gc_map,
320 const ArrayRef<const uint8_t>& cfi_info,
David Srbeckyc6b4dd82015-04-07 20:32:43 +0100321 const ArrayRef<const LinkerPatch>& patches);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700322
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800323 virtual ~CompiledMethod();
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700324
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800325 static CompiledMethod* SwapAllocCompiledMethod(
326 CompilerDriver* driver,
327 InstructionSet instruction_set,
328 const ArrayRef<const uint8_t>& quick_code,
329 const size_t frame_size_in_bytes,
330 const uint32_t core_spill_mask,
331 const uint32_t fp_spill_mask,
332 DefaultSrcMap* src_mapping_table,
333 const ArrayRef<const uint8_t>& mapping_table,
334 const ArrayRef<const uint8_t>& vmap_table,
335 const ArrayRef<const uint8_t>& native_gc_map,
336 const ArrayRef<const uint8_t>& cfi_info,
David Srbeckyc6b4dd82015-04-07 20:32:43 +0100337 const ArrayRef<const LinkerPatch>& patches);
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800338
339 static void ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m);
340
Ian Rogers0c7abda2012-09-19 13:33:42 -0700341 size_t GetFrameSizeInBytes() const {
342 return frame_size_in_bytes_;
Logan Chien110bcba2012-04-16 19:11:28 +0800343 }
Ian Rogers0c7abda2012-09-19 13:33:42 -0700344
345 uint32_t GetCoreSpillMask() const {
346 return core_spill_mask_;
347 }
348
349 uint32_t GetFpSpillMask() const {
350 return fp_spill_mask_;
351 }
352
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800353 const SwapSrcMap& GetSrcMappingTable() const {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700354 DCHECK(src_mapping_table_ != nullptr);
355 return *src_mapping_table_;
356 }
357
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800358 SwapVector<uint8_t> const* GetMappingTable() const {
Nicolas Geoffray376b2bb2014-12-09 14:26:32 +0000359 return mapping_table_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700360 }
361
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800362 const SwapVector<uint8_t>* GetVmapTable() const {
Mathieu Chartier193bad92013-08-29 18:46:00 -0700363 DCHECK(vmap_table_ != nullptr);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800364 return vmap_table_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700365 }
366
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800367 SwapVector<uint8_t> const* GetGcMap() const {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100368 return gc_map_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700369 }
Logan Chien110bcba2012-04-16 19:11:28 +0800370
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800371 const SwapVector<uint8_t>* GetCFIInfo() const {
Mark Mendellae9fd932014-02-10 16:14:35 -0800372 return cfi_info_;
373 }
374
Vladimir Markob207e142015-04-02 21:25:21 +0100375 ArrayRef<const LinkerPatch> GetPatches() const {
376 return ArrayRef<const LinkerPatch>(patches_);
Vladimir Markof4da6752014-08-01 19:04:18 +0100377 }
378
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700379 private:
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800380 // Whether or not the arrays are owned by the compiled method or dedupe sets.
381 const bool owns_arrays_;
Ian Rogersa1827042013-04-18 16:36:43 -0700382 // For quick code, the size of the activation used by the code.
Ian Rogers0c7abda2012-09-19 13:33:42 -0700383 const size_t frame_size_in_bytes_;
Ian Rogersa1827042013-04-18 16:36:43 -0700384 // For quick code, a bit mask describing spilled GPR callee-save registers.
Ian Rogers169c9a72011-11-13 20:13:17 -0800385 const uint32_t core_spill_mask_;
Ian Rogersa1827042013-04-18 16:36:43 -0700386 // For quick code, a bit mask describing spilled FPR callee-save registers.
Ian Rogers169c9a72011-11-13 20:13:17 -0800387 const uint32_t fp_spill_mask_;
David Srbecky6f715892015-03-30 14:21:42 +0100388 // For quick code, a set of pairs (PC, DEX) mapping from native PC offset to DEX offset.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800389 SwapSrcMap* src_mapping_table_;
Ian Rogers96faf5b2013-08-09 22:05:32 -0700390 // For quick code, a uleb128 encoded map from native PC offset to dex PC aswell as dex PC to
391 // native PC offset. Size prefixed.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800392 SwapVector<uint8_t>* mapping_table_;
Ian Rogers96faf5b2013-08-09 22:05:32 -0700393 // For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800394 SwapVector<uint8_t>* vmap_table_;
Ian Rogersa1827042013-04-18 16:36:43 -0700395 // For quick code, a map keyed by native PC indices to bitmaps describing what dalvik registers
Elliott Hughes956af0f2014-12-11 14:34:28 -0800396 // are live.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800397 SwapVector<uint8_t>* gc_map_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800398 // For quick code, a FDE entry for the debug_frame section.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800399 SwapVector<uint8_t>* cfi_info_;
Vladimir Markof4da6752014-08-01 19:04:18 +0100400 // For quick code, linker patches needed by the method.
Vladimir Markob207e142015-04-02 21:25:21 +0100401 const SwapVector<LinkerPatch> patches_;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700402};
403
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700404} // namespace art
405
Mathieu Chartier193bad92013-08-29 18:46:00 -0700406#endif // ART_COMPILER_COMPILED_METHOD_H_