5 #include "src/constant-pool.h" 6 #include "src/assembler-inl.h" 11 #if defined(V8_TARGET_ARCH_PPC) 13 ConstantPoolBuilder::ConstantPoolBuilder(
int ptr_reach_bits,
14 int double_reach_bits) {
15 info_[ConstantPoolEntry::INTPTR].entries.reserve(64);
16 info_[ConstantPoolEntry::INTPTR].regular_reach_bits = ptr_reach_bits;
17 info_[ConstantPoolEntry::DOUBLE].regular_reach_bits = double_reach_bits;
20 ConstantPoolEntry::Access ConstantPoolBuilder::NextAccess(
21 ConstantPoolEntry::Type type)
const {
22 const PerTypeEntryInfo& info = info_[type];
24 if (info.overflow())
return ConstantPoolEntry::OVERFLOWED;
26 int dbl_count = info_[ConstantPoolEntry::DOUBLE].regular_count;
27 int dbl_offset = dbl_count * kDoubleSize;
28 int ptr_count = info_[ConstantPoolEntry::INTPTR].regular_count;
29 int ptr_offset = ptr_count * kPointerSize + dbl_offset;
31 if (type == ConstantPoolEntry::DOUBLE) {
33 int ptr_reach_bits = info_[ConstantPoolEntry::INTPTR].regular_reach_bits;
34 if (!is_uintn(dbl_offset, info.regular_reach_bits) ||
36 !is_uintn(ptr_offset + kDoubleSize - kPointerSize, ptr_reach_bits))) {
37 return ConstantPoolEntry::OVERFLOWED;
40 DCHECK(type == ConstantPoolEntry::INTPTR);
41 if (!is_uintn(ptr_offset, info.regular_reach_bits)) {
42 return ConstantPoolEntry::OVERFLOWED;
46 return ConstantPoolEntry::REGULAR;
49 ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry(
50 ConstantPoolEntry& entry, ConstantPoolEntry::Type type) {
51 DCHECK(!emitted_label_.is_bound());
52 PerTypeEntryInfo& info = info_[type];
53 const int entry_size = ConstantPoolEntry::size(type);
56 if (entry.sharing_ok()) {
58 std::vector<ConstantPoolEntry>::iterator it = info.shared_entries.begin();
59 int end =
static_cast<int>(info.shared_entries.size());
60 for (
int i = 0;
i < end;
i++, it++) {
61 if ((entry_size == kPointerSize) ? entry.value() == it->value()
62 : entry.value64() == it->value64()) {
64 entry.set_merged_index(
i);
72 DCHECK(!merged || entry.merged_index() < info.regular_count);
73 ConstantPoolEntry::Access access =
74 (merged ? ConstantPoolEntry::REGULAR : NextAccess(type));
78 if (entry.sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) {
79 info.shared_entries.push_back(entry);
81 info.entries.push_back(entry);
86 if (merged || info.overflow())
return access;
88 if (access == ConstantPoolEntry::REGULAR) {
91 info.overflow_start =
static_cast<int>(info.entries.size()) - 1;
97 void ConstantPoolBuilder::EmitSharedEntries(Assembler* assm,
98 ConstantPoolEntry::Type type) {
99 PerTypeEntryInfo& info = info_[type];
100 std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
101 const int entry_size = ConstantPoolEntry::size(type);
102 int base = emitted_label_.pos();
104 int shared_end =
static_cast<int>(shared_entries.size());
105 std::vector<ConstantPoolEntry>::iterator shared_it = shared_entries.begin();
106 for (
int i = 0;
i < shared_end;
i++, shared_it++) {
107 int offset = assm->pc_offset() - base;
108 shared_it->set_offset(offset);
109 if (entry_size == kPointerSize) {
110 assm->dp(shared_it->value());
112 assm->dq(shared_it->value64());
114 DCHECK(is_uintn(offset, info.regular_reach_bits));
117 assm->PatchConstantPoolAccessInstruction(shared_it->position(), offset,
118 ConstantPoolEntry::REGULAR, type);
122 void ConstantPoolBuilder::EmitGroup(Assembler* assm,
123 ConstantPoolEntry::Access access,
124 ConstantPoolEntry::Type type) {
125 PerTypeEntryInfo& info = info_[type];
126 const bool overflow = info.overflow();
127 std::vector<ConstantPoolEntry>& entries = info.entries;
128 std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
129 const int entry_size = ConstantPoolEntry::size(type);
130 int base = emitted_label_.pos();
135 if (access == ConstantPoolEntry::REGULAR) {
137 EmitSharedEntries(assm, type);
140 if (access == ConstantPoolEntry::REGULAR) {
142 end = overflow ? info.overflow_start :
static_cast<int>(entries.size());
144 DCHECK(access == ConstantPoolEntry::OVERFLOWED);
145 if (!overflow)
return;
146 begin = info.overflow_start;
147 end =
static_cast<int>(entries.size());
150 std::vector<ConstantPoolEntry>::iterator it = entries.begin();
151 if (begin > 0) std::advance(it, begin);
152 for (
int i = begin;
i < end;
i++, it++) {
155 ConstantPoolEntry::Access entry_access;
156 if (!it->is_merged()) {
158 offset = assm->pc_offset() - base;
159 entry_access = access;
160 if (entry_size == kPointerSize) {
161 assm->dp(it->value());
163 assm->dq(it->value64());
167 offset = shared_entries[it->merged_index()].offset();
168 entry_access = ConstantPoolEntry::REGULAR;
171 DCHECK(entry_access == ConstantPoolEntry::OVERFLOWED ||
172 is_uintn(offset, info.regular_reach_bits));
175 assm->PatchConstantPoolAccessInstruction(it->position(), offset,
181 int ConstantPoolBuilder::Emit(Assembler* assm) {
182 bool emitted = emitted_label_.is_bound();
183 bool empty = IsEmpty();
187 if (!empty) assm->DataAlign(kDoubleSize);
188 assm->bind(&emitted_label_);
192 EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::DOUBLE);
193 EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::INTPTR);
194 if (info_[ConstantPoolEntry::DOUBLE].overflow()) {
195 assm->DataAlign(kDoubleSize);
196 EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
197 ConstantPoolEntry::DOUBLE);
199 if (info_[ConstantPoolEntry::INTPTR].overflow()) {
200 EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
201 ConstantPoolEntry::INTPTR);
206 return !empty ? emitted_label_.pos() : 0;
209 #endif // defined(V8_TARGET_ARCH_PPC)