blob: f33db09677a49136eedf722c070dc0ff88d09010 [file] [log] [blame]
Mathieu Chartier193bad92013-08-29 18:46:00 -07001/*
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 */
16
17#include "compiled_method.h"
18#include "driver/compiler_driver.h"
19
20namespace art {
21
22CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080023 const ArrayRef<const uint8_t>& quick_code, bool owns_code_array)
Ian Rogersef7d42f2014-01-06 12:55:46 -080024 : compiler_driver_(compiler_driver), instruction_set_(instruction_set),
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080025 owns_code_array_(owns_code_array), quick_code_(nullptr) {
Elliott Hughes956af0f2014-12-11 14:34:28 -080026 SetCode(&quick_code);
Mathieu Chartier193bad92013-08-29 18:46:00 -070027}
28
Andreas Gampee21dc3d2014-12-08 16:59:43 -080029void CompiledCode::SetCode(const ArrayRef<const uint8_t>* quick_code) {
Nicolas Geoffray69207032015-07-09 18:15:19 +010030 if (quick_code != nullptr && !quick_code->empty()) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080031 if (owns_code_array_) {
32 // If we are supposed to own the code, don't deduplicate it.
33 CHECK(quick_code_ == nullptr);
34 quick_code_ = new SwapVector<uint8_t>(quick_code->begin(), quick_code->end(),
35 compiler_driver_->GetSwapSpaceAllocator());
36 } else {
37 quick_code_ = compiler_driver_->DeduplicateCode(*quick_code);
38 }
39 }
40}
41
42CompiledCode::~CompiledCode() {
43 if (owns_code_array_) {
44 delete quick_code_;
Ian Rogersef7d42f2014-01-06 12:55:46 -080045 }
46}
47
48bool CompiledCode::operator==(const CompiledCode& rhs) const {
49 if (quick_code_ != nullptr) {
50 if (rhs.quick_code_ == nullptr) {
51 return false;
52 } else if (quick_code_->size() != rhs.quick_code_->size()) {
53 return false;
54 } else {
55 return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin());
56 }
Ian Rogersef7d42f2014-01-06 12:55:46 -080057 }
Elliott Hughes956af0f2014-12-11 14:34:28 -080058 return (rhs.quick_code_ == nullptr);
Mathieu Chartier193bad92013-08-29 18:46:00 -070059}
60
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061size_t CompiledCode::AlignCode(size_t offset) const {
Mathieu Chartier193bad92013-08-29 18:46:00 -070062 return AlignCode(offset, instruction_set_);
63}
64
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080065size_t CompiledCode::AlignCode(size_t offset, InstructionSet instruction_set) {
Andreas Gampeaf13ad92014-04-11 12:07:48 -070066 return RoundUp(offset, GetInstructionSetAlignment(instruction_set));
Mathieu Chartier193bad92013-08-29 18:46:00 -070067}
68
69size_t CompiledCode::CodeDelta() const {
Dave Allison50abf0a2014-06-23 13:19:59 -070070 return CodeDelta(instruction_set_);
71}
72
73size_t CompiledCode::CodeDelta(InstructionSet instruction_set) {
74 switch (instruction_set) {
Mathieu Chartier193bad92013-08-29 18:46:00 -070075 case kArm:
Stuart Monteithb95a5342014-03-12 13:32:32 +000076 case kArm64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070077 case kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -080078 case kMips64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070079 case kX86:
Dmitry Petrochenkofca82202014-03-21 11:21:37 +070080 case kX86_64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070081 return 0;
82 case kThumb2: {
83 // +1 to set the low-order bit so a BLX will switch to Thumb mode
84 return 1;
85 }
86 default:
Dave Allison50abf0a2014-06-23 13:19:59 -070087 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
Mathieu Chartier193bad92013-08-29 18:46:00 -070088 return 0;
89 }
90}
91
92const void* CompiledCode::CodePointer(const void* code_pointer,
93 InstructionSet instruction_set) {
94 switch (instruction_set) {
95 case kArm:
Stuart Monteithb95a5342014-03-12 13:32:32 +000096 case kArm64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070097 case kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -080098 case kMips64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070099 case kX86:
Dmitry Petrochenkofca82202014-03-21 11:21:37 +0700100 case kX86_64:
Mathieu Chartier193bad92013-08-29 18:46:00 -0700101 return code_pointer;
102 case kThumb2: {
103 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
104 // Set the low-order bit so a BLX will switch to Thumb mode
105 address |= 0x1;
106 return reinterpret_cast<const void*>(address);
107 }
108 default:
109 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700110 return nullptr;
Mathieu Chartier193bad92013-08-29 18:46:00 -0700111 }
112}
113
Mathieu Chartier193bad92013-08-29 18:46:00 -0700114const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
Elliott Hughes956af0f2014-12-11 14:34:28 -0800115 CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size());
Mathieu Chartier193bad92013-08-29 18:46:00 -0700116 return oatdata_offsets_to_compiled_code_offset_;
117}
118
119void CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
120 oatdata_offsets_to_compiled_code_offset_.push_back(offset);
121}
Mathieu Chartier193bad92013-08-29 18:46:00 -0700122
Ian Rogers72d32622014-05-06 16:20:11 -0700123CompiledMethod::CompiledMethod(CompilerDriver* driver,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700124 InstructionSet instruction_set,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800125 const ArrayRef<const uint8_t>& quick_code,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700126 const size_t frame_size_in_bytes,
127 const uint32_t core_spill_mask,
128 const uint32_t fp_spill_mask,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800129 DefaultSrcMap* src_mapping_table,
130 const ArrayRef<const uint8_t>& mapping_table,
131 const ArrayRef<const uint8_t>& vmap_table,
132 const ArrayRef<const uint8_t>& native_gc_map,
133 const ArrayRef<const uint8_t>& cfi_info,
Vladimir Markob207e142015-04-02 21:25:21 +0100134 const ArrayRef<const LinkerPatch>& patches)
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800135 : CompiledCode(driver, instruction_set, quick_code, !driver->DedupeEnabled()),
136 owns_arrays_(!driver->DedupeEnabled()),
137 frame_size_in_bytes_(frame_size_in_bytes), core_spill_mask_(core_spill_mask),
138 fp_spill_mask_(fp_spill_mask),
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800139 patches_(patches.begin(), patches.end(), driver->GetSwapSpaceAllocator()) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800140 if (owns_arrays_) {
141 if (src_mapping_table == nullptr) {
142 src_mapping_table_ = new SwapSrcMap(driver->GetSwapSpaceAllocator());
143 } else {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800144 src_mapping_table_ = new SwapSrcMap(src_mapping_table->begin(), src_mapping_table->end(),
145 driver->GetSwapSpaceAllocator());
146 }
147 mapping_table_ = mapping_table.empty() ?
148 nullptr : new SwapVector<uint8_t>(mapping_table.begin(), mapping_table.end(),
149 driver->GetSwapSpaceAllocator());
150 vmap_table_ = new SwapVector<uint8_t>(vmap_table.begin(), vmap_table.end(),
151 driver->GetSwapSpaceAllocator());
152 gc_map_ = native_gc_map.empty() ? nullptr :
153 new SwapVector<uint8_t>(native_gc_map.begin(), native_gc_map.end(),
154 driver->GetSwapSpaceAllocator());
155 cfi_info_ = cfi_info.empty() ? nullptr :
156 new SwapVector<uint8_t>(cfi_info.begin(), cfi_info.end(), driver->GetSwapSpaceAllocator());
157 } else {
158 src_mapping_table_ = src_mapping_table == nullptr ?
159 driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>()) :
David Srbecky6f715892015-03-30 14:21:42 +0100160 driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>(*src_mapping_table));
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800161 mapping_table_ = mapping_table.empty() ?
162 nullptr : driver->DeduplicateMappingTable(mapping_table);
163 vmap_table_ = driver->DeduplicateVMapTable(vmap_table);
164 gc_map_ = native_gc_map.empty() ? nullptr : driver->DeduplicateGCMap(native_gc_map);
165 cfi_info_ = cfi_info.empty() ? nullptr : driver->DeduplicateCFIInfo(cfi_info);
166 }
Mathieu Chartier193bad92013-08-29 18:46:00 -0700167}
168
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800169CompiledMethod* CompiledMethod::SwapAllocCompiledMethod(
170 CompilerDriver* driver,
171 InstructionSet instruction_set,
172 const ArrayRef<const uint8_t>& quick_code,
173 const size_t frame_size_in_bytes,
174 const uint32_t core_spill_mask,
175 const uint32_t fp_spill_mask,
176 DefaultSrcMap* src_mapping_table,
177 const ArrayRef<const uint8_t>& mapping_table,
178 const ArrayRef<const uint8_t>& vmap_table,
179 const ArrayRef<const uint8_t>& native_gc_map,
180 const ArrayRef<const uint8_t>& cfi_info,
Vladimir Markob207e142015-04-02 21:25:21 +0100181 const ArrayRef<const LinkerPatch>& patches) {
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800182 SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
183 CompiledMethod* ret = alloc.allocate(1);
184 alloc.construct(ret, driver, instruction_set, quick_code, frame_size_in_bytes, core_spill_mask,
185 fp_spill_mask, src_mapping_table, mapping_table, vmap_table, native_gc_map,
186 cfi_info, patches);
187 return ret;
Nicolas Geoffray39468442014-09-02 15:17:15 +0100188}
189
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800190
191
192void CompiledMethod::ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m) {
193 SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
194 alloc.destroy(m);
195 alloc.deallocate(m, 1);
Mathieu Chartier193bad92013-08-29 18:46:00 -0700196}
197
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800198CompiledMethod::~CompiledMethod() {
199 if (owns_arrays_) {
200 delete src_mapping_table_;
201 delete mapping_table_;
202 delete vmap_table_;
203 delete gc_map_;
204 delete cfi_info_;
205 }
206}
207
Mathieu Chartier193bad92013-08-29 18:46:00 -0700208} // namespace art