compiled_method.cc revision 193bad9b9cfd10642043fa2ebbfc68bd5f9ede4b
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,
23193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                           const std::vector<uint8_t>& code)
24193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : compiler_driver_(compiler_driver), instruction_set_(instruction_set), code_(nullptr) {
25193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  SetCode(code);
26265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
27265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
28193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
29193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                           const std::string& elf_object, const std::string& symbol)
30193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : compiler_driver_(compiler_driver), instruction_set_(instruction_set), symbol_(symbol) {
31265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(elf_object.size(), 0U);
32265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(symbol.size(), 0U);
33193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  std::vector<uint8_t> temp_code(elf_object.size());
34193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  for (size_t i = 0; i < elf_object.size(); ++i) {
35193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    temp_code[i] = elf_object[i];
36193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  }
37265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // TODO: we shouldn't just shove ELF objects in as "code" but
38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // change to have different kinds of compiled methods.  This is
39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // being deferred until we work on hybrid execution or at least
40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // until we work on batch compilation.
41193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  SetCode(temp_code);
42193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
43193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
44193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartiervoid CompiledCode::SetCode(const std::vector<uint8_t>& code) {
45193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  CHECK(!code.empty());
46193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  code_ = compiler_driver_->DeduplicateCode(code);
47265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
48265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
49598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset) const {
50598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  return AlignCode(offset, instruction_set_);
51598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
52598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
53598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) {
54598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
55598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
56598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2:
57598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kArmAlignment);
58598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
59598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kMipsAlignment);
60598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
61598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kX86Alignment);
62598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
63598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
64598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
65598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
66598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
67598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
68598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const {
69598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set_) {
70598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
71598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
72598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
73598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
74598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
75598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // +1 to set the low-order bit so a BLX will switch to Thumb mode
76598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 1;
77598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
78598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
79598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_;
80598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
81598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
82598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
83598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
84598c513a2737d872e22ea8bcedec61b92deff357Logan Chienconst void* CompiledCode::CodePointer(const void* code_pointer,
85598c513a2737d872e22ea8bcedec61b92deff357Logan Chien                                      InstructionSet instruction_set) {
86598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
87598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
88598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
89598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
90598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return code_pointer;
91598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
92598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
93598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // Set the low-order bit so a BLX will switch to Thumb mode
94598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      address |= 0x1;
95598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return reinterpret_cast<const void*>(address);
96598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
97598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
98598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
99598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return NULL;
100598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
101598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
102598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
103265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER)
104265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::string& CompiledCode::GetSymbol() const {
105265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, symbol_.size());
106265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return symbol_;
107265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
108265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
109265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
110265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_;
111265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return oatdata_offsets_to_compiled_code_offset_;
112265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
113265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
114265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
115265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  oatdata_offsets_to_compiled_code_offset_.push_back(offset);
116265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
117265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif
118265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
119193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver,
120193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               InstructionSet instruction_set,
121ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers                               const std::vector<uint8_t>& code,
1223320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1233320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
1243320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t fp_spill_mask,
12596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers                               const std::vector<uint8_t>& mapping_table,
12696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers                               const std::vector<uint8_t>& vmap_table,
1270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                               const std::vector<uint8_t>& native_gc_map)
128193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code), frame_size_in_bytes_(frame_size_in_bytes),
1290c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
130193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_(driver.DeduplicateMappingTable(mapping_table)),
131193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_(driver.DeduplicateVMapTable(vmap_table)),
132193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  gc_map_(driver.DeduplicateGCMap(native_gc_map)) {
1333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
1343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
135193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver,
136193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               InstructionSet instruction_set,
137e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                               const std::vector<uint8_t>& code,
1383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
140169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers                               const uint32_t fp_spill_mask)
141193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code),
142598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      frame_size_in_bytes_(frame_size_in_bytes),
143193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask) {
144193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
145193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
146193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>());
147193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
148193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
149193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier// Constructs a CompiledMethod for the Portable compiler.
150193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
151193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& code, const std::vector<uint8_t>& gc_map,
152193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& symbol)
153193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code, symbol),
154193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
155193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      fp_spill_mask_(0), gc_map_(driver.DeduplicateGCMap(gc_map)) {
156193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
157193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
158193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
159193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier
160193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu ChartierCompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
161193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                               const std::string& code, const std::string& symbol)
162193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier    : CompiledCode(&driver, instruction_set, code, symbol),
163193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
164193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      fp_spill_mask_(0) {
165193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
166193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
167193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>());
168193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier}
1693320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1703320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}  // namespace art
171