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

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
« src/layout-descriptor.cc ('K') | « 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 PropertyKind { 37 enum PropertyKind {
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 PropertyKind props[] = { 448 PropertyKind props[] = {
206 PROP_CONSTANT, 449 PROP_CONSTANT,
207 PROP_TAGGED, // field #0 450 PROP_TAGGED, // field #0
208 PROP_CONSTANT, 451 PROP_CONSTANT,
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 isolate, kPropsCount, descriptors, kSmiValueSize); 839 isolate, kPropsCount, descriptors, kSmiValueSize);
597 CHECK(!layout_descriptor->IsSlowLayout()); 840 CHECK(!layout_descriptor->IsSlowLayout());
598 841
599 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull( 842 layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
600 isolate, kPropsCount, descriptors, kSmiValueSize + 1); 843 isolate, kPropsCount, descriptors, kSmiValueSize + 1);
601 CHECK(layout_descriptor->IsSlowLayout()); 844 CHECK(layout_descriptor->IsSlowLayout());
602 } 845 }
603 } 846 }
604 847
605 848
849 static void TestLayoutDescriptorHelper(Isolate* isolate,
850 int inobject_properties,
851 Handle<DescriptorArray> descriptors,
852 int number_of_descriptors) {
853 Handle<Map> map = Map::Create(isolate, inobject_properties);
854
855 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
856 map, descriptors, descriptors->number_of_descriptors());
857 map->InitializeDescriptors(*descriptors, *layout_descriptor);
858 DCHECK(layout_descriptor->IsConsistentWithMap(*map));
859
860 LayoutDescriptorHelper helper(*map);
861 bool all_fields_tagged = true;
862
863 int instance_size = map->instance_size();
864
865 int end_offset = instance_size * 2;
866 int first_non_tagged_field_offset = end_offset;
867 for (int i = 0; i < number_of_descriptors; i++) {
868 PropertyDetails details = descriptors->GetDetails(i);
869 if (details.type() != FIELD) continue;
870 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
871 if (!index.is_inobject()) continue;
872 all_fields_tagged &= !details.representation().IsDouble();
873 bool expected_tagged = !index.is_double();
874 if (!expected_tagged) {
875 first_non_tagged_field_offset =
876 Min(first_non_tagged_field_offset, index.offset());
877 }
878
879 int end_of_region_offset;
880 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
881 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset(), instance_size,
882 &end_of_region_offset));
883 CHECK(end_of_region_offset > 0);
884 CHECK(end_of_region_offset % kPointerSize == 0);
885 CHECK(end_of_region_offset <= instance_size);
886
887 for (int offset = index.offset(); offset < end_of_region_offset;
888 offset += kPointerSize) {
889 CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
890 }
891 if (end_of_region_offset < instance_size) {
892 CHECK_EQ(!expected_tagged, helper.IsTagged(end_of_region_offset));
893 } else {
894 CHECK_EQ(true, helper.IsTagged(end_of_region_offset));
895 }
896 }
897
898 for (int offset = 0; offset < JSObject::kHeaderSize; offset += kPointerSize) {
899 // Header queries
900 CHECK_EQ(true, helper.IsTagged(offset));
901 int end_of_region_offset;
902 CHECK_EQ(true, helper.IsTagged(offset, end_offset, &end_of_region_offset));
903 CHECK_EQ(first_non_tagged_field_offset, end_of_region_offset);
904
905 // Out of bounds queries
906 CHECK_EQ(true, helper.IsTagged(offset + instance_size));
907 }
908
909 CHECK_EQ(all_fields_tagged, helper.all_fields_tagged());
910 }
911
912
913 TEST(LayoutDescriptorHelperMixed) {
914 CcTest::InitializeVM();
915 Isolate* isolate = CcTest::i_isolate();
916 v8::HandleScope scope(CcTest::isolate());
917
918 Handle<LayoutDescriptor> layout_descriptor;
919 const int kPropsCount = kSmiValueSize * 3;
920 PropertyKind props[kPropsCount];
921 for (int i = 0; i < kPropsCount; i++) {
922 props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
923 }
924 Handle<DescriptorArray> descriptors =
925 CreateDescriptorArray(isolate, props, kPropsCount);
926
927 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
928
929 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
930
931 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
932
933 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
934 kPropsCount);
935
936 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
937 }
938
939
940 TEST(LayoutDescriptorHelperAllTagged) {
941 CcTest::InitializeVM();
942 Isolate* isolate = CcTest::i_isolate();
943 v8::HandleScope scope(CcTest::isolate());
944
945 Handle<LayoutDescriptor> layout_descriptor;
946 const int kPropsCount = kSmiValueSize * 3;
947 PropertyKind props[kPropsCount];
948 for (int i = 0; i < kPropsCount; i++) {
949 props[i] = PROP_TAGGED;
950 }
951 Handle<DescriptorArray> descriptors =
952 CreateDescriptorArray(isolate, props, kPropsCount);
953
954 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
955
956 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
957
958 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
959
960 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
961 kPropsCount);
962
963 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
964 }
965
966
967 TEST(LayoutDescriptorHelperAllDoubles) {
968 CcTest::InitializeVM();
969 Isolate* isolate = CcTest::i_isolate();
970 v8::HandleScope scope(CcTest::isolate());
971
972 Handle<LayoutDescriptor> layout_descriptor;
973 const int kPropsCount = kSmiValueSize * 3;
974 PropertyKind props[kPropsCount];
975 for (int i = 0; i < kPropsCount; i++) {
976 props[i] = PROP_DOUBLE;
977 }
978 Handle<DescriptorArray> descriptors =
979 CreateDescriptorArray(isolate, props, kPropsCount);
980
981 TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
982
983 TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
984
985 TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
986
987 TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
988 kPropsCount);
989
990 TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
991 }
992
993
606 TEST(StoreBufferScanOnScavenge) { 994 TEST(StoreBufferScanOnScavenge) {
607 CcTest::InitializeVM(); 995 CcTest::InitializeVM();
608 Isolate* isolate = CcTest::i_isolate(); 996 Isolate* isolate = CcTest::i_isolate();
609 Factory* factory = isolate->factory(); 997 Factory* factory = isolate->factory();
610 v8::HandleScope scope(CcTest::isolate()); 998 v8::HandleScope scope(CcTest::isolate());
611 999
612 CompileRun( 1000 CompileRun(
613 "function A() {" 1001 "function A() {"
614 " this.x = 42.5;" 1002 " this.x = 42.5;"
615 " this.o = {};" 1003 " this.o = {};"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 1048 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
661 chunk->set_scan_on_scavenge(true); 1049 chunk->set_scan_on_scavenge(true);
662 1050
663 // Trigger GCs and force evacuation. Should not crash there. 1051 // Trigger GCs and force evacuation. Should not crash there.
664 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 1052 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
665 1053
666 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); 1054 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
667 } 1055 }
668 1056
669 #endif 1057 #endif
OLDNEW
« src/layout-descriptor.cc ('K') | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698