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