compiled_method.cc revision 265091e581c9f643b37e7966890911f09e223269
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"
183320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
193320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstromnamespace art {
203320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
21265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledCode::CompiledCode(InstructionSet instruction_set, const std::vector<uint8_t>& code)
22265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    : instruction_set_(instruction_set), code_(code)
23265091e581c9f643b37e7966890911f09e223269Brian Carlstrom{
24265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(code.size(), 0U);
25265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
26265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
27265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledCode::CompiledCode(InstructionSet instruction_set,
28265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                           const std::string& elf_object,
29265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                           const std::string& symbol)
30265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    : instruction_set_(instruction_set), symbol_(symbol) {
31265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(elf_object.size(), 0U);
32265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(symbol.size(), 0U);
33265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // TODO: we shouldn't just shove ELF objects in as "code" but
34265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // change to have different kinds of compiled methods.  This is
35265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // being deferred until we work on hybrid execution or at least
36265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // until we work on batch compilation.
37265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  code_.resize(elf_object.size());
38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  memcpy(&code_[0], &elf_object[0], elf_object.size());
39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
41598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset) const {
42598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  return AlignCode(offset, instruction_set_);
43598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
44598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
45598c513a2737d872e22ea8bcedec61b92deff357Logan Chienuint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) {
46598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
47598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
48598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2:
49598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kArmAlignment);
50598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
51598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kMipsAlignment);
52598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
53598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return RoundUp(offset, kX86Alignment);
54598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
55598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
56598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
57598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
58598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
59598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
60598c513a2737d872e22ea8bcedec61b92deff357Logan Chiensize_t CompiledCode::CodeDelta() const {
61598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set_) {
62598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
63598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
64598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
65598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
66598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
67598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // +1 to set the low-order bit so a BLX will switch to Thumb mode
68598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 1;
69598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
70598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
71598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_;
72598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return 0;
73598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
74598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
75598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
76598c513a2737d872e22ea8bcedec61b92deff357Logan Chienconst void* CompiledCode::CodePointer(const void* code_pointer,
77598c513a2737d872e22ea8bcedec61b92deff357Logan Chien                                      InstructionSet instruction_set) {
78598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  switch (instruction_set) {
79598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kArm:
80598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kMips:
81598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kX86:
82598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return code_pointer;
83598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    case kThumb2: {
84598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
85598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      // Set the low-order bit so a BLX will switch to Thumb mode
86598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      address |= 0x1;
87598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return reinterpret_cast<const void*>(address);
88598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    }
89598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    default:
90598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
91598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      return NULL;
92598c513a2737d872e22ea8bcedec61b92deff357Logan Chien  }
93598c513a2737d872e22ea8bcedec61b92deff357Logan Chien}
94598c513a2737d872e22ea8bcedec61b92deff357Logan Chien
95265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER)
96265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::string& CompiledCode::GetSymbol() const {
97265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, symbol_.size());
98265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return symbol_;
99265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
100265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
101265091e581c9f643b37e7966890911f09e223269Brian Carlstromconst std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
102265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_;
103265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return oatdata_offsets_to_compiled_code_offset_;
104265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
105265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
106265091e581c9f643b37e7966890911f09e223269Brian Carlstromvoid CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
107265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  oatdata_offsets_to_compiled_code_offset_.push_back(offset);
108265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
109265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#endif
110265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1113320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiledMethod::CompiledMethod(InstructionSet instruction_set,
112ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers                               const std::vector<uint8_t>& code,
1133320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1143320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
1153320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t fp_spill_mask,
116e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                               const std::vector<uint32_t>& mapping_table,
1170c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                               const std::vector<uint16_t>& vmap_table,
1180c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                               const std::vector<uint8_t>& native_gc_map)
119265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    : CompiledCode(instruction_set, code), frame_size_in_bytes_(frame_size_in_bytes),
1200c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
1210c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      native_gc_map_(native_gc_map)
1226920bceb9636910fd82c710946313d6577fbfdfcLogan Chien{
123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  DCHECK_EQ(vmap_table.size(),
124b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers            static_cast<uint32_t>(__builtin_popcount(core_spill_mask)
125b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers                                  + __builtin_popcount(fp_spill_mask)));
126e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom  CHECK_LE(vmap_table.size(), (1U << 16) - 1); // length must fit in 2^16-1
1273320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1283320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  std::vector<uint32_t> length_prefixed_mapping_table;
1293320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  length_prefixed_mapping_table.push_back(mapping_table.size());
1303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  length_prefixed_mapping_table.insert(length_prefixed_mapping_table.end(),
1313320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                       mapping_table.begin(),
1323320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                       mapping_table.end());
1333320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  DCHECK_EQ(mapping_table.size() + 1, length_prefixed_mapping_table.size());
1343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1353320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  std::vector<uint16_t> length_prefixed_vmap_table;
1363320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  length_prefixed_vmap_table.push_back(vmap_table.size());
1373320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  length_prefixed_vmap_table.insert(length_prefixed_vmap_table.end(),
1383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                    vmap_table.begin(),
1393320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                    vmap_table.end());
1403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  DCHECK_EQ(vmap_table.size() + 1, length_prefixed_vmap_table.size());
1410dd7ddaa36a2cf37490dc166ebc21818364130a7Brian Carlstrom  DCHECK_EQ(vmap_table.size(), length_prefixed_vmap_table[0]);
1423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  mapping_table_ = length_prefixed_mapping_table;
1443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom  vmap_table_ = length_prefixed_vmap_table;
1450dd7ddaa36a2cf37490dc166ebc21818364130a7Brian Carlstrom  DCHECK_EQ(vmap_table_[0], static_cast<uint32_t>(__builtin_popcount(core_spill_mask) + __builtin_popcount(fp_spill_mask)));
1463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}
1473320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1483320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromCompiledMethod::CompiledMethod(InstructionSet instruction_set,
149e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                               const std::vector<uint8_t>& code,
1503320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const size_t frame_size_in_bytes,
1513320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                               const uint32_t core_spill_mask,
152169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogers                               const uint32_t fp_spill_mask)
153598c513a2737d872e22ea8bcedec61b92deff357Logan Chien    : CompiledCode(instruction_set, code),
154598c513a2737d872e22ea8bcedec61b92deff357Logan Chien      frame_size_in_bytes_(frame_size_in_bytes),
155265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask) {}
1563320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
157598c513a2737d872e22ea8bcedec61b92deff357Logan ChienCompiledInvokeStub::CompiledInvokeStub(InstructionSet instruction_set,
158598c513a2737d872e22ea8bcedec61b92deff357Logan Chien                                       const std::vector<uint8_t>& code)
159265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    : CompiledCode(instruction_set, code) {}
160265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
161265091e581c9f643b37e7966890911f09e223269Brian CarlstromCompiledInvokeStub::CompiledInvokeStub(InstructionSet instruction_set,
162265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                       const std::string& elf_object,
163265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                       const std::string& symbol)
164265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    : CompiledCode(instruction_set, elf_object, symbol) {}
1653320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1663320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom}  // namespace art
167