1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Test embedded constant pool builder code.
6
7 #include "src/v8.h"
8
9 #include "src/assembler.h"
10 #include "test/cctest/cctest.h"
11
12 using namespace v8::internal;
13
14 const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
15 const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
16 const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
17 const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;
18
19 const int kReachBits = 6; // Use reach of 64-bytes to test overflow.
20 const int kReach = 1 << kReachBits;
21
22
TEST(ConstantPoolPointers)23 TEST(ConstantPoolPointers) {
24 ConstantPoolBuilder builder(kReachBits, kReachBits);
25 const int kRegularCount = kReach / kPointerSize;
26 ConstantPoolEntry::Access access;
27 int pos = 0;
28 intptr_t value = 0;
29 bool sharing_ok = true;
30
31 CHECK(builder.IsEmpty());
32 while (builder.NextAccess(kPtrType) == kRegAccess) {
33 access = builder.AddEntry(pos++, value++, sharing_ok);
34 CHECK_EQ(access, kRegAccess);
35 }
36 CHECK(!builder.IsEmpty());
37 CHECK_EQ(pos, kRegularCount);
38
39 access = builder.AddEntry(pos, value, sharing_ok);
40 CHECK_EQ(access, kOvflAccess);
41 }
42
43
TEST(ConstantPoolDoubles)44 TEST(ConstantPoolDoubles) {
45 ConstantPoolBuilder builder(kReachBits, kReachBits);
46 const int kRegularCount = kReach / kDoubleSize;
47 ConstantPoolEntry::Access access;
48 int pos = 0;
49 double value = 0.0;
50
51 CHECK(builder.IsEmpty());
52 while (builder.NextAccess(kDblType) == kRegAccess) {
53 access = builder.AddEntry(pos++, value);
54 value += 0.5;
55 CHECK_EQ(access, kRegAccess);
56 }
57 CHECK(!builder.IsEmpty());
58 CHECK_EQ(pos, kRegularCount);
59
60 access = builder.AddEntry(pos, value);
61 CHECK_EQ(access, kOvflAccess);
62 }
63
64
TEST(ConstantPoolMixedTypes)65 TEST(ConstantPoolMixedTypes) {
66 ConstantPoolBuilder builder(kReachBits, kReachBits);
67 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
68 ((kPointerSize < kDoubleSize) ? 1 : 0));
69 ConstantPoolEntry::Type type = kPtrType;
70 ConstantPoolEntry::Access access;
71 int pos = 0;
72 intptr_t ptrValue = 0;
73 double dblValue = 0.0;
74 bool sharing_ok = true;
75
76 CHECK(builder.IsEmpty());
77 while (builder.NextAccess(type) == kRegAccess) {
78 if (type == kPtrType) {
79 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
80 type = kDblType;
81 } else {
82 access = builder.AddEntry(pos++, dblValue);
83 dblValue += 0.5;
84 type = kPtrType;
85 }
86 CHECK_EQ(access, kRegAccess);
87 }
88 CHECK(!builder.IsEmpty());
89 CHECK_EQ(pos, kRegularCount);
90
91 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
92 CHECK_EQ(access, kOvflAccess);
93 access = builder.AddEntry(pos, dblValue);
94 CHECK_EQ(access, kOvflAccess);
95 }
96
97
TEST(ConstantPoolMixedReach)98 TEST(ConstantPoolMixedReach) {
99 const int ptrReachBits = kReachBits + 2;
100 const int ptrReach = 1 << ptrReachBits;
101 const int dblReachBits = kReachBits;
102 const int dblReach = kReach;
103 const int dblRegularCount =
104 Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize));
105 const int ptrRegularCount =
106 ((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) /
107 kPointerSize) +
108 dblRegularCount;
109 ConstantPoolBuilder builder(ptrReachBits, dblReachBits);
110 ConstantPoolEntry::Access access;
111 int pos = 0;
112 intptr_t ptrValue = 0;
113 double dblValue = 0.0;
114 bool sharing_ok = true;
115 int ptrCount = 0;
116 int dblCount = 0;
117
118 CHECK(builder.IsEmpty());
119 while (builder.NextAccess(kDblType) == kRegAccess) {
120 access = builder.AddEntry(pos++, dblValue);
121 dblValue += 0.5;
122 dblCount++;
123 CHECK_EQ(access, kRegAccess);
124
125 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
126 ptrCount++;
127 CHECK_EQ(access, kRegAccess);
128 }
129 CHECK(!builder.IsEmpty());
130 CHECK_EQ(dblCount, dblRegularCount);
131
132 while (ptrCount < ptrRegularCount) {
133 access = builder.AddEntry(pos++, dblValue);
134 dblValue += 0.5;
135 CHECK_EQ(access, kOvflAccess);
136
137 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
138 ptrCount++;
139 CHECK_EQ(access, kRegAccess);
140 }
141 CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess);
142
143 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
144 CHECK_EQ(access, kOvflAccess);
145 access = builder.AddEntry(pos, dblValue);
146 CHECK_EQ(access, kOvflAccess);
147 }
148
149
TEST(ConstantPoolSharing)150 TEST(ConstantPoolSharing) {
151 ConstantPoolBuilder builder(kReachBits, kReachBits);
152 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
153 ((kPointerSize < kDoubleSize) ? 1 : 0));
154 ConstantPoolEntry::Access access;
155
156 CHECK(builder.IsEmpty());
157
158 ConstantPoolEntry::Type type = kPtrType;
159 int pos = 0;
160 intptr_t ptrValue = 0;
161 double dblValue = 0.0;
162 bool sharing_ok = true;
163 while (builder.NextAccess(type) == kRegAccess) {
164 if (type == kPtrType) {
165 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
166 type = kDblType;
167 } else {
168 access = builder.AddEntry(pos++, dblValue);
169 dblValue += 0.5;
170 type = kPtrType;
171 }
172 CHECK_EQ(access, kRegAccess);
173 }
174 CHECK(!builder.IsEmpty());
175 CHECK_EQ(pos, kRegularCount);
176
177 type = kPtrType;
178 ptrValue = 0;
179 dblValue = 0.0;
180 while (pos < kRegularCount * 2) {
181 if (type == kPtrType) {
182 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
183 type = kDblType;
184 } else {
185 access = builder.AddEntry(pos++, dblValue);
186 dblValue += 0.5;
187 type = kPtrType;
188 }
189 CHECK_EQ(access, kRegAccess);
190 }
191
192 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
193 CHECK_EQ(access, kOvflAccess);
194 access = builder.AddEntry(pos, dblValue);
195 CHECK_EQ(access, kOvflAccess);
196 }
197
198
TEST(ConstantPoolNoSharing)199 TEST(ConstantPoolNoSharing) {
200 ConstantPoolBuilder builder(kReachBits, kReachBits);
201 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
202 ((kPointerSize < kDoubleSize) ? 1 : 0));
203 ConstantPoolEntry::Access access;
204
205 CHECK(builder.IsEmpty());
206
207 ConstantPoolEntry::Type type = kPtrType;
208 int pos = 0;
209 intptr_t ptrValue = 0;
210 double dblValue = 0.0;
211 bool sharing_ok = false;
212 while (builder.NextAccess(type) == kRegAccess) {
213 if (type == kPtrType) {
214 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
215 type = kDblType;
216 } else {
217 access = builder.AddEntry(pos++, dblValue);
218 dblValue += 0.5;
219 type = kPtrType;
220 }
221 CHECK_EQ(access, kRegAccess);
222 }
223 CHECK(!builder.IsEmpty());
224 CHECK_EQ(pos, kRegularCount);
225
226 type = kPtrType;
227 ptrValue = 0;
228 dblValue = 0.0;
229 sharing_ok = true;
230 while (pos < kRegularCount * 2) {
231 if (type == kPtrType) {
232 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
233 type = kDblType;
234 CHECK_EQ(access, kOvflAccess);
235 } else {
236 access = builder.AddEntry(pos++, dblValue);
237 dblValue += 0.5;
238 type = kPtrType;
239 CHECK_EQ(access, kRegAccess);
240 }
241 }
242
243 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
244 CHECK_EQ(access, kOvflAccess);
245 access = builder.AddEntry(pos, dblValue);
246 CHECK_EQ(access, kOvflAccess);
247 }
248