12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 163320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 173320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom#include "compiled_method.h" 18193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#include "driver/compiler_driver.h" 193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromnamespace art { 213320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 22193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 23d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison const std::vector<uint8_t>& quick_code) 24ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers : compiler_driver_(compiler_driver), instruction_set_(instruction_set), 25d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison portable_code_(nullptr), quick_code_(nullptr) { 26ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SetCode(&quick_code, nullptr); 27265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 28265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 29193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 30193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier const std::string& elf_object, const std::string& symbol) 31ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers : compiler_driver_(compiler_driver), instruction_set_(instruction_set), 32d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison portable_code_(nullptr), quick_code_(nullptr), symbol_(symbol) { 33265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(elf_object.size(), 0U); 34265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(symbol.size(), 0U); 35193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier std::vector<uint8_t> temp_code(elf_object.size()); 36193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier for (size_t i = 0; i < elf_object.size(); ++i) { 37193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier temp_code[i] = elf_object[i]; 38193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier } 39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // TODO: we shouldn't just shove ELF objects in as "code" but 40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // change to have different kinds of compiled methods. This is 41265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // being deferred until we work on hybrid execution or at least 42265091e581c9f643b37e7966890911f09e223269Brian Carlstrom // until we work on batch compilation. 43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SetCode(nullptr, &temp_code); 44193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier} 45193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 46ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersvoid CompiledCode::SetCode(const std::vector<uint8_t>* quick_code, 47ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const std::vector<uint8_t>* portable_code) { 48ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (portable_code != nullptr) { 49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CHECK(!portable_code->empty()); 50ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers portable_code_ = compiler_driver_->DeduplicateCode(*portable_code); 51ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 52ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (quick_code != nullptr) { 53ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CHECK(!quick_code->empty()); 54ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers quick_code_ = compiler_driver_->DeduplicateCode(*quick_code); 55ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 56ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 58ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersbool CompiledCode::operator==(const CompiledCode& rhs) const { 59ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (quick_code_ != nullptr) { 60ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (rhs.quick_code_ == nullptr) { 61ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 62ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else if (quick_code_->size() != rhs.quick_code_->size()) { 63ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 64ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 65ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin()); 66ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 67ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else if (portable_code_ != nullptr) { 68ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (rhs.portable_code_ == nullptr) { 69ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 70ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else if (portable_code_->size() != rhs.portable_code_->size()) { 71ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 72ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 73ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return std::equal(portable_code_->begin(), portable_code_->end(), 74ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers rhs.portable_code_->begin()); 75ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 77ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return (rhs.quick_code_ == nullptr) && (rhs.portable_code_ == nullptr); 78265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 79265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 80598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset) const { 81598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return AlignCode(offset, instruction_set_); 82598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 83598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 84598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) { 85af13ad9fd18b6f75fe82e7995224c55654594f93Andreas Gampe return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); 86598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 87598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 88598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const { 8950abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison return CodeDelta(instruction_set_); 9050abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison} 9150abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison 9250abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allisonsize_t CompiledCode::CodeDelta(InstructionSet instruction_set) { 9350abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison switch (instruction_set) { 94598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kArm: 95b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith case kArm64: 96598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kMips: 97598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kX86: 98fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko case kX86_64: 99598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 100598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kThumb2: { 101598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // +1 to set the low-order bit so a BLX will switch to Thumb mode 102598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 1; 103598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 104598c513a2737d872e22ea8bcedec61b92deff357Logan Chien default: 10550abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 106598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 107598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 108598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 109598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 110598c513a2737d872e22ea8bcedec61b92deff357Logan Chienconst void* CompiledCode::CodePointer(const void* code_pointer, 111598c513a2737d872e22ea8bcedec61b92deff357Logan Chien InstructionSet instruction_set) { 112598c513a2737d872e22ea8bcedec61b92deff357Logan Chien switch (instruction_set) { 113598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kArm: 114b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith case kArm64: 115598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kMips: 116598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kX86: 117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko case kX86_64: 118598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return code_pointer; 119598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kThumb2: { 120598c513a2737d872e22ea8bcedec61b92deff357Logan Chien uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer); 121598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // Set the low-order bit so a BLX will switch to Thumb mode 122598c513a2737d872e22ea8bcedec61b92deff357Logan Chien address |= 0x1; 123598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return reinterpret_cast<const void*>(address); 124598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 125598c513a2737d872e22ea8bcedec61b92deff357Logan Chien default: 126598c513a2737d872e22ea8bcedec61b92deff357Logan Chien LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 127598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return NULL; 128598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 129598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 130598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 131265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::string& CompiledCode::GetSymbol() const { 132265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(0U, symbol_.size()); 133265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return symbol_; 134265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 135265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 136265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const { 137265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_; 138265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return oatdata_offsets_to_compiled_code_offset_; 139265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 140265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 141265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) { 142265091e581c9f643b37e7966890911f09e223269Brian Carlstrom oatdata_offsets_to_compiled_code_offset_.push_back(offset); 143265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 144265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 14572d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod::CompiledMethod(CompilerDriver* driver, 146193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier InstructionSet instruction_set, 147ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const std::vector<uint8_t>& quick_code, 1483320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const size_t frame_size_in_bytes, 1493320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t core_spill_mask, 1503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t fp_spill_mask, 15196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const std::vector<uint8_t>& mapping_table, 15296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers const std::vector<uint8_t>& vmap_table, 153ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell const std::vector<uint8_t>& native_gc_map, 154d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison const std::vector<uint8_t>* cfi_info) 15572d32629303f8f39362a4099481f48646aed042fIan Rogers : CompiledCode(driver, instruction_set, quick_code), frame_size_in_bytes_(frame_size_in_bytes), 1560c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), 15772d32629303f8f39362a4099481f48646aed042fIan Rogers mapping_table_(driver->DeduplicateMappingTable(mapping_table)), 15872d32629303f8f39362a4099481f48646aed042fIan Rogers vmap_table_(driver->DeduplicateVMapTable(vmap_table)), 15972d32629303f8f39362a4099481f48646aed042fIan Rogers gc_map_(driver->DeduplicateGCMap(native_gc_map)), 16072d32629303f8f39362a4099481f48646aed042fIan Rogers cfi_info_(driver->DeduplicateCFIInfo(cfi_info)) { 1613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 16372d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod::CompiledMethod(CompilerDriver* driver, 164193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier InstructionSet instruction_set, 165e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom const std::vector<uint8_t>& code, 1663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const size_t frame_size_in_bytes, 1673320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t core_spill_mask, 168169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers const uint32_t fp_spill_mask) 16972d32629303f8f39362a4099481f48646aed042fIan Rogers : CompiledCode(driver, instruction_set, code), 170598c513a2737d872e22ea8bcedec61b92deff357Logan Chien frame_size_in_bytes_(frame_size_in_bytes), 171ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), 17272d32629303f8f39362a4099481f48646aed042fIan Rogers mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())), 17372d32629303f8f39362a4099481f48646aed042fIan Rogers vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())), 17472d32629303f8f39362a4099481f48646aed042fIan Rogers gc_map_(driver->DeduplicateGCMap(std::vector<uint8_t>())), 175ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell cfi_info_(nullptr) { 176193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier} 177193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 178193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier// Constructs a CompiledMethod for the Portable compiler. 17972d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, 180193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier const std::string& code, const std::vector<uint8_t>& gc_map, 181193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier const std::string& symbol) 18272d32629303f8f39362a4099481f48646aed042fIan Rogers : CompiledCode(driver, instruction_set, code, symbol), 183193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 18472d32629303f8f39362a4099481f48646aed042fIan Rogers fp_spill_mask_(0), gc_map_(driver->DeduplicateGCMap(gc_map)) { 18572d32629303f8f39362a4099481f48646aed042fIan Rogers mapping_table_ = driver->DeduplicateMappingTable(std::vector<uint8_t>()); 18672d32629303f8f39362a4099481f48646aed042fIan Rogers vmap_table_ = driver->DeduplicateVMapTable(std::vector<uint8_t>()); 187193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier} 188193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 18972d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, 190193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier const std::string& code, const std::string& symbol) 19172d32629303f8f39362a4099481f48646aed042fIan Rogers : CompiledCode(driver, instruction_set, code, symbol), 192193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 193193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier fp_spill_mask_(0) { 19472d32629303f8f39362a4099481f48646aed042fIan Rogers mapping_table_ = driver->DeduplicateMappingTable(std::vector<uint8_t>()); 19572d32629303f8f39362a4099481f48646aed042fIan Rogers vmap_table_ = driver->DeduplicateVMapTable(std::vector<uint8_t>()); 19672d32629303f8f39362a4099481f48646aed042fIan Rogers gc_map_ = driver->DeduplicateGCMap(std::vector<uint8_t>()); 197193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier} 198d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison 1993320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} // namespace art 200