blob: 082600f5abce56ab7c36fcb702648f5f5fa9f69f [file] [log] [blame]
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "compiled_method.h"
4
5namespace art {
6
7CompiledMethod::CompiledMethod(InstructionSet instruction_set,
8 std::vector<short>& short_code,
9 const size_t frame_size_in_bytes,
10 const size_t return_pc_offset_in_bytes,
11 const uint32_t core_spill_mask,
12 const uint32_t fp_spill_mask,
13 std::vector<uint32_t>& mapping_table,
14 std::vector<uint16_t>& vmap_table) {
15 CHECK_NE(short_code.size(), 0U);
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -070016 CHECK_GE(vmap_table.size(), 1U); // should always contain an entry for LR
Brian Carlstrom3320cf42011-10-04 14:58:28 -070017
18 size_t code_byte_count = short_code.size() * sizeof(short_code[0]);
19 std::vector<uint8_t> byte_code(code_byte_count);
20 memcpy(&byte_code[0], &short_code[0], code_byte_count);
21
22 std::vector<uint32_t> length_prefixed_mapping_table;
23 length_prefixed_mapping_table.push_back(mapping_table.size());
24 length_prefixed_mapping_table.insert(length_prefixed_mapping_table.end(),
25 mapping_table.begin(),
26 mapping_table.end());
27 DCHECK_EQ(mapping_table.size() + 1, length_prefixed_mapping_table.size());
28
29 std::vector<uint16_t> length_prefixed_vmap_table;
30 length_prefixed_vmap_table.push_back(vmap_table.size());
31 length_prefixed_vmap_table.insert(length_prefixed_vmap_table.end(),
32 vmap_table.begin(),
33 vmap_table.end());
34 DCHECK_EQ(vmap_table.size() + 1, length_prefixed_vmap_table.size());
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -070035 DCHECK_EQ(vmap_table.size(), length_prefixed_vmap_table[0]);
Brian Carlstrom3320cf42011-10-04 14:58:28 -070036
37 instruction_set_ = instruction_set;
38 code_ = byte_code;
39 frame_size_in_bytes_ = frame_size_in_bytes;
40 return_pc_offset_in_bytes_ = return_pc_offset_in_bytes;
41 core_spill_mask_ = core_spill_mask;
42 fp_spill_mask_ = fp_spill_mask;
43 mapping_table_ = length_prefixed_mapping_table;
44 vmap_table_ = length_prefixed_vmap_table;
Brian Carlstrom0dd7dda2011-10-25 15:47:53 -070045
46 DCHECK_EQ(vmap_table_[0], static_cast<uint32_t>(__builtin_popcount(core_spill_mask) + __builtin_popcount(fp_spill_mask)));
Brian Carlstrom3320cf42011-10-04 14:58:28 -070047}
48
49CompiledMethod::CompiledMethod(InstructionSet instruction_set,
50 std::vector<uint8_t>& code,
51 const size_t frame_size_in_bytes,
52 const size_t return_pc_offset_in_bytes,
53 const uint32_t core_spill_mask,
54 const uint32_t fp_spill_mask) {
55 CHECK_NE(code.size(), 0U);
56
57 instruction_set_ = instruction_set;
58 code_ = code;
59 frame_size_in_bytes_ = frame_size_in_bytes;
60 return_pc_offset_in_bytes_ = return_pc_offset_in_bytes;
61 core_spill_mask_ = core_spill_mask;
62 fp_spill_mask_ = fp_spill_mask;
63}
64
65CompiledMethod::~CompiledMethod() {}
66
67InstructionSet CompiledMethod::GetInstructionSet() const {
68 return instruction_set_;
69}
70
71const std::vector<uint8_t>& CompiledMethod::GetCode() const {
72 return code_;
73}
74
75size_t CompiledMethod::GetFrameSizeInBytes() const {
76 return frame_size_in_bytes_;
77}
78
79size_t CompiledMethod::GetReturnPcOffsetInBytes() const {
80 return return_pc_offset_in_bytes_;
81}
82
83uint32_t CompiledMethod::GetCoreSpillMask() const {
84 return core_spill_mask_;
85}
86
87uint32_t CompiledMethod::GetFpSpillMask() const {
88 return fp_spill_mask_;
89}
90
91const std::vector<uint32_t>& CompiledMethod::GetMappingTable() const {
92 return mapping_table_;
93}
94
95const std::vector<uint16_t>& CompiledMethod::GetVmapTable() const {
96 return vmap_table_;
97}
98
99uint32_t CompiledMethod::AlignCode(uint32_t offset) const {
100 return AlignCode(offset, instruction_set_);
101}
102
103uint32_t CompiledMethod::AlignCode(uint32_t offset, InstructionSet instruction_set) {
104 switch (instruction_set) {
105 case kArm:
106 case kThumb2:
107 return RoundUp(offset, kArmAlignment);
108 case kX86:
109 return offset;
110 default:
111 LOG(FATAL) << "Unknown InstructionSet " << (int) instruction_set;
112 return 0;
113 }
114}
115
116size_t CompiledMethod::CodeDelta() const {
117 switch (instruction_set_) {
118 case kArm:
119 case kX86:
120 return 0;
121 case kThumb2: {
122 // +1 to set the low-order bit so a BLX will switch to Thumb mode
123 return 1;
124 }
125 default:
126 LOG(FATAL) << "Unknown InstructionSet " << (int) instruction_set_;
127 return NULL;
128 }
129}
130
131const void* CompiledMethod::CodePointer(const void* code_pointer,
132 InstructionSet instruction_set) {
133 switch (instruction_set) {
134 case kArm:
135 case kX86:
136 return code_pointer;
137 case kThumb2: {
138 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer);
139 // Set the low-order bit so a BLX will switch to Thumb mode
140 address |= 0x1;
141 return reinterpret_cast<const void*>(address);
142 }
143 default:
144 LOG(FATAL) << "Unknown InstructionSet " << (int) instruction_set;
145 return NULL;
146 }
147}
148
149
150CompiledInvokeStub::CompiledInvokeStub(std::vector<uint8_t>& code) {
151 CHECK_NE(code.size(), 0U);
152 code_ = code;
153}
154
155CompiledInvokeStub::~CompiledInvokeStub() {}
156
157const std::vector<uint8_t>& CompiledInvokeStub::GetCode() const {
158 return code_;
159}
160
161} // namespace art