Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: test/cctest/test-constantpool.cc

Issue 1131783003: Embedded constant pools. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address remaining comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
rmcilroy 2015/06/01 09:52:09 2015. Also you just need the short copyright notic
MTBrandyberry 2015/06/01 21:01:30 Done.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // Test constant pool array code. 28 // Test embedded constant pool builder code.
29 29
30 #include "src/v8.h" 30 #include "src/v8.h"
31 31
32 #include "src/factory.h" 32 #include "src/assembler.h"
33 #include "src/objects.h"
34 #include "test/cctest/cctest.h" 33 #include "test/cctest/cctest.h"
35 34
36 using namespace v8::internal; 35 using namespace v8::internal;
37 36
38 static ConstantPoolArray::Type kTypes[] = { ConstantPoolArray::INT64, 37 const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
39 ConstantPoolArray::CODE_PTR, 38 const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
40 ConstantPoolArray::HEAP_PTR, 39 const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
41 ConstantPoolArray::INT32 }; 40 const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;
42 static ConstantPoolArray::LayoutSection kSmall =
43 ConstantPoolArray::SMALL_SECTION;
44 static ConstantPoolArray::LayoutSection kExtended =
45 ConstantPoolArray::EXTENDED_SECTION;
46 41
47 Code* DummyCode(LocalContext* context) { 42 const int kReachBits = 6; // Use reach of 64-bytes to test overflow.
48 CompileRun("function foo() {};"); 43 const int kReach = 1 << kReachBits;
rmcilroy 2015/06/01 09:52:09 nit - could you add one test which has dblReach di
MTBrandyberry 2015/06/01 21:01:30 Done.
49 i::Handle<i::JSFunction> fun = v8::Utils::OpenHandle( 44
50 *v8::Local<v8::Function>::Cast( 45
51 (*context)->Global()->Get(v8_str("foo")))); 46 TEST(ConstantPoolPointers) {
52 return fun->code(); 47 ConstantPoolBuilder builder(kReachBits, kReachBits);
48 const int kRegularCount = kReach / kPointerSize;
49 ConstantPoolEntry::Access access;
50 int pos = 0;
51 intptr_t value = 0;
52 bool sharing_ok = true;
53
54 CHECK(builder.IsEmpty());
55 while (builder.NextAccess(kPtrType) == kRegAccess) {
56 access = builder.AddEntry(pos++, value++, sharing_ok);
57 CHECK_EQ(access, kRegAccess);
58 }
59 CHECK(!builder.IsEmpty());
60 CHECK_EQ(pos, kRegularCount);
61
62 access = builder.AddEntry(pos, value, sharing_ok);
63 CHECK_EQ(access, kOvflAccess);
53 } 64 }
54 65
55 66
56 TEST(ConstantPoolSmall) { 67 TEST(ConstantPoolDoubles) {
57 LocalContext context; 68 ConstantPoolBuilder builder(kReachBits, kReachBits);
58 Isolate* isolate = CcTest::i_isolate(); 69 const int kRegularCount = kReach / kDoubleSize;
59 Factory* factory = isolate->factory(); 70 ConstantPoolEntry::Access access;
60 v8::HandleScope scope(context->GetIsolate()); 71 int pos = 0;
72 double value = 0.0;
61 73
62 // Check construction. 74 CHECK(builder.IsEmpty());
63 ConstantPoolArray::NumberOfEntries small(3, 1, 2, 1); 75 while (builder.NextAccess(kDblType) == kRegAccess) {
64 Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small); 76 access = builder.AddEntry(pos++, value);
77 value += 0.5;
78 CHECK_EQ(access, kRegAccess);
79 }
80 CHECK(!builder.IsEmpty());
81 CHECK_EQ(pos, kRegularCount);
65 82
66 int expected_counts[] = { 3, 1, 2, 1 }; 83 access = builder.AddEntry(pos, value);
67 int expected_first_idx[] = { 0, 3, 4, 6 }; 84 CHECK_EQ(access, kOvflAccess);
68 int expected_last_idx[] = { 2, 3, 5, 6 };
69 for (int i = 0; i < 4; i++) {
70 CHECK_EQ(expected_counts[i], array->number_of_entries(kTypes[i], kSmall));
71 CHECK_EQ(expected_first_idx[i], array->first_index(kTypes[i], kSmall));
72 CHECK_EQ(expected_last_idx[i], array->last_index(kTypes[i], kSmall));
73 }
74 CHECK(!array->is_extended_layout());
75
76 // Check getters and setters.
77 int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
78 Handle<Object> object = factory->NewHeapNumber(4.0, IMMUTABLE, TENURED);
79 Code* code = DummyCode(&context);
80 array->set(0, big_number);
81 array->set(1, 0.5);
82 array->set(2, 3e-24);
83 array->set(3, code->entry());
84 array->set(4, code);
85 array->set(5, *object);
86 array->set(6, 50);
87 CHECK_EQ(big_number, array->get_int64_entry(0));
88 CHECK_EQ(0.5, array->get_int64_entry_as_double(1));
89 CHECK_EQ(3e-24, array->get_int64_entry_as_double(2));
90 CHECK_EQ(code->entry(), array->get_code_ptr_entry(3));
91 CHECK_EQ(code, array->get_heap_ptr_entry(4));
92 CHECK_EQ(*object, array->get_heap_ptr_entry(5));
93 CHECK_EQ(50, array->get_int32_entry(6));
94 } 85 }
95 86
96 87
97 TEST(ConstantPoolExtended) { 88 TEST(ConstantPoolMixedTypes) {
98 LocalContext context; 89 ConstantPoolBuilder builder(kReachBits, kReachBits);
99 Isolate* isolate = CcTest::i_isolate(); 90 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
100 Factory* factory = isolate->factory(); 91 ((kPointerSize < kDoubleSize) ? 1 : 0));
101 v8::HandleScope scope(context->GetIsolate()); 92 ConstantPoolEntry::Type type = kPtrType;
93 ConstantPoolEntry::Access access;
94 int pos = 0;
95 intptr_t ptrValue = 0;
96 double dblValue = 0.0;
97 bool sharing_ok = true;
102 98
103 // Check construction. 99 CHECK(builder.IsEmpty());
104 ConstantPoolArray::NumberOfEntries small(1, 2, 3, 4); 100 while (builder.NextAccess(type) == kRegAccess) {
105 ConstantPoolArray::NumberOfEntries extended(5, 6, 7, 8); 101 if (type == kPtrType) {
106 Handle<ConstantPoolArray> array = 102 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
107 factory->NewExtendedConstantPoolArray(small, extended); 103 type = kDblType;
104 } else {
105 access = builder.AddEntry(pos++, dblValue);
106 dblValue += 0.5;
107 type = kPtrType;
108 }
109 CHECK_EQ(access, kRegAccess);
110 }
111 CHECK(!builder.IsEmpty());
112 CHECK_EQ(pos, kRegularCount);
108 113
109 // Check small section. 114 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
110 int small_counts[] = { 1, 2, 3, 4 }; 115 CHECK_EQ(access, kOvflAccess);
111 int small_first_idx[] = { 0, 1, 3, 6 }; 116 access = builder.AddEntry(pos, dblValue);
112 int small_last_idx[] = { 0, 2, 5, 9 }; 117 CHECK_EQ(access, kOvflAccess);
113 for (int i = 0; i < 4; i++) { 118 }
114 CHECK_EQ(small_counts[i], array->number_of_entries(kTypes[i], kSmall)); 119
115 CHECK_EQ(small_first_idx[i], array->first_index(kTypes[i], kSmall)); 120
116 CHECK_EQ(small_last_idx[i], array->last_index(kTypes[i], kSmall)); 121 TEST(ConstantPoolSharing) {
122 ConstantPoolBuilder builder(kReachBits, kReachBits);
123 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
124 ((kPointerSize < kDoubleSize) ? 1 : 0));
125 ConstantPoolEntry::Access access;
126
127 CHECK(builder.IsEmpty());
128
129 ConstantPoolEntry::Type type = kPtrType;
130 int pos = 0;
131 intptr_t ptrValue = 0;
132 double dblValue = 0.0;
133 bool sharing_ok = true;
134 while (builder.NextAccess(type) == kRegAccess) {
135 if (type == kPtrType) {
136 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
137 type = kDblType;
138 } else {
139 access = builder.AddEntry(pos++, dblValue);
140 dblValue += 0.5;
141 type = kPtrType;
142 }
143 CHECK_EQ(access, kRegAccess);
144 }
145 CHECK(!builder.IsEmpty());
146 CHECK_EQ(pos, kRegularCount);
147
148 type = kPtrType;
149 ptrValue = 0;
150 dblValue = 0.0;
151 while (pos < kRegularCount * 2) {
152 if (type == kPtrType) {
153 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
154 type = kDblType;
155 } else {
156 access = builder.AddEntry(pos++, dblValue);
157 dblValue += 0.5;
158 type = kPtrType;
159 }
160 CHECK_EQ(access, kRegAccess);
117 } 161 }
118 162
119 // Check extended layout. 163 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
120 CHECK(array->is_extended_layout()); 164 CHECK_EQ(access, kOvflAccess);
121 int extended_counts[] = { 5, 6, 7, 8 }; 165 access = builder.AddEntry(pos, dblValue);
122 int extended_first_idx[] = { 10, 15, 21, 28 }; 166 CHECK_EQ(access, kOvflAccess);
123 int extended_last_idx[] = { 14, 20, 27, 35 }; 167 }
124 for (int i = 0; i < 4; i++) { 168
125 CHECK_EQ(extended_counts[i], 169
126 array->number_of_entries(kTypes[i], kExtended)); 170 TEST(ConstantPoolNoSharing) {
127 CHECK_EQ(extended_first_idx[i], array->first_index(kTypes[i], kExtended)); 171 ConstantPoolBuilder builder(kReachBits, kReachBits);
128 CHECK_EQ(extended_last_idx[i], array->last_index(kTypes[i], kExtended)); 172 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
173 ((kPointerSize < kDoubleSize) ? 1 : 0));
174 ConstantPoolEntry::Access access;
175
176 CHECK(builder.IsEmpty());
177
178 ConstantPoolEntry::Type type = kPtrType;
179 int pos = 0;
180 intptr_t ptrValue = 0;
181 double dblValue = 0.0;
182 bool sharing_ok = false;
183 while (builder.NextAccess(type) == kRegAccess) {
184 if (type == kPtrType) {
185 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
186 type = kDblType;
187 } else {
188 access = builder.AddEntry(pos++, dblValue);
189 dblValue += 0.5;
190 type = kPtrType;
191 }
192 CHECK_EQ(access, kRegAccess);
129 } 193 }
194 CHECK(!builder.IsEmpty());
195 CHECK_EQ(pos, kRegularCount);
130 196
131 // Check small and large section's don't overlap. 197 type = kPtrType;
132 int64_t small_section_int64 = V8_2PART_UINT64_C(0x56781234, DEF09ABC); 198 ptrValue = 0;
133 Code* small_section_code_ptr = DummyCode(&context); 199 dblValue = 0.0;
134 Handle<Object> small_section_heap_ptr = 200 sharing_ok = true;
135 factory->NewHeapNumber(4.0, IMMUTABLE, TENURED); 201 while (pos < kRegularCount * 2) {
136 int32_t small_section_int32 = 0xab12cd45; 202 if (type == kPtrType) {
137 203 access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
138 int64_t extended_section_int64 = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0); 204 type = kDblType;
139 Code* extended_section_code_ptr = DummyCode(&context); 205 CHECK_EQ(access, kOvflAccess);
140 Handle<Object> extended_section_heap_ptr =
141 factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
142 int32_t extended_section_int32 = 0xef67ab89;
143
144 for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
145 i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
146 if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
147 array->set(i, small_section_int64);
148 } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
149 array->set(i, small_section_code_ptr->entry());
150 } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
151 array->set(i, *small_section_heap_ptr);
152 } else { 206 } else {
153 CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall)); 207 access = builder.AddEntry(pos++, dblValue);
154 array->set(i, small_section_int32); 208 dblValue += 0.5;
155 } 209 type = kPtrType;
156 } 210 CHECK_EQ(access, kRegAccess);
157 for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
158 i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
159 if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
160 array->set(i, extended_section_int64);
161 } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
162 array->set(i, extended_section_code_ptr->entry());
163 } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
164 array->set(i, *extended_section_heap_ptr);
165 } else {
166 CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
167 array->set(i, extended_section_int32);
168 } 211 }
169 } 212 }
170 213
171 for (int i = array->first_index(ConstantPoolArray::INT64, kSmall); 214 access = builder.AddEntry(pos++, ptrValue, sharing_ok);
172 i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) { 215 CHECK_EQ(access, kOvflAccess);
173 if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) { 216 access = builder.AddEntry(pos, dblValue);
174 CHECK_EQ(small_section_int64, array->get_int64_entry(i)); 217 CHECK_EQ(access, kOvflAccess);
175 } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
176 CHECK_EQ(small_section_code_ptr->entry(), array->get_code_ptr_entry(i));
177 } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
178 CHECK_EQ(*small_section_heap_ptr, array->get_heap_ptr_entry(i));
179 } else {
180 CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
181 CHECK_EQ(small_section_int32, array->get_int32_entry(i));
182 }
183 }
184 for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
185 i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
186 if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
187 CHECK_EQ(extended_section_int64, array->get_int64_entry(i));
188 } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
189 CHECK_EQ(extended_section_code_ptr->entry(),
190 array->get_code_ptr_entry(i));
191 } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
192 CHECK_EQ(*extended_section_heap_ptr, array->get_heap_ptr_entry(i));
193 } else {
194 CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
195 CHECK_EQ(extended_section_int32, array->get_int32_entry(i));
196 }
197 }
198 } 218 }
rmcilroy 2015/06/01 09:52:09 It would be nice if you could test the emitting lo
MTBrandyberry 2015/06/01 21:01:31 I considered this, however other than validating t
rmcilroy 2015/06/02 13:57:21 OK fair enough.
199
200
201 static void CheckIterator(Handle<ConstantPoolArray> array,
202 ConstantPoolArray::Type type,
203 int expected_indexes[],
204 int count) {
205 int i = 0;
206 ConstantPoolArray::Iterator iter(*array, type);
207 while (!iter.is_finished()) {
208 CHECK_EQ(expected_indexes[i++], iter.next_index());
209 }
210 CHECK_EQ(count, i);
211 }
212
213
214 TEST(ConstantPoolIteratorSmall) {
215 LocalContext context;
216 Isolate* isolate = CcTest::i_isolate();
217 Factory* factory = isolate->factory();
218 v8::HandleScope scope(context->GetIsolate());
219
220 ConstantPoolArray::NumberOfEntries small(1, 5, 2, 0);
221 Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
222
223 int expected_int64_indexs[] = { 0 };
224 CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 1);
225 int expected_code_indexs[] = { 1, 2, 3, 4, 5 };
226 CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 5);
227 int expected_heap_indexs[] = { 6, 7 };
228 CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 2);
229 int expected_int32_indexs[1];
230 CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 0);
231 }
232
233
234 TEST(ConstantPoolIteratorExtended) {
235 LocalContext context;
236 Isolate* isolate = CcTest::i_isolate();
237 Factory* factory = isolate->factory();
238 v8::HandleScope scope(context->GetIsolate());
239
240 ConstantPoolArray::NumberOfEntries small(1, 0, 0, 4);
241 ConstantPoolArray::NumberOfEntries extended(5, 0, 3, 0);
242 Handle<ConstantPoolArray> array =
243 factory->NewExtendedConstantPoolArray(small, extended);
244
245 int expected_int64_indexs[] = { 0, 5, 6, 7, 8, 9 };
246 CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 6);
247 int expected_code_indexs[1];
248 CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 0);
249 int expected_heap_indexs[] = { 10, 11, 12 };
250 CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 3);
251 int expected_int32_indexs[] = { 1, 2, 3, 4 };
252 CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 4);
253 }
254
255
256 TEST(ConstantPoolPreciseGC) {
257 LocalContext context;
258 Isolate* isolate = CcTest::i_isolate();
259 Heap* heap = isolate->heap();
260 Factory* factory = isolate->factory();
261 v8::HandleScope scope(context->GetIsolate());
262
263 ConstantPoolArray::NumberOfEntries small(1, 0, 0, 1);
264 Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
265
266 // Check that the store buffer knows which entries are pointers and which are
267 // not. To do this, make non-pointer entries which look like new space
268 // pointers but are actually invalid and ensure the GC doesn't try to move
269 // them.
270 Handle<HeapObject> object = factory->NewHeapNumber(4.0);
271 Object* raw_ptr = *object;
272 // If interpreted as a pointer, this should be right inside the heap number
273 // which will cause a crash when trying to lookup the 'map' pointer.
274 intptr_t invalid_ptr = reinterpret_cast<intptr_t>(raw_ptr) + kInt32Size;
275 int32_t invalid_ptr_int32 = static_cast<int32_t>(invalid_ptr);
276 int64_t invalid_ptr_int64 = static_cast<int64_t>(invalid_ptr);
277 array->set(0, invalid_ptr_int64);
278 array->set(1, invalid_ptr_int32);
279
280 // Ensure we perform a scan on scavenge for the constant pool's page.
281 MemoryChunk::FromAddress(array->address())->set_scan_on_scavenge(true);
282 heap->CollectGarbage(NEW_SPACE);
283
284 // Check the object was moved by GC.
285 CHECK_NE(*object, raw_ptr);
286
287 // Check the non-pointer entries weren't changed.
288 CHECK_EQ(invalid_ptr_int64, array->get_int64_entry(0));
289 CHECK_EQ(invalid_ptr_int32, array->get_int32_entry(1));
290 }
291
292
293 TEST(ConstantPoolCompacting) {
294 if (i::FLAG_never_compact) return;
295 i::FLAG_always_compact = true;
296 LocalContext context;
297 Isolate* isolate = CcTest::i_isolate();
298 Heap* heap = isolate->heap();
299 Factory* factory = isolate->factory();
300 v8::HandleScope scope(context->GetIsolate());
301
302 ConstantPoolArray::NumberOfEntries small(0, 0, 1, 0);
303 ConstantPoolArray::NumberOfEntries extended(0, 0, 1, 0);
304 Handle<ConstantPoolArray> array =
305 factory->NewExtendedConstantPoolArray(small, extended);
306
307 // Start a second old-space page so that the heap pointer added to the
308 // constant pool array ends up on the an evacuation candidate page.
309 Page* first_page = heap->old_space()->anchor()->next_page();
310 {
311 HandleScope scope(isolate);
312 int dummy_array_size = Page::kMaxRegularHeapObjectSize - 92 * KB;
313 Handle<HeapObject> temp =
314 factory->NewFixedDoubleArray(dummy_array_size / kDoubleSize, TENURED);
315 CHECK(heap->InOldSpace(temp->address()));
316 Handle<HeapObject> heap_ptr =
317 factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
318 CHECK(heap->InOldSpace(heap_ptr->address()));
319 CHECK(!first_page->Contains(heap_ptr->address()));
320 array->set(0, *heap_ptr);
321 array->set(1, *heap_ptr);
322 }
323
324 // Check heap pointers are correctly updated on GC.
325 Object* old_ptr = array->get_heap_ptr_entry(0);
326 Handle<Object> object(old_ptr, isolate);
327 CHECK_EQ(old_ptr, *object);
328 CHECK_EQ(old_ptr, array->get_heap_ptr_entry(1));
329
330 // Force compacting garbage collection.
331 CHECK(FLAG_always_compact);
332 heap->CollectAllGarbage();
333
334 CHECK_NE(old_ptr, *object);
335 CHECK_EQ(*object, array->get_heap_ptr_entry(0));
336 CHECK_EQ(*object, array->get_heap_ptr_entry(1));
337 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698