blob: 3e34144836f62d01d621e39c4ba40512d454badc [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
Elliott Hughes0f3c5532012-03-30 14:51:51 -070024#include "instruction_set.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070025#include "utils.h"
26
Shih-wei Liaod1fec812012-02-13 09:51:10 -080027namespace llvm {
28 class Function;
Ian Rogersa1827042013-04-18 16:36:43 -070029} // namespace llvm
Shih-wei Liaod1fec812012-02-13 09:51:10 -080030
Brian Carlstrom3320cf42011-10-04 14:58:28 -070031namespace art {
32
Mathieu Chartier193bad92013-08-29 18:46:00 -070033class CompilerDriver;
34
Logan Chien598c5132012-04-28 22:00:44 +080035class CompiledCode {
36 public:
Brian Carlstrom265091e2013-01-30 14:08:26 -080037 // For Quick to supply an code blob
Mathieu Chartier193bad92013-08-29 18:46:00 -070038 CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
Dave Allisond6ed6422014-04-09 23:36:15 +000039 const std::vector<uint8_t>& quick_code);
Logan Chien598c5132012-04-28 22:00:44 +080040
Brian Carlstrom265091e2013-01-30 14:08:26 -080041 // For Portable to supply an ELF object
Mathieu Chartier193bad92013-08-29 18:46:00 -070042 CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
43 const std::string& elf_object, const std::string &symbol);
Logan Chien598c5132012-04-28 22:00:44 +080044
Logan Chien598c5132012-04-28 22:00:44 +080045 InstructionSet GetInstructionSet() const {
46 return instruction_set_;
47 }
48
Ian Rogersef7d42f2014-01-06 12:55:46 -080049 const std::vector<uint8_t>* GetPortableCode() const {
50 return portable_code_;
Logan Chien598c5132012-04-28 22:00:44 +080051 }
52
Ian Rogersef7d42f2014-01-06 12:55:46 -080053 const std::vector<uint8_t>* GetQuickCode() const {
54 return quick_code_;
Logan Chien598c5132012-04-28 22:00:44 +080055 }
56
Ian Rogersef7d42f2014-01-06 12:55:46 -080057 void SetCode(const std::vector<uint8_t>* quick_code, const std::vector<uint8_t>* portable_code);
58
59 bool operator==(const CompiledCode& rhs) const;
60
Logan Chien598c5132012-04-28 22:00:44 +080061 // To align an offset from a page-aligned value to make it suitable
62 // for code storage. For example on ARM, to ensure that PC relative
63 // valu computations work out as expected.
64 uint32_t AlignCode(uint32_t offset) const;
65 static uint32_t AlignCode(uint32_t offset, InstructionSet instruction_set);
66
67 // returns the difference between the code address and a usable PC.
68 // mainly to cope with kThumb2 where the lower bit must be set.
69 size_t CodeDelta() const;
Dave Allison50abf0a2014-06-23 13:19:59 -070070 static size_t CodeDelta(InstructionSet instruction_set);
Logan Chien598c5132012-04-28 22:00:44 +080071
72 // Returns a pointer suitable for invoking the code at the argument
73 // code_pointer address. Mainly to cope with kThumb2 where the
74 // lower bit must be set to indicate Thumb mode.
75 static const void* CodePointer(const void* code_pointer,
76 InstructionSet instruction_set);
77
Brian Carlstrom265091e2013-01-30 14:08:26 -080078 const std::string& GetSymbol() const;
79 const std::vector<uint32_t>& GetOatdataOffsetsToCompliledCodeOffset() const;
80 void AddOatdataOffsetToCompliledCodeOffset(uint32_t offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -080081
Logan Chien598c5132012-04-28 22:00:44 +080082 private:
Ian Rogersef7d42f2014-01-06 12:55:46 -080083 CompilerDriver* const compiler_driver_;
Mathieu Chartier193bad92013-08-29 18:46:00 -070084
Logan Chien598c5132012-04-28 22:00:44 +080085 const InstructionSet instruction_set_;
Brian Carlstrom8227cc12013-03-06 14:26:48 -080086
Ian Rogersef7d42f2014-01-06 12:55:46 -080087 // The ELF image for portable.
88 std::vector<uint8_t>* portable_code_;
89
90 // Used to store the PIC code for Quick.
91 std::vector<uint8_t>* quick_code_;
Brian Carlstrom265091e2013-01-30 14:08:26 -080092
93 // Used for the Portable ELF symbol name.
Ian Rogersa1827042013-04-18 16:36:43 -070094 const std::string symbol_;
Brian Carlstrom265091e2013-01-30 14:08:26 -080095
96 // There are offsets from the oatdata symbol to where the offset to
97 // the compiled method will be found. These are computed by the
98 // OatWriter and then used by the ElfWriter to add relocations so
99 // that MCLinker can update the values to the location in the linked .so.
100 std::vector<uint32_t> oatdata_offsets_to_compiled_code_offset_;
Logan Chien598c5132012-04-28 22:00:44 +0800101};
102
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700103class SrcMapElem {
104 public:
105 uint32_t from_;
106 int32_t to_;
107
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700108 explicit operator int64_t() const {
109 return (static_cast<int64_t>(to_) << 32) | from_;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700110 }
111
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700112 bool operator<(const SrcMapElem& sme) const {
113 return int64_t(*this) < int64_t(sme);
114 }
115
116 bool operator==(const SrcMapElem& sme) const {
117 return int64_t(*this) == int64_t(sme);
118 }
119
120 explicit operator uint8_t() const {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700121 return static_cast<uint8_t>(from_ + to_);
122 }
123};
124
125class SrcMap FINAL : public std::vector<SrcMapElem> {
126 public:
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700127 void SortByFrom() {
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700128 std::sort(begin(), end(), [] (const SrcMapElem& lhs, const SrcMapElem& rhs) -> bool {
129 return lhs.from_ < rhs.from_;
130 });
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700131 }
132
133 const_iterator FindByTo(int32_t to) const {
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700134 return std::lower_bound(begin(), end(), SrcMapElem({0, to}));
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700135 }
136
137 SrcMap& Arrange() {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700138 if (!empty()) {
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700139 std::sort(begin(), end());
140 resize(std::unique(begin(), end()) - begin());
141 shrink_to_fit();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700142 }
143 return *this;
144 }
145
146 void DeltaFormat(const SrcMapElem& start, uint32_t highest_pc) {
147 // Convert from abs values to deltas.
148 if (!empty()) {
149 SortByFrom();
150
151 // TODO: one PC can be mapped to several Java src lines.
152 // do we want such a one-to-many correspondence?
153
154 // get rid of the highest values
155 size_t i = size() - 1;
156 for (; i > 0 ; i--) {
157 if ((*this)[i].from_ >= highest_pc) {
158 break;
159 }
160 }
161 this->resize(i + 1);
162
163 for (size_t i = size(); --i >= 1; ) {
164 (*this)[i].from_ -= (*this)[i-1].from_;
165 (*this)[i].to_ -= (*this)[i-1].to_;
166 }
167 DCHECK((*this)[0].from_ >= start.from_);
168 (*this)[0].from_ -= start.from_;
169 (*this)[0].to_ -= start.to_;
170 }
171 }
172};
173
174class CompiledMethod FINAL : public CompiledCode {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700175 public:
Nicolas Geoffray39468442014-09-02 15:17:15 +0100176 // Constructs a CompiledMethod for Quick.
Ian Rogers72d32622014-05-06 16:20:11 -0700177 CompiledMethod(CompilerDriver* driver,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700178 InstructionSet instruction_set,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800179 const std::vector<uint8_t>& quick_code,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700180 const size_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700181 const uint32_t core_spill_mask,
182 const uint32_t fp_spill_mask,
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700183 SrcMap* src_mapping_table,
Ian Rogers96faf5b2013-08-09 22:05:32 -0700184 const std::vector<uint8_t>& mapping_table,
185 const std::vector<uint8_t>& vmap_table,
Mark Mendellae9fd932014-02-10 16:14:35 -0800186 const std::vector<uint8_t>& native_gc_map,
Dave Allisond6ed6422014-04-09 23:36:15 +0000187 const std::vector<uint8_t>* cfi_info);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700188
Nicolas Geoffray39468442014-09-02 15:17:15 +0100189 // Constructs a CompiledMethod for Optimizing.
190 CompiledMethod(CompilerDriver* driver,
191 InstructionSet instruction_set,
192 const std::vector<uint8_t>& quick_code,
193 const size_t frame_size_in_bytes,
194 const uint32_t core_spill_mask,
195 const uint32_t fp_spill_mask,
196 const std::vector<uint8_t>& mapping_table,
197 const std::vector<uint8_t>& vmap_table);
198
Ian Rogersef7d42f2014-01-06 12:55:46 -0800199 // Constructs a CompiledMethod for the QuickJniCompiler.
Ian Rogers72d32622014-05-06 16:20:11 -0700200 CompiledMethod(CompilerDriver* driver,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700201 InstructionSet instruction_set,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800202 const std::vector<uint8_t>& quick_code,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700203 const size_t frame_size_in_bytes,
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700204 const uint32_t core_spill_mask,
Tong Shen547cdfd2014-08-05 01:54:19 -0700205 const uint32_t fp_spill_mask,
206 const std::vector<uint8_t>* cfi_info);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700207
Brian Carlstrom265091e2013-01-30 14:08:26 -0800208 // Constructs a CompiledMethod for the Portable compiler.
Ian Rogers72d32622014-05-06 16:20:11 -0700209 CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700210 const std::vector<uint8_t>& gc_map, const std::string& symbol);
TDYa127ce4cc0d2012-11-18 16:59:53 -0800211
Brian Carlstrom265091e2013-01-30 14:08:26 -0800212 // Constructs a CompiledMethod for the Portable JniCompiler.
Ian Rogers72d32622014-05-06 16:20:11 -0700213 CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700214 const std::string& symbol);
Logan Chien6920bce2012-03-17 21:44:01 +0800215
Ian Rogers0c7abda2012-09-19 13:33:42 -0700216 ~CompiledMethod() {}
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700217
Ian Rogers0c7abda2012-09-19 13:33:42 -0700218 size_t GetFrameSizeInBytes() const {
219 return frame_size_in_bytes_;
Logan Chien110bcba2012-04-16 19:11:28 +0800220 }
Ian Rogers0c7abda2012-09-19 13:33:42 -0700221
222 uint32_t GetCoreSpillMask() const {
223 return core_spill_mask_;
224 }
225
226 uint32_t GetFpSpillMask() const {
227 return fp_spill_mask_;
228 }
229
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700230 const SrcMap& GetSrcMappingTable() const {
231 DCHECK(src_mapping_table_ != nullptr);
232 return *src_mapping_table_;
233 }
234
Ian Rogers96faf5b2013-08-09 22:05:32 -0700235 const std::vector<uint8_t>& GetMappingTable() const {
Mathieu Chartier193bad92013-08-29 18:46:00 -0700236 DCHECK(mapping_table_ != nullptr);
237 return *mapping_table_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700238 }
239
Ian Rogers96faf5b2013-08-09 22:05:32 -0700240 const std::vector<uint8_t>& GetVmapTable() const {
Mathieu Chartier193bad92013-08-29 18:46:00 -0700241 DCHECK(vmap_table_ != nullptr);
242 return *vmap_table_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700243 }
244
Nicolas Geoffray39468442014-09-02 15:17:15 +0100245 std::vector<uint8_t> const* GetGcMap() const {
246 return gc_map_;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700247 }
Logan Chien110bcba2012-04-16 19:11:28 +0800248
Mark Mendellae9fd932014-02-10 16:14:35 -0800249 const std::vector<uint8_t>* GetCFIInfo() const {
250 return cfi_info_;
251 }
252
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700253 private:
Ian Rogersa1827042013-04-18 16:36:43 -0700254 // For quick code, the size of the activation used by the code.
Ian Rogers0c7abda2012-09-19 13:33:42 -0700255 const size_t frame_size_in_bytes_;
Ian Rogersa1827042013-04-18 16:36:43 -0700256 // For quick code, a bit mask describing spilled GPR callee-save registers.
Ian Rogers169c9a72011-11-13 20:13:17 -0800257 const uint32_t core_spill_mask_;
Ian Rogersa1827042013-04-18 16:36:43 -0700258 // For quick code, a bit mask describing spilled FPR callee-save registers.
Ian Rogers169c9a72011-11-13 20:13:17 -0800259 const uint32_t fp_spill_mask_;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700260 // For quick code, a set of pairs (PC, Line) mapping from native PC offset to Java line
261 SrcMap* src_mapping_table_;
Ian Rogers96faf5b2013-08-09 22:05:32 -0700262 // For quick code, a uleb128 encoded map from native PC offset to dex PC aswell as dex PC to
263 // native PC offset. Size prefixed.
Mathieu Chartier193bad92013-08-29 18:46:00 -0700264 std::vector<uint8_t>* mapping_table_;
Ian Rogers96faf5b2013-08-09 22:05:32 -0700265 // For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed.
Mathieu Chartier193bad92013-08-29 18:46:00 -0700266 std::vector<uint8_t>* vmap_table_;
Ian Rogersa1827042013-04-18 16:36:43 -0700267 // For quick code, a map keyed by native PC indices to bitmaps describing what dalvik registers
268 // are live. For portable code, the key is a dalvik PC.
Mathieu Chartier193bad92013-08-29 18:46:00 -0700269 std::vector<uint8_t>* gc_map_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800270 // For quick code, a FDE entry for the debug_frame section.
271 std::vector<uint8_t>* cfi_info_;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700272};
273
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700274} // namespace art
275
Mathieu Chartier193bad92013-08-29 18:46:00 -0700276#endif // ART_COMPILER_COMPILED_METHOD_H_