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" 1835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko 1935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "driver/compiled_method_storage.h" 20193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier#include "driver/compiler_driver.h" 2135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "utils/swap_space.h" 223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromnamespace art { 243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 25d8dbc8da0e5cc6b5c2176ce2d3877e6194d72c0cVladimir MarkoCompiledCode::CompiledCode(CompilerDriver* compiler_driver, 26d8dbc8da0e5cc6b5c2176ce2d3877e6194d72c0cVladimir Marko InstructionSet instruction_set, 2735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const uint8_t>& quick_code) 2835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko : compiler_driver_(compiler_driver), 2992f7f3ce3b01f7c7df1c15b81c900e087248093fVladimir Marko quick_code_(compiler_driver_->GetCompiledMethodStorage()->DeduplicateCode(quick_code)), 3092f7f3ce3b01f7c7df1c15b81c900e087248093fVladimir Marko packed_fields_(InstructionSetField::Encode(instruction_set)) { 31e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 32e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 33e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierCompiledCode::~CompiledCode() { 3435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko compiler_driver_->GetCompiledMethodStorage()->ReleaseCode(quick_code_); 35ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 36ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 37ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersbool CompiledCode::operator==(const CompiledCode& rhs) const { 38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (quick_code_ != nullptr) { 39ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (rhs.quick_code_ == nullptr) { 40ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 41ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else if (quick_code_->size() != rhs.quick_code_->size()) { 42ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin()); 45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 46ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 47956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes return (rhs.quick_code_ == nullptr); 48265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 49265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 50e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiersize_t CompiledCode::AlignCode(size_t offset) const { 5192f7f3ce3b01f7c7df1c15b81c900e087248093fVladimir Marko return AlignCode(offset, GetInstructionSet()); 52598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 53598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 54e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiersize_t CompiledCode::AlignCode(size_t offset, InstructionSet instruction_set) { 55af13ad9fd18b6f75fe82e7995224c55654594f93Andreas Gampe return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); 56598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 57598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 58598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const { 5992f7f3ce3b01f7c7df1c15b81c900e087248093fVladimir Marko return CodeDelta(GetInstructionSet()); 6050abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison} 6150abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison 6250abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allisonsize_t CompiledCode::CodeDelta(InstructionSet instruction_set) { 6350abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison switch (instruction_set) { 6433bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kArm: 6533bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kArm64: 6633bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kMips: 6733bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kMips64: 6833bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kX86: 6933bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kX86_64: 70598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 7133bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kThumb2: { 72598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // +1 to set the low-order bit so a BLX will switch to Thumb mode 73598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 1; 74598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 75598c513a2737d872e22ea8bcedec61b92deff357Logan Chien default: 7650abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 77598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 78598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 79598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 80598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 81d8dbc8da0e5cc6b5c2176ce2d3877e6194d72c0cVladimir Markoconst void* CompiledCode::CodePointer(const void* code_pointer, InstructionSet instruction_set) { 82598c513a2737d872e22ea8bcedec61b92deff357Logan Chien switch (instruction_set) { 8333bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kArm: 8433bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kArm64: 8533bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kMips: 8633bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kMips64: 8733bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kX86: 8833bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kX86_64: 89598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return code_pointer; 9033bff25bcd7a02d35c54f63740eadb1a4833fc92Vladimir Marko case InstructionSet::kThumb2: { 91598c513a2737d872e22ea8bcedec61b92deff357Logan Chien uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer); 92598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // Set the low-order bit so a BLX will switch to Thumb mode 93598c513a2737d872e22ea8bcedec61b92deff357Logan Chien address |= 0x1; 94598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return reinterpret_cast<const void*>(address); 95598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 96598c513a2737d872e22ea8bcedec61b92deff357Logan Chien default: 97598c513a2737d872e22ea8bcedec61b92deff357Logan Chien LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 982cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 99598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 100598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 101598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 10272d32629303f8f39362a4099481f48646aed042fIan RogersCompiledMethod::CompiledMethod(CompilerDriver* driver, 103193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier InstructionSet instruction_set, 104e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& quick_code, 1053320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const size_t frame_size_in_bytes, 1063320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t core_spill_mask, 1073320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom const uint32_t fp_spill_mask, 108cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier const ArrayRef<const uint8_t>& method_info, 109e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 110e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 111d8dbc8da0e5cc6b5c2176ce2d3877e6194d72c0cVladimir Marko const ArrayRef<const linker::LinkerPatch>& patches) 11235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko : CompiledCode(driver, instruction_set, quick_code), 113cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier frame_size_in_bytes_(frame_size_in_bytes), 114cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier core_spill_mask_(core_spill_mask), 115e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier fp_spill_mask_(fp_spill_mask), 116cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier method_info_(driver->GetCompiledMethodStorage()->DeduplicateMethodInfo(method_info)), 11735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko vmap_table_(driver->GetCompiledMethodStorage()->DeduplicateVMapTable(vmap_table)), 11835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko cfi_info_(driver->GetCompiledMethodStorage()->DeduplicateCFIInfo(cfi_info)), 11935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko patches_(driver->GetCompiledMethodStorage()->DeduplicateLinkerPatches(patches)) { 1203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} 1213320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom 122e21dc3db191df04c100620965bee4617b3b24397Andreas GampeCompiledMethod* CompiledMethod::SwapAllocCompiledMethod( 123e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe CompilerDriver* driver, 124e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe InstructionSet instruction_set, 125e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& quick_code, 126e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const size_t frame_size_in_bytes, 127e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const uint32_t core_spill_mask, 128e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const uint32_t fp_spill_mask, 129cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier const ArrayRef<const uint8_t>& method_info, 130e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 131e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 132d8dbc8da0e5cc6b5c2176ce2d3877e6194d72c0cVladimir Marko const ArrayRef<const linker::LinkerPatch>& patches) { 13335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko SwapAllocator<CompiledMethod> alloc(driver->GetCompiledMethodStorage()->GetSwapSpaceAllocator()); 134e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe CompiledMethod* ret = alloc.allocate(1); 1359d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko alloc.construct(ret, 1369d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko driver, 1379d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko instruction_set, 1389d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko quick_code, 1399d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko frame_size_in_bytes, 1409d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko core_spill_mask, 1419d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko fp_spill_mask, 142cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier method_info, 1439d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko vmap_table, 144e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe cfi_info, patches); 145e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe return ret; 1463946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray} 1473946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray 148e21dc3db191df04c100620965bee4617b3b24397Andreas Gampevoid CompiledMethod::ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m) { 14935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko SwapAllocator<CompiledMethod> alloc(driver->GetCompiledMethodStorage()->GetSwapSpaceAllocator()); 150e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe alloc.destroy(m); 151e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe alloc.deallocate(m, 1); 152193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier} 153193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier 154e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierCompiledMethod::~CompiledMethod() { 15535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko CompiledMethodStorage* storage = GetCompilerDriver()->GetCompiledMethodStorage(); 15635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko storage->ReleaseLinkerPatches(patches_); 15735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko storage->ReleaseCFIInfo(cfi_info_); 15835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko storage->ReleaseVMapTable(vmap_table_); 159cbcedbf9382bc773713cd3552ed96f417bf1daebMathieu Chartier storage->ReleaseMethodInfo(method_info_); 160e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 161e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} // namespace art 163