blob: 29ff390678c03c7ab8b41688dd21d12bea85e03d [file] [log] [blame]
Mathieu Chartier193bad92013-08-29 18:46:00 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "compiled_method.h"
18#include "driver/compiler_driver.h"
19
20namespace art {
21
22CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
23 const std::vector<uint8_t>& code)
24 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), code_(nullptr) {
25 SetCode(code);
26}
27
28CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
29 const std::string& elf_object, const std::string& symbol)
30 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), symbol_(symbol) {
31 CHECK_NE(elf_object.size(), 0U);
32 CHECK_NE(symbol.size(), 0U);
33 std::vector<uint8_t> temp_code(elf_object.size());
34 for (size_t i = 0; i < elf_object.size(); ++i) {
35 temp_code[i] = elf_object[i];
36 }
37 // TODO: we shouldn't just shove ELF objects in as "code" but
38 // change to have different kinds of compiled methods. This is
39 // being deferred until we work on hybrid execution or at least
40 // until we work on batch compilation.
41 SetCode(temp_code);
42}
43
44void CompiledCode::SetCode(const std::vector<uint8_t>& code) {
45 CHECK(!code.empty());
46 code_ = compiler_driver_->DeduplicateCode(code);
47}
48
49uint32_t CompiledCode::AlignCode(uint32_t offset) const {
50 return AlignCode(offset, instruction_set_);
51}
52
53uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) {
54 switch (instruction_set) {
55 case kArm:
56 case kThumb2:
57 return RoundUp(offset, kArmAlignment);
58 case kMips:
59 return RoundUp(offset, kMipsAlignment);
60 case kX86:
61 return RoundUp(offset, kX86Alignment);
62 default:
63 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
64 return 0;
65 }
66}
67
68size_t CompiledCode::CodeDelta() const {
69 switch (instruction_set_) {
70 case kArm:
71 case kMips:
72 case kX86:
73 return 0;
74 case kThumb2: {
75 // +1 to set the low-order bit so a BLX will switch to Thumb mode
76 return 1;
77 }
78 default:
79 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_;
80 return 0;
81 }
82}
83
84const void* CompiledCode::CodePointer(const void* code_pointer,
85 InstructionSet instruction_set) {
86 switch (instruction_set) {
87 case kArm:
88 case kMips:
89 case kX86:
90 return code_pointer;
91 case kThumb2: {
92 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
93 // Set the low-order bit so a BLX will switch to Thumb mode
94 address |= 0x1;
95 return reinterpret_cast<const void*>(address);
96 }
97 default:
98 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
99 return NULL;
100 }
101}
102
103#if defined(ART_USE_PORTABLE_COMPILER)
104const std::string& CompiledCode::GetSymbol() const {
105 CHECK_NE(0U, symbol_.size());
106 return symbol_;
107}
108
109const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
110 CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_;
111 return oatdata_offsets_to_compiled_code_offset_;
112}
113
114void CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) {
115 oatdata_offsets_to_compiled_code_offset_.push_back(offset);
116}
117#endif
118
119CompiledMethod::CompiledMethod(CompilerDriver& driver,
120 InstructionSet instruction_set,
121 const std::vector<uint8_t>& code,
122 const size_t frame_size_in_bytes,
123 const uint32_t core_spill_mask,
124 const uint32_t fp_spill_mask,
125 const std::vector<uint8_t>& mapping_table,
126 const std::vector<uint8_t>& vmap_table,
127 const std::vector<uint8_t>& native_gc_map)
128 : CompiledCode(&driver, instruction_set, code), frame_size_in_bytes_(frame_size_in_bytes),
129 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask),
130 mapping_table_(driver.DeduplicateMappingTable(mapping_table)),
131 vmap_table_(driver.DeduplicateVMapTable(vmap_table)),
132 gc_map_(driver.DeduplicateGCMap(native_gc_map)) {
133}
134
135CompiledMethod::CompiledMethod(CompilerDriver& driver,
136 InstructionSet instruction_set,
137 const std::vector<uint8_t>& code,
138 const size_t frame_size_in_bytes,
139 const uint32_t core_spill_mask,
140 const uint32_t fp_spill_mask)
141 : CompiledCode(&driver, instruction_set, code),
142 frame_size_in_bytes_(frame_size_in_bytes),
143 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask) {
144 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
145 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
146 gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>());
147}
148
149// Constructs a CompiledMethod for the Portable compiler.
150CompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
151 const std::string& code, const std::vector<uint8_t>& gc_map,
152 const std::string& symbol)
153 : CompiledCode(&driver, instruction_set, code, symbol),
154 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
155 fp_spill_mask_(0), gc_map_(driver.DeduplicateGCMap(gc_map)) {
156 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
157 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
158}
159
160CompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set,
161 const std::string& code, const std::string& symbol)
162 : CompiledCode(&driver, instruction_set, code, symbol),
163 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
164 fp_spill_mask_(0) {
165 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>());
166 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>());
167 gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>());
168}
169
170} // namespace art