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 25193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 2635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const uint8_t>& quick_code) 2735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko : compiler_driver_(compiler_driver), 2835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko instruction_set_(instruction_set), 2935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko quick_code_(compiler_driver_->GetCompiledMethodStorage()->DeduplicateCode(quick_code)) { 30e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 31e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 32e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierCompiledCode::~CompiledCode() { 3335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko compiler_driver_->GetCompiledMethodStorage()->ReleaseCode(quick_code_); 34ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 35ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 36ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersbool CompiledCode::operator==(const CompiledCode& rhs) const { 37ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (quick_code_ != nullptr) { 38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (rhs.quick_code_ == nullptr) { 39ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 40ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else if (quick_code_->size() != rhs.quick_code_->size()) { 41ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return false; 42ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin()); 44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 46956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes return (rhs.quick_code_ == nullptr); 47265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 48265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 49e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiersize_t CompiledCode::AlignCode(size_t offset) const { 50598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return AlignCode(offset, instruction_set_); 51598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 52598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 53e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiersize_t CompiledCode::AlignCode(size_t offset, InstructionSet instruction_set) { 54af13ad9fd18b6f75fe82e7995224c55654594f93Andreas Gampe return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); 55598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 56598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 57598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const { 5850abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison return CodeDelta(instruction_set_); 5950abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison} 6050abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison 6150abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allisonsize_t CompiledCode::CodeDelta(InstructionSet instruction_set) { 6250abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison switch (instruction_set) { 63598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kArm: 64b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith case kArm64: 65598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kMips: 6657b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe case kMips64: 67598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kX86: 68fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko case kX86_64: 69598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 70598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kThumb2: { 71598c513a2737d872e22ea8bcedec61b92deff357Logan Chien // +1 to set the low-order bit so a BLX will switch to Thumb mode 72598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 1; 73598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 74598c513a2737d872e22ea8bcedec61b92deff357Logan Chien default: 7550abf0ad03c2cad0fa7969fc1b0bfadb0ca3bf3aDave Allison LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 76598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return 0; 77598c513a2737d872e22ea8bcedec61b92deff357Logan Chien } 78598c513a2737d872e22ea8bcedec61b92deff357Logan Chien} 79598c513a2737d872e22ea8bcedec61b92deff357Logan Chien 80598c513a2737d872e22ea8bcedec61b92deff357Logan Chienconst void* CompiledCode::CodePointer(const void* code_pointer, 81598c513a2737d872e22ea8bcedec61b92deff357Logan Chien InstructionSet instruction_set) { 82598c513a2737d872e22ea8bcedec61b92deff357Logan Chien switch (instruction_set) { 83598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kArm: 84b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith case kArm64: 85598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kMips: 8657b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe case kMips64: 87598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case kX86: 88fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko case kX86_64: 89598c513a2737d872e22ea8bcedec61b92deff357Logan Chien return code_pointer; 90598c513a2737d872e22ea8bcedec61b92deff357Logan Chien case 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, 10835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const SrcMapElem>& src_mapping_table, 109e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 110e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 111b207e1473dda1730604a28db2b4fa52f2998aeaeVladimir Marko const ArrayRef<const LinkerPatch>& patches) 11235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko : CompiledCode(driver, instruction_set, quick_code), 113e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier frame_size_in_bytes_(frame_size_in_bytes), core_spill_mask_(core_spill_mask), 114e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier fp_spill_mask_(fp_spill_mask), 11535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko src_mapping_table_( 11635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko driver->GetCompiledMethodStorage()->DeduplicateSrcMappingTable(src_mapping_table)), 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, 12935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko const ArrayRef<const SrcMapElem>& src_mapping_table, 130e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& vmap_table, 131e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe const ArrayRef<const uint8_t>& cfi_info, 132b207e1473dda1730604a28db2b4fa52f2998aeaeVladimir Marko const ArrayRef<const 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, 1429d07e3d128ccfa0ef7670feadd424a825e447d1dVladimir Marko src_mapping_table, 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_); 15935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko storage->ReleaseSrcMappingTable(src_mapping_table_); 160e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 161e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 1623320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom} // namespace art 163