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

Side by Side Diff: test/cctest/test-unboxed-doubles.cc

Issue 391693002: In-object double fields unboxing (for 64-bit only). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Toon's comments Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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 #include <stdlib.h>
6 #include <utility>
7
8 #include "src/v8.h"
9
10 #include "src/compilation-cache.h"
11 #include "src/execution.h"
12 #include "src/factory.h"
13 #include "src/global-handles.h"
14 #include "src/ic/ic.h"
15 #include "src/macro-assembler.h"
16 #include "test/cctest/cctest.h"
17
18 using namespace v8::base;
19 using namespace v8::internal;
20
21 #if (V8_DOUBLE_FIELDS_UNBOXING)
22
23
24 namespace v8 {
25 namespace internal {
26
27 class TestAccessor {
28 public:
29 static inline LayoutDescriptor* LayoutDescriptor_SetTagged(
30 LayoutDescriptor* layout_descriptor, int field_index, bool tagged) {
31 return layout_descriptor->SetTagged(field_index, tagged);
32 }
33
34 static inline int LayoutDescriptor_capacity(
35 LayoutDescriptor* layout_descriptor) {
36 return layout_descriptor->capacity();
37 }
38
39 static inline Handle<Map> Map_CopyInstallDescriptors(
40 Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
41 Handle<LayoutDescriptor> full_layout_descriptor) {
42 return Map::CopyInstallDescriptors(map, new_descriptor, descriptors,
43 full_layout_descriptor);
44 }
45 };
46 }
47 } // namespace v8::internal
48
49
50 enum PropertyKind {
51 PROP_CONSTANT,
52 PROP_SMI,
53 PROP_DOUBLE,
54 PROP_TAGGED,
55 PROP_KIND_NUMBER,
56 };
57
58 static Representation representations[PROP_KIND_NUMBER] = {
59 Representation::None(), Representation::Smi(), Representation::Double(),
60 Representation::Tagged()};
61
62
63 static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate,
64 PropertyKind* props,
65 int kPropsCount) {
66 Factory* factory = isolate->factory();
67
68 Handle<String> func_name = factory->InternalizeUtf8String("func");
69 Handle<JSFunction> func = factory->NewFunction(func_name);
70
71 Handle<DescriptorArray> descriptors =
72 DescriptorArray::Allocate(isolate, 0, kPropsCount);
73
74 int next_field_offset = 0;
75 for (int i = 0; i < kPropsCount; i++) {
76 EmbeddedVector<char, 64> buffer;
77 SNPrintF(buffer, "prop%d", i);
78 Handle<String> name = factory->InternalizeUtf8String(buffer.start());
79
80 PropertyKind kind = props[i];
81
82 if (kind == PROP_CONSTANT) {
83 ConstantDescriptor d(name, func, NONE);
84 descriptors->Append(&d);
85
86 } else {
87 FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
88 next_field_offset += f.GetDetails().field_width_in_words();
89 descriptors->Append(&f);
90 }
91 }
92 return descriptors;
93 }
94
95
96 TEST(LayoutDescriptorBasicFast) {
97 CcTest::InitializeVM();
98 v8::HandleScope scope(CcTest::isolate());
99
100 LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
101
102 CHECK(!layout_desc->IsSlowLayout());
103 CHECK(layout_desc->IsFastPointerLayout());
104 CHECK_EQ(kSmiValueSize, TestAccessor::LayoutDescriptor_capacity(layout_desc));
105
106 for (int i = 0; i < kSmiValueSize + 13; i++) {
107 CHECK_EQ(true, layout_desc->IsTagged(i));
108 }
109 CHECK_EQ(true, layout_desc->IsTagged(-1));
110 CHECK_EQ(true, layout_desc->IsTagged(-12347));
111 CHECK_EQ(true, layout_desc->IsTagged(15635));
112 CHECK(layout_desc->IsFastPointerLayout());
113
114 for (int i = 0; i < kSmiValueSize; i++) {
115 layout_desc =
116 TestAccessor::LayoutDescriptor_SetTagged(layout_desc, i, false);
117 CHECK_EQ(false, layout_desc->IsTagged(i));
118 layout_desc =
119 TestAccessor::LayoutDescriptor_SetTagged(layout_desc, i, true);
120 CHECK_EQ(true, layout_desc->IsTagged(i));
121 }
122 CHECK(layout_desc->IsFastPointerLayout());
123 }
124
125
126 TEST(LayoutDescriptorBasicSlow) {
127 CcTest::InitializeVM();
128 Isolate* isolate = CcTest::i_isolate();
129 v8::HandleScope scope(CcTest::isolate());
130
131 Handle<LayoutDescriptor> layout_descriptor;
132 const int kPropsCount = kSmiValueSize * 3;
133 PropertyKind props[kPropsCount];
134 for (int i = 0; i < kPropsCount; i++) {
135 // All properties tagged.
136 props[i] = PROP_TAGGED;
137 }
138
139 {
140 Handle<DescriptorArray> descriptors =
141 CreateDescriptorArray(isolate, props, kPropsCount);
142
143 Handle<Map> map = Map::Create(isolate, kPropsCount);
144
145 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
146 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
147 CHECK_EQ(kSmiValueSize,
148 TestAccessor::LayoutDescriptor_capacity(*layout_descriptor));
149 map->InitializeDescriptors(*descriptors, *layout_descriptor);
150 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
151 }
152
153 props[0] = PROP_DOUBLE;
154 props[kPropsCount - 1] = PROP_DOUBLE;
155
156 Handle<DescriptorArray> descriptors =
157 CreateDescriptorArray(isolate, props, kPropsCount);
158
159 {
160 int inobject_properties = kPropsCount - 1;
161 Handle<Map> map = Map::Create(isolate, inobject_properties);
162
163 // Should be fast as the only double property is the first one.
164 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
165 CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
166 CHECK(!layout_descriptor->IsSlowLayout());
167 CHECK(!layout_descriptor->IsFastPointerLayout());
168
169 CHECK_EQ(false, layout_descriptor->IsTagged(0));
170 for (int i = 1; i < kPropsCount; i++) {
171 CHECK_EQ(true, layout_descriptor->IsTagged(i));
172 }
173 map->InitializeDescriptors(*descriptors, *layout_descriptor);
174 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
175 }
176
177 {
178 int inobject_properties = kPropsCount;
179 Handle<Map> map = Map::Create(isolate, inobject_properties);
180
181 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
182 CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
183 CHECK(layout_descriptor->IsSlowLayout());
184 CHECK(!layout_descriptor->IsFastPointerLayout());
185 CHECK(TestAccessor::LayoutDescriptor_capacity(*layout_descriptor) >
186 kSmiValueSize);
187
188 CHECK_EQ(false, layout_descriptor->IsTagged(0));
189 CHECK_EQ(false, layout_descriptor->IsTagged(kPropsCount - 1));
190 for (int i = 1; i < kPropsCount - 1; i++) {
191 CHECK_EQ(true, layout_descriptor->IsTagged(i));
192 }
193
194 map->InitializeDescriptors(*descriptors, *layout_descriptor);
195 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
196
197 // Here we have truly slow layout descriptor, so play with the bits.
198 CHECK_EQ(true, layout_descriptor->IsTagged(-1));
199 CHECK_EQ(true, layout_descriptor->IsTagged(-12347));
200 CHECK_EQ(true, layout_descriptor->IsTagged(15635));
201
202 LayoutDescriptor* layout_desc = *layout_descriptor;
203 // Play with the bits but leave it in consistent state with map at the end.
204 for (int i = 1; i < kPropsCount - 1; i++) {
205 layout_desc =
206 TestAccessor::LayoutDescriptor_SetTagged(layout_desc, i, false);
207 CHECK_EQ(false, layout_desc->IsTagged(i));
208 layout_desc =
209 TestAccessor::LayoutDescriptor_SetTagged(layout_desc, i, true);
210 CHECK_EQ(true, layout_desc->IsTagged(i));
211 }
212 CHECK(layout_desc->IsSlowLayout());
213 CHECK(!layout_desc->IsFastPointerLayout());
214
215 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
216 }
217 }
218
219
220 TEST(LayoutDescriptorCreateNewFast) {
221 CcTest::InitializeVM();
222 Isolate* isolate = CcTest::i_isolate();
223 v8::HandleScope scope(CcTest::isolate());
224
225 Handle<LayoutDescriptor> layout_descriptor;
226 PropertyKind props[] = {
227 PROP_CONSTANT,
228 PROP_TAGGED, // field #0
229 PROP_CONSTANT,
230 PROP_DOUBLE, // field #1
231 PROP_CONSTANT,
232 PROP_TAGGED, // field #2
233 PROP_CONSTANT,
234 };
235 const int kPropsCount = arraysize(props);
236
237 Handle<DescriptorArray> descriptors =
238 CreateDescriptorArray(isolate, props, kPropsCount);
239
240 {
241 Handle<Map> map = Map::Create(isolate, 0);
242 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
243 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
244 map->InitializeDescriptors(*descriptors, *layout_descriptor);
245 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
246 }
247
248 {
249 Handle<Map> map = Map::Create(isolate, 1);
250 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
251 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
252 map->InitializeDescriptors(*descriptors, *layout_descriptor);
253 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
254 }
255
256 {
257 Handle<Map> map = Map::Create(isolate, 2);
258 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
259 CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
260 CHECK(!layout_descriptor->IsSlowLayout());
261 CHECK_EQ(true, layout_descriptor->IsTagged(0));
262 CHECK_EQ(false, layout_descriptor->IsTagged(1));
263 CHECK_EQ(true, layout_descriptor->IsTagged(2));
264 CHECK_EQ(true, layout_descriptor->IsTagged(125));
265 map->InitializeDescriptors(*descriptors, *layout_descriptor);
266 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
267 }
268 }
269
270
271 TEST(LayoutDescriptorCreateNewSlow) {
272 CcTest::InitializeVM();
273 Isolate* isolate = CcTest::i_isolate();
274 v8::HandleScope scope(CcTest::isolate());
275
276 Handle<LayoutDescriptor> layout_descriptor;
277 const int kPropsCount = kSmiValueSize * 3;
278 PropertyKind props[kPropsCount];
279 for (int i = 0; i < kPropsCount; i++) {
280 props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
281 }
282
283 Handle<DescriptorArray> descriptors =
284 CreateDescriptorArray(isolate, props, kPropsCount);
285
286 {
287 Handle<Map> map = Map::Create(isolate, 0);
288 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
289 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
290 map->InitializeDescriptors(*descriptors, *layout_descriptor);
291 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
292 }
293
294 {
295 Handle<Map> map = Map::Create(isolate, 1);
296 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
297 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
298 map->InitializeDescriptors(*descriptors, *layout_descriptor);
299 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
300 }
301
302 {
303 Handle<Map> map = Map::Create(isolate, 2);
304 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
305 CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
306 CHECK(!layout_descriptor->IsSlowLayout());
307 CHECK_EQ(true, layout_descriptor->IsTagged(0));
308 CHECK_EQ(false, layout_descriptor->IsTagged(1));
309 CHECK_EQ(true, layout_descriptor->IsTagged(2));
310 CHECK_EQ(true, layout_descriptor->IsTagged(125));
311 map->InitializeDescriptors(*descriptors, *layout_descriptor);
312 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
313 }
314
315 {
316 int inobject_properties = kPropsCount / 2;
317 Handle<Map> map = Map::Create(isolate, inobject_properties);
318 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
319 CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
320 CHECK(layout_descriptor->IsSlowLayout());
321 for (int i = 0; i < inobject_properties; i++) {
322 // PROP_DOUBLE has index 1 among FIELD properties.
323 const bool tagged = (i % (PROP_KIND_NUMBER - 1)) != 1;
324 CHECK_EQ(tagged, layout_descriptor->IsTagged(i));
325 }
326 // Every property after inobject_properties must be tagged.
327 for (int i = inobject_properties; i < kPropsCount; i++) {
328 CHECK_EQ(true, layout_descriptor->IsTagged(i));
329 }
330 map->InitializeDescriptors(*descriptors, *layout_descriptor);
331 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
332
333 // Now test LayoutDescriptor::cast_gc_safe().
334 Handle<LayoutDescriptor> layout_descriptor_copy =
335 LayoutDescriptor::New(map, descriptors, kPropsCount);
336
337 LayoutDescriptor* layout_desc = *layout_descriptor;
338 CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
339 CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
340 CHECK(layout_descriptor->IsFixedTypedArrayBase());
341 // Now make it look like a forwarding pointer to layout_descriptor_copy.
342 MapWord map_word = layout_desc->map_word();
343 CHECK(!map_word.IsForwardingAddress());
344 layout_desc->set_map_word(
345 MapWord::FromForwardingAddress(*layout_descriptor_copy));
346 CHECK(layout_desc->map_word().IsForwardingAddress());
347 CHECK_EQ(*layout_descriptor_copy,
348 LayoutDescriptor::cast_gc_safe(layout_desc));
349
350 // Restore it back.
351 layout_desc->set_map_word(map_word);
352 CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
353 }
354 }
355
356
357 static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
358 Isolate* isolate, int inobject_properties, PropertyKind* props,
359 int kPropsCount) {
360 Factory* factory = isolate->factory();
361
362 Handle<String> func_name = factory->InternalizeUtf8String("func");
363 Handle<JSFunction> func = factory->NewFunction(func_name);
364
365 Handle<DescriptorArray> descriptors =
366 DescriptorArray::Allocate(isolate, 0, kPropsCount);
367
368 Handle<Map> map = Map::Create(isolate, inobject_properties);
369 map->InitializeDescriptors(*descriptors,
370 LayoutDescriptor::FastPointerLayout());
371
372 int next_field_offset = 0;
373 for (int i = 0; i < kPropsCount; i++) {
374 EmbeddedVector<char, 64> buffer;
375 SNPrintF(buffer, "prop%d", i);
376 Handle<String> name = factory->InternalizeUtf8String(buffer.start());
377
378 Handle<LayoutDescriptor> layout_descriptor;
379 PropertyKind kind = props[i];
380 if (kind == PROP_CONSTANT) {
381 ConstantDescriptor d(name, func, NONE);
382 layout_descriptor = LayoutDescriptor::Append(map, d.GetDetails());
383 descriptors->Append(&d);
384
385 } else {
386 FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
387 int field_width_in_words = f.GetDetails().field_width_in_words();
388 next_field_offset += field_width_in_words;
389 layout_descriptor = LayoutDescriptor::Append(map, f.GetDetails());
390 descriptors->Append(&f);
391
392 int field_index = f.GetDetails().field_index();
393 bool is_inobject = field_index < map->inobject_properties();
394 for (int bit = 0; bit < field_width_in_words; bit++) {
395 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
396 !layout_descriptor->IsTagged(field_index + bit));
397 }
398 CHECK(layout_descriptor->IsTagged(next_field_offset));
399 }
400 map->InitializeDescriptors(*descriptors, *layout_descriptor);
401 }
402 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate);
403 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
404 return layout_descriptor;
405 }
406
407
408 TEST(LayoutDescriptorAppend) {
409 CcTest::InitializeVM();
410 Isolate* isolate = CcTest::i_isolate();
411 v8::HandleScope scope(CcTest::isolate());
412
413 Handle<LayoutDescriptor> layout_descriptor;
414 const int kPropsCount = kSmiValueSize * 3;
415 PropertyKind props[kPropsCount];
416 for (int i = 0; i < kPropsCount; i++) {
417 props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
418 }
419
420 layout_descriptor =
421 TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
422 CHECK(!layout_descriptor->IsSlowLayout());
423
424 layout_descriptor =
425 TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
426 CHECK(!layout_descriptor->IsSlowLayout());
427
428 layout_descriptor =
429 TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
430 CHECK(!layout_descriptor->IsSlowLayout());
431
432 layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
433 props, kPropsCount);
434 CHECK(layout_descriptor->IsSlowLayout());
435
436 layout_descriptor =
437 TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
438 CHECK(layout_descriptor->IsSlowLayout());
439 }
440
441
442 TEST(LayoutDescriptorAppendAllDoubles) {
443 CcTest::InitializeVM();
444 Isolate* isolate = CcTest::i_isolate();
445 v8::HandleScope scope(CcTest::isolate());
446
447 Handle<LayoutDescriptor> layout_descriptor;
448 const int kPropsCount = kSmiValueSize * 3;
449 PropertyKind props[kPropsCount];
450 for (int i = 0; i < kPropsCount; i++) {
451 props[i] = PROP_DOUBLE;
452 }
453
454 layout_descriptor =
455 TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
456 CHECK(!layout_descriptor->IsSlowLayout());
457
458 layout_descriptor =
459 TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
460 CHECK(!layout_descriptor->IsSlowLayout());
461
462 layout_descriptor =
463 TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
464 CHECK(!layout_descriptor->IsSlowLayout());
465
466 layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize + 1,
467 props, kPropsCount);
468 CHECK(layout_descriptor->IsSlowLayout());
469
470 layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
471 props, kPropsCount);
472 CHECK(layout_descriptor->IsSlowLayout());
473
474 layout_descriptor =
475 TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
476 CHECK(layout_descriptor->IsSlowLayout());
477
478 {
479 // Ensure layout descriptor switches into slow mode at the right moment.
480 layout_descriptor =
481 TestLayoutDescriptorAppend(isolate, kPropsCount, props, kSmiValueSize);
482 CHECK(!layout_descriptor->IsSlowLayout());
483
484 layout_descriptor = TestLayoutDescriptorAppend(isolate, kPropsCount, props,
485 kSmiValueSize + 1);
486 CHECK(layout_descriptor->IsSlowLayout());
487 }
488 }
489
490
491 static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
492 Isolate* isolate, int inobject_properties,
493 Handle<DescriptorArray> descriptors, int number_of_descriptors) {
494 Handle<Map> map = Map::Create(isolate, inobject_properties);
495
496 Handle<LayoutDescriptor> full_layout_descriptor = LayoutDescriptor::New(
497 map, descriptors, descriptors->number_of_descriptors());
498
499 int nof = 0;
500 bool switched_to_slow_mode = false;
501
502 for (int i = 0; i < number_of_descriptors; i++) {
503 PropertyDetails details = descriptors->GetDetails(i);
504
505 // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally
506 // and does all the required map-descriptors related book keeping.
507 map = TestAccessor::Map_CopyInstallDescriptors(map, i, descriptors,
508 full_layout_descriptor);
509
510 LayoutDescriptor* layout_desc = map->layout_descriptor();
511
512 if (layout_desc->IsSlowLayout()) {
513 switched_to_slow_mode = true;
514 CHECK_EQ(*full_layout_descriptor, layout_desc);
515 } else {
516 CHECK(!switched_to_slow_mode);
517 if (details.type() == FIELD) {
518 nof++;
519 int field_index = details.field_index();
520 int field_width_in_words = details.field_width_in_words();
521
522 bool is_inobject = field_index < map->inobject_properties();
523 for (int bit = 0; bit < field_width_in_words; bit++) {
524 CHECK_EQ(is_inobject && details.representation().IsDouble(),
525 !layout_desc->IsTagged(field_index + bit));
526 }
527 CHECK(layout_desc->IsTagged(field_index + field_width_in_words));
528 }
529 }
530 DCHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
531 }
532
533 Handle<LayoutDescriptor> layout_descriptor = map->GetLayoutDescriptor();
534 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
535 return layout_descriptor;
536 }
537
538
539 TEST(LayoutDescriptorAppendIfFastOrUseFull) {
540 CcTest::InitializeVM();
541 Isolate* isolate = CcTest::i_isolate();
542 v8::HandleScope scope(CcTest::isolate());
543
544 Handle<LayoutDescriptor> layout_descriptor;
545 const int kPropsCount = kSmiValueSize * 3;
546 PropertyKind props[kPropsCount];
547 for (int i = 0; i < kPropsCount; i++) {
548 props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
549 }
550 Handle<DescriptorArray> descriptors =
551 CreateDescriptorArray(isolate, props, kPropsCount);
552
553 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
554 isolate, 0, descriptors, kPropsCount);
555 CHECK(!layout_descriptor->IsSlowLayout());
556
557 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
558 isolate, 13, descriptors, kPropsCount);
559 CHECK(!layout_descriptor->IsSlowLayout());
560
561 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
562 isolate, kSmiValueSize, descriptors, kPropsCount);
563 CHECK(!layout_descriptor->IsSlowLayout());
564
565 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
566 isolate, kSmiValueSize * 2, descriptors, kPropsCount);
567 CHECK(layout_descriptor->IsSlowLayout());
568
569 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
570 isolate, kPropsCount, descriptors, kPropsCount);
571 CHECK(layout_descriptor->IsSlowLayout());
572 }
573
574
575 TEST(LayoutDescriptorAppendIfFastOrUseFullAllDoubles) {
576 CcTest::InitializeVM();
577 Isolate* isolate = CcTest::i_isolate();
578 v8::HandleScope scope(CcTest::isolate());
579
580 Handle<LayoutDescriptor> layout_descriptor;
581 const int kPropsCount = kSmiValueSize * 3;
582 PropertyKind props[kPropsCount];
583 for (int i = 0; i < kPropsCount; i++) {
584 props[i] = PROP_DOUBLE;
585 }
586 Handle<DescriptorArray> descriptors =
587 CreateDescriptorArray(isolate, props, kPropsCount);
588
589 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
590 isolate, 0, descriptors, kPropsCount);
591 CHECK(!layout_descriptor->IsSlowLayout());
592
593 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
594 isolate, 13, descriptors, kPropsCount);
595 CHECK(!layout_descriptor->IsSlowLayout());
596
597 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
598 isolate, kSmiValueSize, descriptors, kPropsCount);
599 CHECK(!layout_descriptor->IsSlowLayout());
600
601 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
602 isolate, kSmiValueSize + 1, descriptors, kPropsCount);
603 CHECK(layout_descriptor->IsSlowLayout());
604
605 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
606 isolate, kSmiValueSize * 2, descriptors, kPropsCount);
607 CHECK(layout_descriptor->IsSlowLayout());
608
609 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
610 isolate, kPropsCount, descriptors, kPropsCount);
611 CHECK(layout_descriptor->IsSlowLayout());
612
613 {
614 // Ensure layout descriptor switches into slow mode at the right moment.
615 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
616 isolate, kPropsCount, descriptors, kSmiValueSize);
617 CHECK(!layout_descriptor->IsSlowLayout());
618
619 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
620 isolate, kPropsCount, descriptors, kSmiValueSize + 1);
621 CHECK(layout_descriptor->IsSlowLayout());
622 }
623 }
624
625
626 TEST(StoreBufferScanOnScavenge) {
627 CcTest::InitializeVM();
628 Isolate* isolate = CcTest::i_isolate();
629 Factory* factory = isolate->factory();
630 v8::HandleScope scope(CcTest::isolate());
631
632 CompileRun(
633 "function A() {"
634 " this.x = 42.5;"
635 " this.o = {};"
636 "};"
637 "var o = new A();");
638
639 Handle<String> obj_name = factory->InternalizeUtf8String("o");
640
641 Handle<Object> obj_value =
642 Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked();
643 CHECK(obj_value->IsJSObject());
644 Handle<JSObject> obj = Handle<JSObject>::cast(obj_value);
645
646 {
647 // Ensure the object is properly set up.
648 Map* map = obj->map();
649 DescriptorArray* descriptors = map->instance_descriptors();
650 CHECK(map->NumberOfOwnDescriptors() == 2);
651 CHECK(descriptors->GetDetails(0).representation().IsDouble());
652 CHECK(descriptors->GetDetails(1).representation().IsHeapObject());
653 FieldIndex field_index = FieldIndex::ForDescriptor(map, 0);
654 CHECK(field_index.is_inobject() && field_index.is_double());
655 CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
656 if (FLAG_unbox_double_fields) {
657 CHECK_EQ(42.5, obj->RawFastDoublePropertyAt(field_index));
658 }
659 }
660 CHECK(isolate->heap()->new_space()->Contains(*obj));
661
662 // Trigger GCs so that the newly allocated object moves to old gen.
663 SimulateFullSpace(CcTest::heap()->old_pointer_space());
Hannes Payer (out of office) 2014/11/06 12:29:46 You don't need the SimulateFullSpace call.
Igor Sheludko 2014/11/07 08:03:53 Done.
664 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
665 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
666
667 CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
668
669 // Create temp object in the new space.
670 Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
671 CHECK(isolate->heap()->new_space()->Contains(*temp));
672
673 // Construct a double value that looks like a pointer to the new space object
674 // and store it into the obj.
675 Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize;
676 double boom_value = bit_cast<double>(fake_object);
677
678 FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
679 obj->FastPropertyAtPut(field_index,
680 *factory->NewHeapNumber(boom_value, MUTABLE));
681
682 // Enforce scan on scavenge for the obj's page.
683 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
684 chunk->set_scan_on_scavenge(true);
685
686 // Trigger GCs and force evacuation. Should not crash there.
687 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
Hannes Payer (out of office) 2014/11/06 12:29:46 Please verify here that boom_value is still boom_v
Igor Sheludko 2014/11/07 08:03:53 Good point! Done.
688 }
689
690 #endif
OLDNEW
« test/cctest/test-heap.cc ('K') | « test/cctest/test-heap.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698