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

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

Issue 726713003: LayoutDescriptorHelper is now able to calculate the length of contiguous regions of tagged/non-tagg… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 6 years 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
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <utility> 6 #include <utility>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 13 matching lines...) Expand all
24 static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) { 24 static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) {
25 if (obj->IsUnboxedDoubleField(field_index)) { 25 if (obj->IsUnboxedDoubleField(field_index)) {
26 return obj->RawFastDoublePropertyAt(field_index); 26 return obj->RawFastDoublePropertyAt(field_index);
27 } else { 27 } else {
28 Object* value = obj->RawFastPropertyAt(field_index); 28 Object* value = obj->RawFastPropertyAt(field_index);
29 DCHECK(value->IsMutableHeapNumber()); 29 DCHECK(value->IsMutableHeapNumber());
30 return HeapNumber::cast(value)->value(); 30 return HeapNumber::cast(value)->value();
31 } 31 }
32 } 32 }
33 33
34 const int kNumberOfBits = 32;
35
34 36
35 enum TestPropertyKind { 37 enum TestPropertyKind {
36 PROP_CONSTANT, 38 PROP_CONSTANT,
37 PROP_SMI, 39 PROP_SMI,
38 PROP_DOUBLE, 40 PROP_DOUBLE,
39 PROP_TAGGED, 41 PROP_TAGGED,
40 PROP_KIND_NUMBER 42 PROP_KIND_NUMBER
41 }; 43 };
42 44
43 static Representation representations[PROP_KIND_NUMBER] = { 45 static Representation representations[PROP_KIND_NUMBER] = {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 CHECK_EQ(true, layout_desc->IsTagged(15635)); 98 CHECK_EQ(true, layout_desc->IsTagged(15635));
97 CHECK(layout_desc->IsFastPointerLayout()); 99 CHECK(layout_desc->IsFastPointerLayout());
98 100
99 for (int i = 0; i < kSmiValueSize; i++) { 101 for (int i = 0; i < kSmiValueSize; i++) {
100 layout_desc = layout_desc->SetTaggedForTesting(i, false); 102 layout_desc = layout_desc->SetTaggedForTesting(i, false);
101 CHECK_EQ(false, layout_desc->IsTagged(i)); 103 CHECK_EQ(false, layout_desc->IsTagged(i));
102 layout_desc = layout_desc->SetTaggedForTesting(i, true); 104 layout_desc = layout_desc->SetTaggedForTesting(i, true);
103 CHECK_EQ(true, layout_desc->IsTagged(i)); 105 CHECK_EQ(true, layout_desc->IsTagged(i));
104 } 106 }
105 CHECK(layout_desc->IsFastPointerLayout()); 107 CHECK(layout_desc->IsFastPointerLayout());
108
109 int sequence_length;
110 CHECK_EQ(true, layout_desc->IsTagged(0, std::numeric_limits<int>::max(),
111 &sequence_length));
112 CHECK_EQ(std::numeric_limits<int>::max(), sequence_length);
113
114 CHECK_EQ(true, layout_desc->IsTagged(0, 7, &sequence_length));
115 CHECK_EQ(7, sequence_length);
106 } 116 }
107 117
108 118
109 TEST(LayoutDescriptorBasicSlow) { 119 TEST(LayoutDescriptorBasicSlow) {
110 CcTest::InitializeVM(); 120 CcTest::InitializeVM();
111 Isolate* isolate = CcTest::i_isolate(); 121 Isolate* isolate = CcTest::i_isolate();
112 v8::HandleScope scope(CcTest::isolate()); 122 v8::HandleScope scope(CcTest::isolate());
113 123
114 Handle<LayoutDescriptor> layout_descriptor; 124 Handle<LayoutDescriptor> layout_descriptor;
115 const int kPropsCount = kSmiValueSize * 3; 125 const int kPropsCount = kSmiValueSize * 3;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 CHECK_EQ(true, layout_desc->IsTagged(i)); 199 CHECK_EQ(true, layout_desc->IsTagged(i));
190 } 200 }
191 CHECK(layout_desc->IsSlowLayout()); 201 CHECK(layout_desc->IsSlowLayout());
192 CHECK(!layout_desc->IsFastPointerLayout()); 202 CHECK(!layout_desc->IsFastPointerLayout());
193 203
194 DCHECK(layout_descriptor->IsConsistentWithMap(*map)); 204 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
195 } 205 }
196 } 206 }
197 207
198 208
209 static void TestLayoutDescriptorQueries(int layout_descriptor_length,
210 int* bit_flip_positions,
211 int max_sequence_length) {
212 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting(
213 CcTest::i_isolate(), layout_descriptor_length);
214 layout_descriptor_length = layout_descriptor->capacity();
215 LayoutDescriptor* layout_desc = *layout_descriptor;
216
217 {
218 // Fill in the layout descriptor.
219 int cur_bit_flip_index = 0;
220 bool tagged = true;
221 for (int i = 0; i < layout_descriptor_length; i++) {
222 if (i == bit_flip_positions[cur_bit_flip_index]) {
223 tagged = !tagged;
224 ++cur_bit_flip_index;
225 CHECK(i < bit_flip_positions[cur_bit_flip_index]); // check test data
226 }
227 layout_desc = layout_desc->SetTaggedForTesting(i, tagged);
228 }
229 }
230
231 if (layout_desc->IsFastPointerLayout()) {
232 return;
233 }
234
235 {
236 // Check queries.
237 int cur_bit_flip_index = 0;
238 bool tagged = true;
239 for (int i = 0; i < layout_descriptor_length; i++) {
240 if (i == bit_flip_positions[cur_bit_flip_index]) {
241 tagged = !tagged;
242 ++cur_bit_flip_index;
243 }
244 CHECK_EQ(tagged, layout_desc->IsTagged(i));
245
246 int next_bit_flip_position = bit_flip_positions[cur_bit_flip_index];
247 int expected_sequence_length;
248 if (next_bit_flip_position < layout_desc->capacity()) {
249 expected_sequence_length = next_bit_flip_position - i;
250 } else {
251 expected_sequence_length = tagged ? std::numeric_limits<int>::max()
252 : (layout_desc->capacity() - i);
253 }
254 expected_sequence_length =
255 Min(expected_sequence_length, max_sequence_length);
256 int sequence_length;
257 CHECK_EQ(tagged,
258 layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
259 CHECK(sequence_length > 0);
260
261 CHECK_EQ(expected_sequence_length, sequence_length);
262 }
263
264 int sequence_length;
265 CHECK_EQ(true,
266 layout_desc->IsTagged(layout_descriptor_length,
267 max_sequence_length, &sequence_length));
268 CHECK_EQ(max_sequence_length, sequence_length);
269 }
270 }
271
272
273 static void TestLayoutDescriptorQueriesFast(int max_sequence_length) {
274 {
275 LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
276 int sequence_length;
277 for (int i = 0; i < kNumberOfBits; i++) {
278 CHECK_EQ(true,
279 layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
280 CHECK(sequence_length > 0);
281 CHECK_EQ(max_sequence_length, sequence_length);
282 }
283 }
284
285 {
286 int bit_flip_positions[] = {1000};
287 TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
288 max_sequence_length);
289 }
290
291 {
292 int bit_flip_positions[] = {0, 1000};
293 TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
294 max_sequence_length);
295 }
296
297 {
298 int bit_flip_positions[kNumberOfBits + 1];
299 for (int i = 0; i <= kNumberOfBits; i++) {
300 bit_flip_positions[i] = i;
301 }
302 TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
303 max_sequence_length);
304 }
305
306 {
307 int bit_flip_positions[] = {3, 7, 8, 10, 15, 21, 30, 1000};
308 TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
309 max_sequence_length);
310 }
311
312 {
313 int bit_flip_positions[] = {0, 1, 2, 3, 5, 7, 9,
314 12, 15, 18, 22, 26, 29, 1000};
315 TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
316 max_sequence_length);
317 }
318 }
319
320
321 TEST(LayoutDescriptorQueriesFastLimited7) {
322 CcTest::InitializeVM();
323 v8::HandleScope scope(CcTest::isolate());
324
325 TestLayoutDescriptorQueriesFast(7);
326 }
327
328
329 TEST(LayoutDescriptorQueriesFastLimited13) {
330 CcTest::InitializeVM();
331 v8::HandleScope scope(CcTest::isolate());
332
333 TestLayoutDescriptorQueriesFast(13);
334 }
335
336
337 TEST(LayoutDescriptorQueriesFastUnlimited) {
338 CcTest::InitializeVM();
339 v8::HandleScope scope(CcTest::isolate());
340
341 TestLayoutDescriptorQueriesFast(std::numeric_limits<int>::max());
342 }
343
344
345 static void TestLayoutDescriptorQueriesSlow(int max_sequence_length) {
346 {
347 int bit_flip_positions[] = {10000};
348 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
349 max_sequence_length);
350 }
351
352 {
353 int bit_flip_positions[] = {0, 10000};
354 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
355 max_sequence_length);
356 }
357
358 {
359 int bit_flip_positions[kMaxNumberOfDescriptors + 1];
360 for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
361 bit_flip_positions[i] = i;
362 }
363 bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
364 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
365 max_sequence_length);
366 }
367
368 {
369 int bit_flip_positions[] = {3, 7, 8, 10, 15, 21, 30,
370 37, 54, 80, 99, 383, 10000};
371 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
372 max_sequence_length);
373 }
374
375 {
376 int bit_flip_positions[] = {0, 10, 20, 30, 50, 70, 90,
377 120, 150, 180, 220, 260, 290, 10000};
378 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
379 max_sequence_length);
380 }
381
382 {
383 int bit_flip_positions[kMaxNumberOfDescriptors + 1];
384 int cur = 0;
385 for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
386 bit_flip_positions[i] = cur;
387 cur = (cur + 1) * 2;
388 }
389 CHECK(cur < 10000);
390 bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
391 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
392 max_sequence_length);
393 }
394
395 {
396 int bit_flip_positions[kMaxNumberOfDescriptors + 1];
397 int cur = 3;
398 for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
399 bit_flip_positions[i] = cur;
400 cur = (cur + 1) * 2;
401 }
402 CHECK(cur < 10000);
403 bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
404 TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
405 max_sequence_length);
406 }
407 }
408
409
410 TEST(LayoutDescriptorQueriesSlowLimited7) {
411 CcTest::InitializeVM();
412 v8::HandleScope scope(CcTest::isolate());
413
414 TestLayoutDescriptorQueriesSlow(7);
415 }
416
417
418 TEST(LayoutDescriptorQueriesSlowLimited13) {
419 CcTest::InitializeVM();
420 v8::HandleScope scope(CcTest::isolate());
421
422 TestLayoutDescriptorQueriesSlow(13);
423 }
424
425
426 TEST(LayoutDescriptorQueriesSlowLimited42) {
427 CcTest::InitializeVM();
428 v8::HandleScope scope(CcTest::isolate());
429
430 TestLayoutDescriptorQueriesSlow(42);
431 }
432
433
434 TEST(LayoutDescriptorQueriesSlowUnlimited) {
435 CcTest::InitializeVM();
436 v8::HandleScope scope(CcTest::isolate());
437
438 TestLayoutDescriptorQueriesSlow(std::numeric_limits<int>::max());
439 }
440
441
199 TEST(LayoutDescriptorCreateNewFast) { 442 TEST(LayoutDescriptorCreateNewFast) {
200 CcTest::InitializeVM(); 443 CcTest::InitializeVM();
201 Isolate* isolate = CcTest::i_isolate(); 444 Isolate* isolate = CcTest::i_isolate();
202 v8::HandleScope scope(CcTest::isolate()); 445 v8::HandleScope scope(CcTest::isolate());
203 446
204 Handle<LayoutDescriptor> layout_descriptor; 447 Handle<LayoutDescriptor> layout_descriptor;
205 TestPropertyKind props[] = { 448 TestPropertyKind props[] = {
206 PROP_CONSTANT, 449 PROP_CONSTANT,
207 PROP_TAGGED, // field #0 450 PROP_TAGGED, // field #0
208 PROP_CONSTANT, 451 PROP_CONSTANT,
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 // Now the object moves to old gen and it has a double field that looks like 944 // Now the object moves to old gen and it has a double field that looks like
702 // a pointer to a from semi-space. 945 // a pointer to a from semi-space.
703 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now 946 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
704 947
705 CHECK(isolate->heap()->old_pointer_space()->Contains(*obj)); 948 CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
706 949
707 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); 950 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
708 } 951 }
709 952
710 953
954 static void TestLayoutDescriptorHelper(Isolate* isolate,
955 int inobject_properties,
956 Handle<DescriptorArray> descriptors,
957 int number_of_descriptors) {
958 Handle<Map> map = Map::Create(isolate, inobject_properties);
959
960 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
961 map, descriptors, descriptors->number_of_descriptors());
962 map->InitializeDescriptors(*descriptors, *layout_descriptor);
963 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
964
965 LayoutDescriptorHelper helper(*map);
966 bool all_fields_tagged = true;
967
968 int instance_size = map->instance_size();
969
970 int end_offset = instance_size * 2;
971 int first_non_tagged_field_offset = end_offset;
972 for (int i = 0; i < number_of_descriptors; i++) {
973 PropertyDetails details = descriptors->GetDetails(i);
974 if (details.type() != FIELD) continue;
975 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
976 if (!index.is_inobject()) continue;
977 all_fields_tagged &= !details.representation().IsDouble();
978 bool expected_tagged = !index.is_double();
979 if (!expected_tagged) {
980 first_non_tagged_field_offset =
981 Min(first_non_tagged_field_offset, index.offset());
982 }
983
984 int end_of_region_offset;
985 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
986 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset(), instance_size,
987 &end_of_region_offset));
988 CHECK(end_of_region_offset > 0);
989 CHECK(end_of_region_offset % kPointerSize == 0);
990 CHECK(end_of_region_offset <= instance_size);
991
992 for (int offset = index.offset(); offset < end_of_region_offset;
993 offset += kPointerSize) {
994 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
995 }
996 if (end_of_region_offset < instance_size) {
997 CHECK_EQ(!expected_tagged, helper.IsTagged(end_of_region_offset));
998 } else {
999 CHECK_EQ(true, helper.IsTagged(end_of_region_offset));
1000 }
1001 }
1002
1003 for (int offset = 0; offset < JSObject::kHeaderSize; offset += kPointerSize) {
1004 // Header queries
1005 CHECK_EQ(true, helper.IsTagged(offset));
1006 int end_of_region_offset;
1007 CHECK_EQ(true, helper.IsTagged(offset, end_offset, &end_of_region_offset));
1008 CHECK_EQ(first_non_tagged_field_offset, end_of_region_offset);
1009
1010 // Out of bounds queries
1011 CHECK_EQ(true, helper.IsTagged(offset + instance_size));
1012 }
1013
1014 CHECK_EQ(all_fields_tagged, helper.all_fields_tagged());
1015 }
1016
1017
1018 TEST(LayoutDescriptorHelperMixed) {
1019 CcTest::InitializeVM();
1020 Isolate* isolate = CcTest::i_isolate();
1021 v8::HandleScope scope(CcTest::isolate());
1022
1023 Handle<LayoutDescriptor> layout_descriptor;
1024 const int kPropsCount = kSmiValueSize * 3;
1025 TestPropertyKind props[kPropsCount];
1026 for (int i = 0; i < kPropsCount; i++) {
1027 props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
1028 }
1029 Handle<DescriptorArray> descriptors =
1030 CreateDescriptorArray(isolate, props, kPropsCount);
1031
1032 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
1033
1034 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
1035
1036 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
1037
1038 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
1039 kPropsCount);
1040
1041 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
1042 }
1043
1044
1045 TEST(LayoutDescriptorHelperAllTagged) {
1046 CcTest::InitializeVM();
1047 Isolate* isolate = CcTest::i_isolate();
1048 v8::HandleScope scope(CcTest::isolate());
1049
1050 Handle<LayoutDescriptor> layout_descriptor;
1051 const int kPropsCount = kSmiValueSize * 3;
1052 TestPropertyKind props[kPropsCount];
1053 for (int i = 0; i < kPropsCount; i++) {
1054 props[i] = PROP_TAGGED;
1055 }
1056 Handle<DescriptorArray> descriptors =
1057 CreateDescriptorArray(isolate, props, kPropsCount);
1058
1059 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
1060
1061 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
1062
1063 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
1064
1065 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
1066 kPropsCount);
1067
1068 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
1069 }
1070
1071
1072 TEST(LayoutDescriptorHelperAllDoubles) {
1073 CcTest::InitializeVM();
1074 Isolate* isolate = CcTest::i_isolate();
1075 v8::HandleScope scope(CcTest::isolate());
1076
1077 Handle<LayoutDescriptor> layout_descriptor;
1078 const int kPropsCount = kSmiValueSize * 3;
1079 TestPropertyKind props[kPropsCount];
1080 for (int i = 0; i < kPropsCount; i++) {
1081 props[i] = PROP_DOUBLE;
1082 }
1083 Handle<DescriptorArray> descriptors =
1084 CreateDescriptorArray(isolate, props, kPropsCount);
1085
1086 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
1087
1088 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
1089
1090 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
1091
1092 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
1093 kPropsCount);
1094
1095 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
1096 }
1097
1098
711 TEST(StoreBufferScanOnScavenge) { 1099 TEST(StoreBufferScanOnScavenge) {
712 CcTest::InitializeVM(); 1100 CcTest::InitializeVM();
713 Isolate* isolate = CcTest::i_isolate(); 1101 Isolate* isolate = CcTest::i_isolate();
714 Factory* factory = isolate->factory(); 1102 Factory* factory = isolate->factory();
715 v8::HandleScope scope(CcTest::isolate()); 1103 v8::HandleScope scope(CcTest::isolate());
716 1104
717 CompileRun( 1105 CompileRun(
718 "function A() {" 1106 "function A() {"
719 " this.x = 42.5;" 1107 " this.x = 42.5;"
720 " this.o = {};" 1108 " this.o = {};"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 1153 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
766 chunk->set_scan_on_scavenge(true); 1154 chunk->set_scan_on_scavenge(true);
767 1155
768 // Trigger GCs and force evacuation. Should not crash there. 1156 // Trigger GCs and force evacuation. Should not crash there.
769 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 1157 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
770 1158
771 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); 1159 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
772 } 1160 }
773 1161
774 #endif 1162 #endif
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698