compiled_method.cc revision f4da675bbc4615c5f854c81964cac9dd1153baea
1/* 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, 23 const std::vector<uint8_t>& quick_code) 24 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), 25 portable_code_(nullptr), quick_code_(nullptr) { 26 SetCode(&quick_code, nullptr); 27} 28 29CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 30 const std::string& elf_object, const std::string& symbol) 31 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), 32 portable_code_(nullptr), quick_code_(nullptr), symbol_(symbol) { 33 CHECK_NE(elf_object.size(), 0U); 34 CHECK_NE(symbol.size(), 0U); 35 std::vector<uint8_t> temp_code(elf_object.size()); 36 for (size_t i = 0; i < elf_object.size(); ++i) { 37 temp_code[i] = elf_object[i]; 38 } 39 // TODO: we shouldn't just shove ELF objects in as "code" but 40 // change to have different kinds of compiled methods. This is 41 // being deferred until we work on hybrid execution or at least 42 // until we work on batch compilation. 43 SetCode(nullptr, &temp_code); 44} 45 46void CompiledCode::SetCode(const std::vector<uint8_t>* quick_code, 47 const std::vector<uint8_t>* portable_code) { 48 if (portable_code != nullptr) { 49 CHECK(!portable_code->empty()); 50 portable_code_ = compiler_driver_->DeduplicateCode(*portable_code); 51 } 52 if (quick_code != nullptr) { 53 CHECK(!quick_code->empty()); 54 quick_code_ = compiler_driver_->DeduplicateCode(*quick_code); 55 } 56} 57 58bool CompiledCode::operator==(const CompiledCode& rhs) const { 59 if (quick_code_ != nullptr) { 60 if (rhs.quick_code_ == nullptr) { 61 return false; 62 } else if (quick_code_->size() != rhs.quick_code_->size()) { 63 return false; 64 } else { 65 return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin()); 66 } 67 } else if (portable_code_ != nullptr) { 68 if (rhs.portable_code_ == nullptr) { 69 return false; 70 } else if (portable_code_->size() != rhs.portable_code_->size()) { 71 return false; 72 } else { 73 return std::equal(portable_code_->begin(), portable_code_->end(), 74 rhs.portable_code_->begin()); 75 } 76 } 77 return (rhs.quick_code_ == nullptr) && (rhs.portable_code_ == nullptr); 78} 79 80uint32_t CompiledCode::AlignCode(uint32_t offset) const { 81 return AlignCode(offset, instruction_set_); 82} 83 84uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) { 85 return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); 86} 87 88size_t CompiledCode::CodeDelta() const { 89 return CodeDelta(instruction_set_); 90} 91 92size_t CompiledCode::CodeDelta(InstructionSet instruction_set) { 93 switch (instruction_set) { 94 case kArm: 95 case kArm64: 96 case kMips: 97 case kX86: 98 case kX86_64: 99 return 0; 100 case kThumb2: { 101 // +1 to set the low-order bit so a BLX will switch to Thumb mode 102 return 1; 103 } 104 default: 105 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 106 return 0; 107 } 108} 109 110const void* CompiledCode::CodePointer(const void* code_pointer, 111 InstructionSet instruction_set) { 112 switch (instruction_set) { 113 case kArm: 114 case kArm64: 115 case kMips: 116 case kX86: 117 case kX86_64: 118 return code_pointer; 119 case kThumb2: { 120 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer); 121 // Set the low-order bit so a BLX will switch to Thumb mode 122 address |= 0x1; 123 return reinterpret_cast<const void*>(address); 124 } 125 default: 126 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 127 return NULL; 128 } 129} 130 131const std::string& CompiledCode::GetSymbol() const { 132 CHECK_NE(0U, symbol_.size()); 133 return symbol_; 134} 135 136const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const { 137 CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_; 138 return oatdata_offsets_to_compiled_code_offset_; 139} 140 141void CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) { 142 oatdata_offsets_to_compiled_code_offset_.push_back(offset); 143} 144 145CompiledMethod::CompiledMethod(CompilerDriver* driver, 146 InstructionSet instruction_set, 147 const std::vector<uint8_t>& quick_code, 148 const size_t frame_size_in_bytes, 149 const uint32_t core_spill_mask, 150 const uint32_t fp_spill_mask, 151 SrcMap* src_mapping_table, 152 const std::vector<uint8_t>& mapping_table, 153 const std::vector<uint8_t>& vmap_table, 154 const std::vector<uint8_t>& native_gc_map, 155 const std::vector<uint8_t>* cfi_info, 156 const ArrayRef<LinkerPatch>& patches) 157 : CompiledCode(driver, instruction_set, quick_code), frame_size_in_bytes_(frame_size_in_bytes), 158 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), 159 src_mapping_table_(driver->DeduplicateSrcMappingTable(src_mapping_table->Arrange())), 160 mapping_table_(driver->DeduplicateMappingTable(mapping_table)), 161 vmap_table_(driver->DeduplicateVMapTable(vmap_table)), 162 gc_map_(driver->DeduplicateGCMap(native_gc_map)), 163 cfi_info_(driver->DeduplicateCFIInfo(cfi_info)), 164 patches_(patches.begin(), patches.end()) { 165} 166 167CompiledMethod::CompiledMethod(CompilerDriver* driver, 168 InstructionSet instruction_set, 169 const std::vector<uint8_t>& quick_code, 170 const size_t frame_size_in_bytes, 171 const uint32_t core_spill_mask, 172 const uint32_t fp_spill_mask, 173 const std::vector<uint8_t>& mapping_table, 174 const std::vector<uint8_t>& stack_map) 175 : CompiledCode(driver, instruction_set, quick_code), 176 frame_size_in_bytes_(frame_size_in_bytes), 177 core_spill_mask_(core_spill_mask), 178 fp_spill_mask_(fp_spill_mask), 179 src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())), 180 mapping_table_(driver->DeduplicateMappingTable(mapping_table)), 181 vmap_table_(driver->DeduplicateVMapTable(stack_map)), 182 gc_map_(nullptr), 183 cfi_info_(nullptr), 184 patches_() { 185} 186 187CompiledMethod::CompiledMethod(CompilerDriver* driver, 188 InstructionSet instruction_set, 189 const std::vector<uint8_t>& code, 190 const size_t frame_size_in_bytes, 191 const uint32_t core_spill_mask, 192 const uint32_t fp_spill_mask, 193 const std::vector<uint8_t>* cfi_info) 194 : CompiledCode(driver, instruction_set, code), 195 frame_size_in_bytes_(frame_size_in_bytes), 196 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), 197 src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())), 198 mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())), 199 vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())), 200 gc_map_(driver->DeduplicateGCMap(std::vector<uint8_t>())), 201 cfi_info_(driver->DeduplicateCFIInfo(cfi_info)), 202 patches_() { 203} 204 205// Constructs a CompiledMethod for the Portable compiler. 206CompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, 207 const std::string& code, const std::vector<uint8_t>& gc_map, 208 const std::string& symbol) 209 : CompiledCode(driver, instruction_set, code, symbol), 210 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 211 fp_spill_mask_(0), 212 src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())), 213 mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())), 214 vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())), 215 gc_map_(driver->DeduplicateGCMap(gc_map)), 216 cfi_info_(nullptr), 217 patches_() { 218} 219 220CompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, 221 const std::string& code, const std::string& symbol) 222 : CompiledCode(driver, instruction_set, code, symbol), 223 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 224 fp_spill_mask_(0), 225 src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())), 226 mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())), 227 vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())), 228 gc_map_(driver->DeduplicateGCMap(std::vector<uint8_t>())), 229 cfi_info_(nullptr), 230 patches_() { 231} 232 233} // namespace art 234