Chromium Code Reviews

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

Issue 1033273005: Layout descriptor must be trimmed when corresponding descriptors array is trimmed to stay in sync. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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 12 matching lines...)
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...)
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...)
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...)
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...)
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...)
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
OLDNEW

Powered by Google App Engine