compiled_method.cc revision ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4
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,
23ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers                           const std::vector<uint8_t>& quick_code)
24ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    : compiler_driver_(compiler_driver), instruction_set_(instruction_set),
25ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      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),
32ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      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) {
85598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
86598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
87598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2:
88598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kArmAlignment);
89598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
90598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kMipsAlignment);
91598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
92598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kX86Alignment);
93598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
94598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
95598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
96598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
97598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
98598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
99598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const {
100598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set_) {
101598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
102598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
103598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
104598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
105598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
106598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // +1 to set the low-order bit so a BLX will switch to Thumb mode
107598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 1;
108598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
109598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
110598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_;
111598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
112598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
113598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
114598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
115598c513a2737d872e22ea8bcedec61b92deff357Logan Chienconst void* CompiledCode::CodePointer(const void* code_pointer,
116598c513a2737d872e22ea8bcedec61b92deff357Logan Chien                                      InstructionSet instruction_set) {
117598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
118598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
119598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
120598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
121598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return code_pointer;
122598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
123598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
124598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // Set the low-order bit so a BLX will switch to Thumb mode
125598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      address |= 0x1;
126598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return reinterpret_cast<const void*>(address);
127598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
128598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
129598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
130598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return NULL;
131598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
132598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
133598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
134265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::string& CompiledCode::GetSymbol() const {
135265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, symbol_.size());
136265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return symbol_;
137265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
138265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
139265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
140265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_;
141265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return oatdata_offsets_to_compiled_code_offset_;
142265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
143265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
144265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
145265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  oatdata_offsets_to_compiled_code_offset_.push_back(offset);
146265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
147265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
148193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver,
149193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               InstructionSet instruction_set,
150ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers                               const std::vector<uint8_t>& quick_code,
1513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1523320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
1533320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t fp_spill_mask,
15496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers                               const std::vector<uint8_t>& mapping_table,
15596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers                               const std::vector<uint8_t>& vmap_table,
156ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell                               const std::vector<uint8_t>& native_gc_map,
157ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell                               const std::vector<uint8_t>* cfi_info)
158ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    : CompiledCode(&driver, instruction_set, quick_code), frame_size_in_bytes_(frame_size_in_bytes),
1590c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
160193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_(driver.DeduplicateMappingTable(mapping_table)),
161193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_(driver.DeduplicateVMapTable(vmap_table)),
162ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  gc_map_(driver.DeduplicateGCMap(native_gc_map)),
163ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  cfi_info_(driver.DeduplicateCFIInfo(cfi_info)) {
1643320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
1653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
166193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver,
167193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               InstructionSet instruction_set,
168e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                               const std::vector<uint8_t>& code,
1693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
171169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers                               const uint32_t fp_spill_mask)
172193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code),
173598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      frame_size_in_bytes_(frame_size_in_bytes),
174ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
175ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      mapping_table_(driver.DeduplicateMappingTable(std::vector<uint8_t>())),
176ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      vmap_table_(driver.DeduplicateVMapTable(std::vector<uint8_t>())),
177ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      gc_map_(driver.DeduplicateGCMap(std::vector<uint8_t>())),
178ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      cfi_info_(nullptr) {
179193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
180193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
181193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier// Constructs a CompiledMethod for the Portable compiler.
182193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
183193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& code, const std::vector<uint8_t>& gc_map,
184193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& symbol)
185193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code, symbol),
186193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
187193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      fp_spill_mask_(0), gc_map_(driver.DeduplicateGCMap(gc_map)) {
188193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
189193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
190193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
191193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
192193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
193193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& code, const std::string& symbol)
194193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code, symbol),
195193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
196193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      fp_spill_mask_(0) {
197193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
198193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
199193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>());
200193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
2013320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
2023320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}  // namespace art
203