blob: 74ef35e740aede44c99d8137284ff8093d091a5b [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) {
Nicolas Geoffrayc04c8002015-07-14 11:37:54 +010026 if (owns_code_array_) {
27 // If we are supposed to own the code, don't deduplicate it.
28 quick_code_ = new SwapVector<uint8_t>(quick_code.begin(), quick_code.end(),
29 compiler_driver_->GetSwapSpaceAllocator());
30 } else {
31 quick_code_ = compiler_driver_->DeduplicateCode(quick_code);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080032 }
33}
34
35CompiledCode::~CompiledCode() {
36 if (owns_code_array_) {
37 delete quick_code_;
Ian Rogersef7d42f2014-01-06 12:55:46 -080038 }
39}
40
41bool CompiledCode::operator==(const CompiledCode& rhs) const {
42 if (quick_code_ != nullptr) {
43 if (rhs.quick_code_ == nullptr) {
44 return false;
45 } else if (quick_code_->size() != rhs.quick_code_->size()) {
46 return false;
47 } else {
48 return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin());
49 }
Ian Rogersef7d42f2014-01-06 12:55:46 -080050 }
Elliott Hughes956af0f2014-12-11 14:34:28 -080051 return (rhs.quick_code_ == nullptr);
Mathieu Chartier193bad92013-08-29 18:46:00 -070052}
53
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080054size_t CompiledCode::AlignCode(size_t offset) const {
Mathieu Chartier193bad92013-08-29 18:46:00 -070055 return AlignCode(offset, instruction_set_);
56}
57
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080058size_t CompiledCode::AlignCode(size_t offset, InstructionSet instruction_set) {
Andreas Gampeaf13ad92014-04-11 12:07:48 -070059 return RoundUp(offset, GetInstructionSetAlignment(instruction_set));
Mathieu Chartier193bad92013-08-29 18:46:00 -070060}
61
62size_t CompiledCode::CodeDelta() const {
Dave Allison50abf0a2014-06-23 13:19:59 -070063 return CodeDelta(instruction_set_);
64}
65
66size_t CompiledCode::CodeDelta(InstructionSet instruction_set) {
67 switch (instruction_set) {
Mathieu Chartier193bad92013-08-29 18:46:00 -070068 case kArm:
Stuart Monteithb95a5342014-03-12 13:32:32 +000069 case kArm64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070070 case kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -080071 case kMips64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070072 case kX86:
Dmitry Petrochenkofca82202014-03-21 11:21:37 +070073 case kX86_64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070074 return 0;
75 case kThumb2: {
76 // +1 to set the low-order bit so a BLX will switch to Thumb mode
77 return 1;
78 }
79 default:
Dave Allison50abf0a2014-06-23 13:19:59 -070080 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
Mathieu Chartier193bad92013-08-29 18:46:00 -070081 return 0;
82 }
83}
84
85const void* CompiledCode::CodePointer(const void* code_pointer,
86 InstructionSet instruction_set) {
87 switch (instruction_set) {
88 case kArm:
Stuart Monteithb95a5342014-03-12 13:32:32 +000089 case kArm64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070090 case kMips:
Andreas Gampe57b34292015-01-14 15:45:59 -080091 case kMips64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070092 case kX86:
Dmitry Petrochenkofca82202014-03-21 11:21:37 +070093 case kX86_64:
Mathieu Chartier193bad92013-08-29 18:46:00 -070094 return code_pointer;
95 case kThumb2: {
96 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
97 // Set the low-order bit so a BLX will switch to Thumb mode
98 address |= 0x1;
99 return reinterpret_cast<const void*>(address);
100 }
101 default:
102 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700103 return nullptr;
Mathieu Chartier193bad92013-08-29 18:46:00 -0700104 }
105}
106
Mathieu Chartier193bad92013-08-29 18:46:00 -0700107const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
Elliott Hughes956af0f2014-12-11 14:34:28 -0800108 CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size());
Mathieu Chartier193bad92013-08-29 18:46:00 -0700109 return oatdata_offsets_to_compiled_code_offset_;
110}
111
112void CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
113 oatdata_offsets_to_compiled_code_offset_.push_back(offset);
114}
Mathieu Chartier193bad92013-08-29 18:46:00 -0700115
Ian Rogers72d32622014-05-06 16:20:11 -0700116CompiledMethod::CompiledMethod(CompilerDriver* driver,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700117 InstructionSet instruction_set,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800118 const ArrayRef<const uint8_t>& quick_code,
Mathieu Chartier193bad92013-08-29 18:46:00 -0700119 const size_t frame_size_in_bytes,
120 const uint32_t core_spill_mask,
121 const uint32_t fp_spill_mask,
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800122 DefaultSrcMap* src_mapping_table,
123 const ArrayRef<const uint8_t>& mapping_table,
124 const ArrayRef<const uint8_t>& vmap_table,
125 const ArrayRef<const uint8_t>& native_gc_map,
126 const ArrayRef<const uint8_t>& cfi_info,
Vladimir Markob207e142015-04-02 21:25:21 +0100127 const ArrayRef<const LinkerPatch>& patches)
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800128 : CompiledCode(driver, instruction_set, quick_code, !driver->DedupeEnabled()),
129 owns_arrays_(!driver->DedupeEnabled()),
130 frame_size_in_bytes_(frame_size_in_bytes), core_spill_mask_(core_spill_mask),
131 fp_spill_mask_(fp_spill_mask),
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800132 patches_(patches.begin(), patches.end(), driver->GetSwapSpaceAllocator()) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800133 if (owns_arrays_) {
134 if (src_mapping_table == nullptr) {
135 src_mapping_table_ = new SwapSrcMap(driver->GetSwapSpaceAllocator());
136 } else {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800137 src_mapping_table_ = new SwapSrcMap(src_mapping_table->begin(), src_mapping_table->end(),
138 driver->GetSwapSpaceAllocator());
139 }
140 mapping_table_ = mapping_table.empty() ?
141 nullptr : new SwapVector<uint8_t>(mapping_table.begin(), mapping_table.end(),
142 driver->GetSwapSpaceAllocator());
143 vmap_table_ = new SwapVector<uint8_t>(vmap_table.begin(), vmap_table.end(),
144 driver->GetSwapSpaceAllocator());
145 gc_map_ = native_gc_map.empty() ? nullptr :
146 new SwapVector<uint8_t>(native_gc_map.begin(), native_gc_map.end(),
147 driver->GetSwapSpaceAllocator());
148 cfi_info_ = cfi_info.empty() ? nullptr :
149 new SwapVector<uint8_t>(cfi_info.begin(), cfi_info.end(), driver->GetSwapSpaceAllocator());
150 } else {
151 src_mapping_table_ = src_mapping_table == nullptr ?
152 driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>()) :
David Srbecky6f715892015-03-30 14:21:42 +0100153 driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>(*src_mapping_table));
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800154 mapping_table_ = mapping_table.empty() ?
155 nullptr : driver->DeduplicateMappingTable(mapping_table);
156 vmap_table_ = driver->DeduplicateVMapTable(vmap_table);
157 gc_map_ = native_gc_map.empty() ? nullptr : driver->DeduplicateGCMap(native_gc_map);
158 cfi_info_ = cfi_info.empty() ? nullptr : driver->DeduplicateCFIInfo(cfi_info);
159 }
Mathieu Chartier193bad92013-08-29 18:46:00 -0700160}
161
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800162CompiledMethod* CompiledMethod::SwapAllocCompiledMethod(
163 CompilerDriver* driver,
164 InstructionSet instruction_set,
165 const ArrayRef<const uint8_t>& quick_code,
166 const size_t frame_size_in_bytes,
167 const uint32_t core_spill_mask,
168 const uint32_t fp_spill_mask,
169 DefaultSrcMap* src_mapping_table,
170 const ArrayRef<const uint8_t>& mapping_table,
171 const ArrayRef<const uint8_t>& vmap_table,
172 const ArrayRef<const uint8_t>& native_gc_map,
173 const ArrayRef<const uint8_t>& cfi_info,
Vladimir Markob207e142015-04-02 21:25:21 +0100174 const ArrayRef<const LinkerPatch>& patches) {
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800175 SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
176 CompiledMethod* ret = alloc.allocate(1);
177 alloc.construct(ret, driver, instruction_set, quick_code, frame_size_in_bytes, core_spill_mask,
178 fp_spill_mask, src_mapping_table, mapping_table, vmap_table, native_gc_map,
179 cfi_info, patches);
180 return ret;
Nicolas Geoffray39468442014-09-02 15:17:15 +0100181}
182
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800183
184
185void CompiledMethod::ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m) {
186 SwapAllocator<CompiledMethod> alloc(driver->GetSwapSpaceAllocator());
187 alloc.destroy(m);
188 alloc.deallocate(m, 1);
Mathieu Chartier193bad92013-08-29 18:46:00 -0700189}
190
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800191CompiledMethod::~CompiledMethod() {
192 if (owns_arrays_) {
193 delete src_mapping_table_;
194 delete mapping_table_;
195 delete vmap_table_;
196 delete gc_map_;
197 delete cfi_info_;
198 }
199}
200
Mathieu Chartier193bad92013-08-29 18:46:00 -0700201} // namespace art