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

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