OLD | NEW |
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 12 matching lines...) Loading... |
23 | 23 |
24 // | 24 // |
25 // Helper functions. | 25 // Helper functions. |
26 // | 26 // |
27 | 27 |
28 | 28 |
29 static void InitializeVerifiedMapDescriptors( | 29 static void InitializeVerifiedMapDescriptors( |
30 Map* map, DescriptorArray* descriptors, | 30 Map* map, DescriptorArray* descriptors, |
31 LayoutDescriptor* layout_descriptor) { | 31 LayoutDescriptor* layout_descriptor) { |
32 map->InitializeDescriptors(descriptors, layout_descriptor); | 32 map->InitializeDescriptors(descriptors, layout_descriptor); |
33 CHECK(layout_descriptor->IsConsistentWithMap(map)); | 33 CHECK(layout_descriptor->IsConsistentWithMap(map, true)); |
34 } | 34 } |
35 | 35 |
36 | 36 |
37 static Handle<String> MakeString(const char* str) { | 37 static Handle<String> MakeString(const char* str) { |
38 Isolate* isolate = CcTest::i_isolate(); | 38 Isolate* isolate = CcTest::i_isolate(); |
39 Factory* factory = isolate->factory(); | 39 Factory* factory = isolate->factory(); |
40 return factory->InternalizeUtf8String(str); | 40 return factory->InternalizeUtf8String(str); |
41 } | 41 } |
42 | 42 |
43 | 43 |
(...skipping 179 matching lines...) Loading... |
223 LayoutDescriptor* layout_desc = *layout_descriptor; | 223 LayoutDescriptor* layout_desc = *layout_descriptor; |
224 // Play with the bits but leave it in consistent state with map at the end. | 224 // Play with the bits but leave it in consistent state with map at the end. |
225 for (int i = 1; i < kPropsCount - 1; i++) { | 225 for (int i = 1; i < kPropsCount - 1; i++) { |
226 layout_desc = layout_desc->SetTaggedForTesting(i, false); | 226 layout_desc = layout_desc->SetTaggedForTesting(i, false); |
227 CHECK_EQ(false, layout_desc->IsTagged(i)); | 227 CHECK_EQ(false, layout_desc->IsTagged(i)); |
228 layout_desc = layout_desc->SetTaggedForTesting(i, true); | 228 layout_desc = layout_desc->SetTaggedForTesting(i, true); |
229 CHECK_EQ(true, layout_desc->IsTagged(i)); | 229 CHECK_EQ(true, layout_desc->IsTagged(i)); |
230 } | 230 } |
231 CHECK(layout_desc->IsSlowLayout()); | 231 CHECK(layout_desc->IsSlowLayout()); |
232 CHECK(!layout_desc->IsFastPointerLayout()); | 232 CHECK(!layout_desc->IsFastPointerLayout()); |
233 CHECK(layout_descriptor->IsConsistentWithMap(*map)); | 233 CHECK(layout_descriptor->IsConsistentWithMap(*map, true)); |
234 } | 234 } |
235 } | 235 } |
236 | 236 |
237 | 237 |
238 static void TestLayoutDescriptorQueries(int layout_descriptor_length, | 238 static void TestLayoutDescriptorQueries(int layout_descriptor_length, |
239 int* bit_flip_positions, | 239 int* bit_flip_positions, |
240 int max_sequence_length) { | 240 int max_sequence_length) { |
241 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting( | 241 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting( |
242 CcTest::i_isolate(), layout_descriptor_length); | 242 CcTest::i_isolate(), layout_descriptor_length); |
243 layout_descriptor_length = layout_descriptor->capacity(); | 243 layout_descriptor_length = layout_descriptor->capacity(); |
(...skipping 393 matching lines...) Loading... |
637 bool is_inobject = field_index < map->inobject_properties(); | 637 bool is_inobject = field_index < map->inobject_properties(); |
638 for (int bit = 0; bit < field_width_in_words; bit++) { | 638 for (int bit = 0; bit < field_width_in_words; bit++) { |
639 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), | 639 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), |
640 !layout_descriptor->IsTagged(field_index + bit)); | 640 !layout_descriptor->IsTagged(field_index + bit)); |
641 } | 641 } |
642 CHECK(layout_descriptor->IsTagged(next_field_offset)); | 642 CHECK(layout_descriptor->IsTagged(next_field_offset)); |
643 } | 643 } |
644 map->InitializeDescriptors(*descriptors, *layout_descriptor); | 644 map->InitializeDescriptors(*descriptors, *layout_descriptor); |
645 } | 645 } |
646 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); | 646 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); |
647 CHECK(layout_descriptor->IsConsistentWithMap(*map)); | 647 CHECK(layout_descriptor->IsConsistentWithMap(*map, true)); |
648 return layout_descriptor; | 648 return layout_descriptor; |
649 } | 649 } |
650 | 650 |
651 | 651 |
652 TEST(LayoutDescriptorAppend) { | 652 TEST(LayoutDescriptorAppend) { |
653 CcTest::InitializeVM(); | 653 CcTest::InitializeVM(); |
654 Isolate* isolate = CcTest::i_isolate(); | 654 Isolate* isolate = CcTest::i_isolate(); |
655 v8::HandleScope scope(CcTest::isolate()); | 655 v8::HandleScope scope(CcTest::isolate()); |
656 | 656 |
657 Handle<LayoutDescriptor> layout_descriptor; | 657 Handle<LayoutDescriptor> layout_descriptor; |
(...skipping 248 matching lines...) Loading... |
906 Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing"); | 906 Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing"); |
907 JSObject::MigrateToMap(object, normalized_map); | 907 JSObject::MigrateToMap(object, normalized_map); |
908 CHECK(!object->HasFastProperties()); | 908 CHECK(!object->HasFastProperties()); |
909 CHECK(object->map()->HasFastPointerLayout()); | 909 CHECK(object->map()->HasFastPointerLayout()); |
910 | 910 |
911 // Trigger GCs and heap verification. | 911 // Trigger GCs and heap verification. |
912 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 912 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
913 } | 913 } |
914 | 914 |
915 | 915 |
| 916 TEST(DescriptorArrayTrimming) { |
| 917 CcTest::InitializeVM(); |
| 918 v8::HandleScope scope(CcTest::isolate()); |
| 919 Isolate* isolate = CcTest::i_isolate(); |
| 920 |
| 921 const int kPropsCount = 64; |
| 922 const int kSplitPropIndex = 34; |
| 923 const int kTrimmedPropsCount = kPropsCount - kSplitPropIndex; |
| 924 |
| 925 Handle<HeapType> any_type = HeapType::Any(isolate); |
| 926 Handle<Map> map = Map::Create(isolate, 100); |
| 927 for (int i = 0; i < kSplitPropIndex - 1; i++) { |
| 928 map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, |
| 929 Representation::Smi(), |
| 930 INSERT_TRANSITION).ToHandleChecked(); |
| 931 } |
| 932 map = Map::CopyWithField(map, MakeName("prop", kSplitPropIndex), any_type, |
| 933 NONE, Representation::Double(), |
| 934 INSERT_TRANSITION).ToHandleChecked(); |
| 935 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); |
| 936 CHECK(map->layout_descriptor()->IsSlowLayout()); |
| 937 CHECK(map->owns_descriptors()); |
| 938 |
| 939 { |
| 940 // Add transitions to double fields. |
| 941 v8::HandleScope scope(CcTest::isolate()); |
| 942 |
| 943 Handle<Map> tmp_map = map; |
| 944 for (int i = 0; i < kTrimmedPropsCount; i++) { |
| 945 tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE, |
| 946 Representation::Double(), |
| 947 INSERT_TRANSITION).ToHandleChecked(); |
| 948 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
| 949 } |
| 950 // Check that descriptors are shared. |
| 951 CHECK(tmp_map->owns_descriptors()); |
| 952 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
| 953 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); |
| 954 } |
| 955 |
| 956 // The unused tail of the layout descriptor is now "durty" because of sharing. |
| 957 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map)); |
| 958 for (int i = kSplitPropIndex; i < kPropsCount; i++) { |
| 959 CHECK(!map->layout_descriptor()->IsTagged(i)); |
| 960 } |
| 961 CHECK_LT(map->NumberOfOwnDescriptors(), |
| 962 map->instance_descriptors()->number_of_descriptors()); |
| 963 |
| 964 // Call GC that should trim both |map|'s descriptor array and layout |
| 965 // descriptor. |
| 966 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 967 |
| 968 // The unused tail of the layout descriptor is now "clean" again. |
| 969 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); |
| 970 CHECK(map->owns_descriptors()); |
| 971 CHECK_EQ(map->NumberOfOwnDescriptors(), |
| 972 map->instance_descriptors()->number_of_descriptors()); |
| 973 |
| 974 { |
| 975 // Add transitions to tagged fields. |
| 976 v8::HandleScope scope(CcTest::isolate()); |
| 977 |
| 978 Handle<Map> tmp_map = map; |
| 979 for (int i = 0; i < kTrimmedPropsCount; i++) { |
| 980 tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type, |
| 981 NONE, Representation::Tagged(), |
| 982 INSERT_TRANSITION).ToHandleChecked(); |
| 983 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
| 984 } |
| 985 // Check that descriptors are shared. |
| 986 CHECK(tmp_map->owns_descriptors()); |
| 987 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
| 988 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); |
| 989 } |
| 990 } |
| 991 |
| 992 |
916 TEST(DoScavenge) { | 993 TEST(DoScavenge) { |
917 CcTest::InitializeVM(); | 994 CcTest::InitializeVM(); |
918 v8::HandleScope scope(CcTest::isolate()); | 995 v8::HandleScope scope(CcTest::isolate()); |
919 Isolate* isolate = CcTest::i_isolate(); | 996 Isolate* isolate = CcTest::i_isolate(); |
920 Factory* factory = isolate->factory(); | 997 Factory* factory = isolate->factory(); |
921 | 998 |
922 // The plan: create |obj| with double field in new space, do scanvenge so | 999 // The plan: create |obj| with double field in new space, do scanvenge so |
923 // that |obj| is moved to old space, construct a double value that looks like | 1000 // that |obj| is moved to old space, construct a double value that looks like |
924 // a pointer to "from space" pointer. Do scavenge one more time and ensure | 1001 // a pointer to "from space" pointer. Do scavenge one more time and ensure |
925 // that it didn't crash or corrupt the double value stored in the object. | 1002 // that it didn't crash or corrupt the double value stored in the object. |
(...skipping 292 matching lines...) Loading... |
1218 Handle<String> name = MakeName("prop", i); | 1295 Handle<String> name = MakeName("prop", i); |
1219 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), | 1296 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), |
1220 INSERT_TRANSITION).ToHandleChecked(); | 1297 INSERT_TRANSITION).ToHandleChecked(); |
1221 } | 1298 } |
1222 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, | 1299 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, |
1223 Representation::Double(), | 1300 Representation::Double(), |
1224 INSERT_TRANSITION).ToHandleChecked(); | 1301 INSERT_TRANSITION).ToHandleChecked(); |
1225 } | 1302 } |
1226 Handle<LayoutDescriptor> split_layout_descriptor( | 1303 Handle<LayoutDescriptor> split_layout_descriptor( |
1227 split_map->layout_descriptor(), isolate); | 1304 split_map->layout_descriptor(), isolate); |
1228 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map)); | 1305 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true)); |
1229 CHECK(split_layout_descriptor->IsSlowLayout()); | 1306 CHECK(split_layout_descriptor->IsSlowLayout()); |
1230 CHECK(split_map->owns_descriptors()); | 1307 CHECK(split_map->owns_descriptors()); |
1231 | 1308 |
1232 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, | 1309 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, |
1233 NONE, Representation::Double(), | 1310 NONE, Representation::Double(), |
1234 INSERT_TRANSITION).ToHandleChecked(); | 1311 INSERT_TRANSITION).ToHandleChecked(); |
1235 CHECK(!split_map->owns_descriptors()); | 1312 CHECK(!split_map->owns_descriptors()); |
1236 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); | 1313 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); |
1237 | 1314 |
1238 // Layout descriptors should be shared with |split_map|. | 1315 // Layout descriptors should be shared with |split_map|. |
1239 CHECK(map1->owns_descriptors()); | 1316 CHECK(map1->owns_descriptors()); |
1240 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); | 1317 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); |
1241 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1)); | 1318 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true)); |
1242 | 1319 |
1243 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, | 1320 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, |
1244 NONE, Representation::Tagged(), | 1321 NONE, Representation::Tagged(), |
1245 INSERT_TRANSITION).ToHandleChecked(); | 1322 INSERT_TRANSITION).ToHandleChecked(); |
1246 | 1323 |
1247 // Layout descriptors should not be shared with |split_map|. | 1324 // Layout descriptors should not be shared with |split_map|. |
1248 CHECK(map2->owns_descriptors()); | 1325 CHECK(map2->owns_descriptors()); |
1249 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); | 1326 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); |
1250 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2)); | 1327 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true)); |
1251 } | 1328 } |
1252 | 1329 |
1253 | 1330 |
1254 TEST(StoreBufferScanOnScavenge) { | 1331 TEST(StoreBufferScanOnScavenge) { |
1255 CcTest::InitializeVM(); | 1332 CcTest::InitializeVM(); |
1256 Isolate* isolate = CcTest::i_isolate(); | 1333 Isolate* isolate = CcTest::i_isolate(); |
1257 Factory* factory = isolate->factory(); | 1334 Factory* factory = isolate->factory(); |
1258 v8::HandleScope scope(CcTest::isolate()); | 1335 v8::HandleScope scope(CcTest::isolate()); |
1259 | 1336 |
1260 Handle<HeapType> any_type = HeapType::Any(isolate); | 1337 Handle<HeapType> any_type = HeapType::Any(isolate); |
(...skipping 334 matching lines...) Loading... |
1595 | 1672 |
1596 // TODO(ishell): add respective tests for property kind reconfiguring from | 1673 // TODO(ishell): add respective tests for property kind reconfiguring from |
1597 // accessor field to double, once accessor fields are supported by | 1674 // accessor field to double, once accessor fields are supported by |
1598 // Map::ReconfigureProperty(). | 1675 // Map::ReconfigureProperty(). |
1599 | 1676 |
1600 | 1677 |
1601 // TODO(ishell): add respective tests for fast property removal case once | 1678 // TODO(ishell): add respective tests for fast property removal case once |
1602 // Map::ReconfigureProperty() supports that. | 1679 // Map::ReconfigureProperty() supports that. |
1603 | 1680 |
1604 #endif | 1681 #endif |
OLD | NEW |