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/accessors.h" |
10 #include "src/compilation-cache.h" | 11 #include "src/compilation-cache.h" |
11 #include "src/execution.h" | 12 #include "src/execution.h" |
12 #include "src/factory.h" | 13 #include "src/factory.h" |
13 #include "src/field-type.h" | 14 #include "src/field-type.h" |
14 #include "src/global-handles.h" | 15 #include "src/global-handles.h" |
15 #include "src/ic/ic.h" | 16 #include "src/ic/ic.h" |
16 #include "src/macro-assembler.h" | 17 #include "src/macro-assembler.h" |
17 #include "test/cctest/cctest.h" | 18 #include "test/cctest/cctest.h" |
18 #include "test/cctest/heap/heap-utils.h" | 19 #include "test/cctest/heap/heap-utils.h" |
19 | 20 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 } | 72 } |
72 | 73 |
73 void WriteToField(JSObject* object, int descriptor, Object* value) { | 74 void WriteToField(JSObject* object, int descriptor, Object* value) { |
74 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 75 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
75 PropertyDetails details = descriptors->GetDetails(descriptor); | 76 PropertyDetails details = descriptors->GetDetails(descriptor); |
76 object->WriteToField(descriptor, details, value); | 77 object->WriteToField(descriptor, details, value); |
77 } | 78 } |
78 | 79 |
79 const int kNumberOfBits = 32; | 80 const int kNumberOfBits = 32; |
80 | 81 |
81 | |
82 enum TestPropertyKind { | 82 enum TestPropertyKind { |
83 PROP_CONSTANT, | 83 PROP_ACCESSOR_INFO, |
84 PROP_SMI, | 84 PROP_SMI, |
85 PROP_DOUBLE, | 85 PROP_DOUBLE, |
86 PROP_TAGGED, | 86 PROP_TAGGED, |
87 PROP_KIND_NUMBER | 87 PROP_KIND_NUMBER |
88 }; | 88 }; |
89 | 89 |
90 static Representation representations[PROP_KIND_NUMBER] = { | 90 static Representation representations[PROP_KIND_NUMBER] = { |
91 Representation::None(), Representation::Smi(), Representation::Double(), | 91 Representation::None(), Representation::Smi(), Representation::Double(), |
92 Representation::Tagged()}; | 92 Representation::Tagged()}; |
93 | 93 |
94 | 94 |
95 static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate, | 95 static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate, |
96 TestPropertyKind* props, | 96 TestPropertyKind* props, |
97 int kPropsCount) { | 97 int kPropsCount) { |
98 Factory* factory = isolate->factory(); | 98 Factory* factory = isolate->factory(); |
99 | 99 |
100 Handle<String> func_name = factory->InternalizeUtf8String("func"); | |
101 Handle<JSFunction> func = factory->NewFunction(func_name); | |
102 | |
103 Handle<DescriptorArray> descriptors = | 100 Handle<DescriptorArray> descriptors = |
104 DescriptorArray::Allocate(isolate, 0, kPropsCount); | 101 DescriptorArray::Allocate(isolate, 0, kPropsCount); |
105 | 102 |
106 int next_field_offset = 0; | 103 int next_field_offset = 0; |
107 for (int i = 0; i < kPropsCount; i++) { | 104 for (int i = 0; i < kPropsCount; i++) { |
108 EmbeddedVector<char, 64> buffer; | 105 EmbeddedVector<char, 64> buffer; |
109 SNPrintF(buffer, "prop%d", i); | 106 SNPrintF(buffer, "prop%d", i); |
110 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); | 107 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); |
111 | 108 |
112 TestPropertyKind kind = props[i]; | 109 TestPropertyKind kind = props[i]; |
113 | 110 |
114 if (kind == PROP_CONSTANT) { | 111 Descriptor d; |
115 Descriptor d = Descriptor::DataConstant(name, func, NONE); | 112 if (kind == PROP_ACCESSOR_INFO) { |
116 descriptors->Append(&d); | 113 Handle<AccessorInfo> info = |
| 114 Accessors::MakeAccessor(isolate, name, nullptr, nullptr, NONE); |
| 115 d = Descriptor::AccessorConstant(name, info, NONE); |
117 | 116 |
118 } else { | 117 } else { |
119 Descriptor d = Descriptor::DataField(name, next_field_offset, NONE, | 118 d = Descriptor::DataField(name, next_field_offset, NONE, |
120 representations[kind]); | 119 representations[kind]); |
121 next_field_offset += d.GetDetails().field_width_in_words(); | 120 } |
122 descriptors->Append(&d); | 121 descriptors->Append(&d); |
| 122 PropertyDetails details = d.GetDetails(); |
| 123 if (details.location() == kField) { |
| 124 next_field_offset += details.field_width_in_words(); |
123 } | 125 } |
124 } | 126 } |
125 return descriptors; | 127 return descriptors; |
126 } | 128 } |
127 | 129 |
128 | 130 |
129 TEST(LayoutDescriptorBasicFast) { | 131 TEST(LayoutDescriptorBasicFast) { |
130 CcTest::InitializeVM(); | 132 CcTest::InitializeVM(); |
131 v8::HandleScope scope(CcTest::isolate()); | 133 v8::HandleScope scope(CcTest::isolate()); |
132 | 134 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 } | 483 } |
482 | 484 |
483 | 485 |
484 TEST(LayoutDescriptorCreateNewFast) { | 486 TEST(LayoutDescriptorCreateNewFast) { |
485 CcTest::InitializeVM(); | 487 CcTest::InitializeVM(); |
486 Isolate* isolate = CcTest::i_isolate(); | 488 Isolate* isolate = CcTest::i_isolate(); |
487 v8::HandleScope scope(CcTest::isolate()); | 489 v8::HandleScope scope(CcTest::isolate()); |
488 | 490 |
489 Handle<LayoutDescriptor> layout_descriptor; | 491 Handle<LayoutDescriptor> layout_descriptor; |
490 TestPropertyKind props[] = { | 492 TestPropertyKind props[] = { |
491 PROP_CONSTANT, | 493 PROP_ACCESSOR_INFO, |
492 PROP_TAGGED, // field #0 | 494 PROP_TAGGED, // field #0 |
493 PROP_CONSTANT, | 495 PROP_ACCESSOR_INFO, |
494 PROP_DOUBLE, // field #1 | 496 PROP_DOUBLE, // field #1 |
495 PROP_CONSTANT, | 497 PROP_ACCESSOR_INFO, |
496 PROP_TAGGED, // field #2 | 498 PROP_TAGGED, // field #2 |
497 PROP_CONSTANT, | 499 PROP_ACCESSOR_INFO, |
498 }; | 500 }; |
499 const int kPropsCount = arraysize(props); | 501 const int kPropsCount = arraysize(props); |
500 | 502 |
501 Handle<DescriptorArray> descriptors = | 503 Handle<DescriptorArray> descriptors = |
502 CreateDescriptorArray(isolate, props, kPropsCount); | 504 CreateDescriptorArray(isolate, props, kPropsCount); |
503 | 505 |
504 { | 506 { |
505 Handle<Map> map = Map::Create(isolate, 0); | 507 Handle<Map> map = Map::Create(isolate, 0); |
506 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount); | 508 layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount); |
507 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor); | 509 CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc)); | 611 CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc)); |
610 } | 612 } |
611 } | 613 } |
612 | 614 |
613 | 615 |
614 static Handle<LayoutDescriptor> TestLayoutDescriptorAppend( | 616 static Handle<LayoutDescriptor> TestLayoutDescriptorAppend( |
615 Isolate* isolate, int inobject_properties, TestPropertyKind* props, | 617 Isolate* isolate, int inobject_properties, TestPropertyKind* props, |
616 int kPropsCount) { | 618 int kPropsCount) { |
617 Factory* factory = isolate->factory(); | 619 Factory* factory = isolate->factory(); |
618 | 620 |
619 Handle<String> func_name = factory->InternalizeUtf8String("func"); | |
620 Handle<JSFunction> func = factory->NewFunction(func_name); | |
621 | |
622 Handle<DescriptorArray> descriptors = | 621 Handle<DescriptorArray> descriptors = |
623 DescriptorArray::Allocate(isolate, 0, kPropsCount); | 622 DescriptorArray::Allocate(isolate, 0, kPropsCount); |
624 | 623 |
625 Handle<Map> map = Map::Create(isolate, inobject_properties); | 624 Handle<Map> map = Map::Create(isolate, inobject_properties); |
626 map->InitializeDescriptors(*descriptors, | 625 map->InitializeDescriptors(*descriptors, |
627 LayoutDescriptor::FastPointerLayout()); | 626 LayoutDescriptor::FastPointerLayout()); |
628 | 627 |
629 int next_field_offset = 0; | 628 int next_field_offset = 0; |
630 for (int i = 0; i < kPropsCount; i++) { | 629 for (int i = 0; i < kPropsCount; i++) { |
631 EmbeddedVector<char, 64> buffer; | 630 EmbeddedVector<char, 64> buffer; |
632 SNPrintF(buffer, "prop%d", i); | 631 SNPrintF(buffer, "prop%d", i); |
633 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); | 632 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); |
634 | 633 |
635 Handle<LayoutDescriptor> layout_descriptor; | 634 Handle<LayoutDescriptor> layout_descriptor; |
636 TestPropertyKind kind = props[i]; | 635 TestPropertyKind kind = props[i]; |
637 if (kind == PROP_CONSTANT) { | 636 Descriptor d; |
638 Descriptor d = Descriptor::DataConstant(name, func, NONE); | 637 if (kind == PROP_ACCESSOR_INFO) { |
639 layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails()); | 638 Handle<AccessorInfo> info = |
640 descriptors->Append(&d); | 639 Accessors::MakeAccessor(isolate, name, nullptr, nullptr, NONE); |
| 640 d = Descriptor::AccessorConstant(name, info, NONE); |
641 | 641 |
642 } else { | 642 } else { |
643 Descriptor d = Descriptor::DataField(name, next_field_offset, NONE, | 643 d = Descriptor::DataField(name, next_field_offset, NONE, |
644 representations[kind]); | 644 representations[kind]); |
645 int field_width_in_words = d.GetDetails().field_width_in_words(); | 645 } |
| 646 PropertyDetails details = d.GetDetails(); |
| 647 layout_descriptor = LayoutDescriptor::ShareAppend(map, details); |
| 648 descriptors->Append(&d); |
| 649 if (details.location() == kField) { |
| 650 int field_width_in_words = details.field_width_in_words(); |
646 next_field_offset += field_width_in_words; | 651 next_field_offset += field_width_in_words; |
647 layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails()); | |
648 descriptors->Append(&d); | |
649 | 652 |
650 int field_index = d.GetDetails().field_index(); | 653 int field_index = details.field_index(); |
651 bool is_inobject = field_index < map->GetInObjectProperties(); | 654 bool is_inobject = field_index < map->GetInObjectProperties(); |
652 for (int bit = 0; bit < field_width_in_words; bit++) { | 655 for (int bit = 0; bit < field_width_in_words; bit++) { |
653 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), | 656 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), |
654 !layout_descriptor->IsTagged(field_index + bit)); | 657 !layout_descriptor->IsTagged(field_index + bit)); |
655 } | 658 } |
656 CHECK(layout_descriptor->IsTagged(next_field_offset)); | 659 CHECK(layout_descriptor->IsTagged(next_field_offset)); |
657 } | 660 } |
658 map->InitializeDescriptors(*descriptors, *layout_descriptor); | 661 map->InitializeDescriptors(*descriptors, *layout_descriptor); |
659 } | 662 } |
660 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); | 663 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 v8::HandleScope scope(CcTest::isolate()); | 954 v8::HandleScope scope(CcTest::isolate()); |
952 Isolate* isolate = CcTest::i_isolate(); | 955 Isolate* isolate = CcTest::i_isolate(); |
953 | 956 |
954 const int kFieldCount = 128; | 957 const int kFieldCount = 128; |
955 const int kSplitFieldIndex = 32; | 958 const int kSplitFieldIndex = 32; |
956 const int kTrimmedLayoutDescriptorLength = 64; | 959 const int kTrimmedLayoutDescriptorLength = 64; |
957 | 960 |
958 Handle<FieldType> any_type = FieldType::Any(isolate); | 961 Handle<FieldType> any_type = FieldType::Any(isolate); |
959 Handle<Map> map = Map::Create(isolate, kFieldCount); | 962 Handle<Map> map = Map::Create(isolate, kFieldCount); |
960 for (int i = 0; i < kSplitFieldIndex; i++) { | 963 for (int i = 0; i < kSplitFieldIndex; i++) { |
961 map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, | 964 map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, kMutable, |
962 Representation::Smi(), | 965 Representation::Smi(), INSERT_TRANSITION) |
963 INSERT_TRANSITION).ToHandleChecked(); | 966 .ToHandleChecked(); |
964 } | 967 } |
965 map = Map::CopyWithField(map, MakeName("dbl", kSplitFieldIndex), any_type, | 968 map = |
966 NONE, Representation::Double(), | 969 Map::CopyWithField(map, MakeName("dbl", kSplitFieldIndex), any_type, NONE, |
967 INSERT_TRANSITION).ToHandleChecked(); | 970 kMutable, Representation::Double(), INSERT_TRANSITION) |
| 971 .ToHandleChecked(); |
968 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); | 972 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); |
969 CHECK(map->layout_descriptor()->IsSlowLayout()); | 973 CHECK(map->layout_descriptor()->IsSlowLayout()); |
970 CHECK(map->owns_descriptors()); | 974 CHECK(map->owns_descriptors()); |
971 CHECK_EQ(2, map->layout_descriptor()->length()); | 975 CHECK_EQ(2, map->layout_descriptor()->length()); |
972 | 976 |
973 { | 977 { |
974 // Add transitions to double fields. | 978 // Add transitions to double fields. |
975 v8::HandleScope scope(CcTest::isolate()); | 979 v8::HandleScope scope(CcTest::isolate()); |
976 | 980 |
977 Handle<Map> tmp_map = map; | 981 Handle<Map> tmp_map = map; |
978 for (int i = kSplitFieldIndex + 1; i < kFieldCount; i++) { | 982 for (int i = kSplitFieldIndex + 1; i < kFieldCount; i++) { |
979 tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE, | 983 tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE, |
980 Representation::Double(), | 984 kMutable, Representation::Double(), |
981 INSERT_TRANSITION).ToHandleChecked(); | 985 INSERT_TRANSITION) |
| 986 .ToHandleChecked(); |
982 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 987 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
983 } | 988 } |
984 // Check that descriptors are shared. | 989 // Check that descriptors are shared. |
985 CHECK(tmp_map->owns_descriptors()); | 990 CHECK(tmp_map->owns_descriptors()); |
986 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); | 991 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
987 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); | 992 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); |
988 } | 993 } |
989 CHECK(map->layout_descriptor()->IsSlowLayout()); | 994 CHECK(map->layout_descriptor()->IsSlowLayout()); |
990 CHECK_EQ(4, map->layout_descriptor()->length()); | 995 CHECK_EQ(4, map->layout_descriptor()->length()); |
991 | 996 |
(...skipping 17 matching lines...) Expand all Loading... |
1009 CHECK(map->layout_descriptor()->IsSlowLayout()); | 1014 CHECK(map->layout_descriptor()->IsSlowLayout()); |
1010 CHECK_EQ(2, map->layout_descriptor()->length()); | 1015 CHECK_EQ(2, map->layout_descriptor()->length()); |
1011 | 1016 |
1012 { | 1017 { |
1013 // Add transitions to tagged fields. | 1018 // Add transitions to tagged fields. |
1014 v8::HandleScope scope(CcTest::isolate()); | 1019 v8::HandleScope scope(CcTest::isolate()); |
1015 | 1020 |
1016 Handle<Map> tmp_map = map; | 1021 Handle<Map> tmp_map = map; |
1017 for (int i = kSplitFieldIndex + 1; i < kFieldCount - 1; i++) { | 1022 for (int i = kSplitFieldIndex + 1; i < kFieldCount - 1; i++) { |
1018 tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type, | 1023 tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type, |
1019 NONE, Representation::Tagged(), | 1024 NONE, kMutable, Representation::Tagged(), |
1020 INSERT_TRANSITION).ToHandleChecked(); | 1025 INSERT_TRANSITION) |
| 1026 .ToHandleChecked(); |
1021 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 1027 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
1022 } | 1028 } |
1023 tmp_map = Map::CopyWithField(tmp_map, MakeString("dbl"), any_type, NONE, | 1029 tmp_map = |
1024 Representation::Double(), | 1030 Map::CopyWithField(tmp_map, MakeString("dbl"), any_type, NONE, kMutable, |
1025 INSERT_TRANSITION).ToHandleChecked(); | 1031 Representation::Double(), INSERT_TRANSITION) |
| 1032 .ToHandleChecked(); |
1026 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 1033 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
1027 // Check that descriptors are shared. | 1034 // Check that descriptors are shared. |
1028 CHECK(tmp_map->owns_descriptors()); | 1035 CHECK(tmp_map->owns_descriptors()); |
1029 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); | 1036 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
1030 } | 1037 } |
1031 CHECK(map->layout_descriptor()->IsSlowLayout()); | 1038 CHECK(map->layout_descriptor()->IsSlowLayout()); |
1032 } | 1039 } |
1033 | 1040 |
1034 | 1041 |
1035 TEST(DoScavenge) { | 1042 TEST(DoScavenge) { |
1036 CcTest::InitializeVM(); | 1043 CcTest::InitializeVM(); |
1037 v8::HandleScope scope(CcTest::isolate()); | 1044 v8::HandleScope scope(CcTest::isolate()); |
1038 Isolate* isolate = CcTest::i_isolate(); | 1045 Isolate* isolate = CcTest::i_isolate(); |
1039 Factory* factory = isolate->factory(); | 1046 Factory* factory = isolate->factory(); |
1040 | 1047 |
1041 // The plan: create |obj| with double field in new space, do scanvenge so | 1048 // The plan: create |obj| with double field in new space, do scanvenge so |
1042 // that |obj| is moved to old space, construct a double value that looks like | 1049 // that |obj| is moved to old space, construct a double value that looks like |
1043 // a pointer to "from space" pointer. Do scavenge one more time and ensure | 1050 // a pointer to "from space" pointer. Do scavenge one more time and ensure |
1044 // that it didn't crash or corrupt the double value stored in the object. | 1051 // that it didn't crash or corrupt the double value stored in the object. |
1045 | 1052 |
1046 Handle<FieldType> any_type = FieldType::Any(isolate); | 1053 Handle<FieldType> any_type = FieldType::Any(isolate); |
1047 Handle<Map> map = Map::Create(isolate, 10); | 1054 Handle<Map> map = Map::Create(isolate, 10); |
1048 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, | 1055 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable, |
1049 Representation::Double(), | 1056 Representation::Double(), INSERT_TRANSITION) |
1050 INSERT_TRANSITION).ToHandleChecked(); | 1057 .ToHandleChecked(); |
1051 | 1058 |
1052 // Create object in new space. | 1059 // Create object in new space. |
1053 Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); | 1060 Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); |
1054 | 1061 |
1055 Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); | 1062 Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); |
1056 WriteToField(*obj, 0, *heap_number); | 1063 WriteToField(*obj, 0, *heap_number); |
1057 | 1064 |
1058 { | 1065 { |
1059 // Ensure the object is properly set up. | 1066 // Ensure the object is properly set up. |
1060 FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); | 1067 FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 PagedSpace* old_space = heap->old_space(); | 1107 PagedSpace* old_space = heap->old_space(); |
1101 | 1108 |
1102 // The plan: create |obj_value| in old space and ensure that it is allocated | 1109 // The plan: create |obj_value| in old space and ensure that it is allocated |
1103 // on evacuation candidate page, create |obj| with double and tagged fields | 1110 // on evacuation candidate page, create |obj| with double and tagged fields |
1104 // in new space and write |obj_value| to tagged field of |obj|, do two | 1111 // in new space and write |obj_value| to tagged field of |obj|, do two |
1105 // scavenges to promote |obj| to old space, a GC in old space and ensure that | 1112 // scavenges to promote |obj| to old space, a GC in old space and ensure that |
1106 // the tagged value was properly updated after candidates evacuation. | 1113 // the tagged value was properly updated after candidates evacuation. |
1107 | 1114 |
1108 Handle<FieldType> any_type = FieldType::Any(isolate); | 1115 Handle<FieldType> any_type = FieldType::Any(isolate); |
1109 Handle<Map> map = Map::Create(isolate, 10); | 1116 Handle<Map> map = Map::Create(isolate, 10); |
1110 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, | 1117 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable, |
1111 Representation::Double(), | 1118 Representation::Double(), INSERT_TRANSITION) |
1112 INSERT_TRANSITION).ToHandleChecked(); | 1119 .ToHandleChecked(); |
1113 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, | 1120 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable, |
1114 Representation::Tagged(), | 1121 Representation::Tagged(), INSERT_TRANSITION) |
1115 INSERT_TRANSITION).ToHandleChecked(); | 1122 .ToHandleChecked(); |
1116 | 1123 |
1117 // Create |obj_value| in old space. | 1124 // Create |obj_value| in old space. |
1118 Handle<HeapObject> obj_value; | 1125 Handle<HeapObject> obj_value; |
1119 Page* ec_page; | 1126 Page* ec_page; |
1120 { | 1127 { |
1121 AlwaysAllocateScope always_allocate(isolate); | 1128 AlwaysAllocateScope always_allocate(isolate); |
1122 // Make sure |obj_value| is placed on an old-space evacuation candidate. | 1129 // Make sure |obj_value| is placed on an old-space evacuation candidate. |
1123 heap::SimulateFullSpace(old_space); | 1130 heap::SimulateFullSpace(old_space); |
1124 obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); | 1131 obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
1125 ec_page = Page::FromAddress(obj_value->address()); | 1132 ec_page = Page::FromAddress(obj_value->address()); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 CcTest::InitializeVM(); | 1335 CcTest::InitializeVM(); |
1329 v8::HandleScope scope(CcTest::isolate()); | 1336 v8::HandleScope scope(CcTest::isolate()); |
1330 Isolate* isolate = CcTest::i_isolate(); | 1337 Isolate* isolate = CcTest::i_isolate(); |
1331 Handle<FieldType> any_type = FieldType::Any(isolate); | 1338 Handle<FieldType> any_type = FieldType::Any(isolate); |
1332 | 1339 |
1333 Handle<Map> split_map; | 1340 Handle<Map> split_map; |
1334 { | 1341 { |
1335 Handle<Map> map = Map::Create(isolate, 64); | 1342 Handle<Map> map = Map::Create(isolate, 64); |
1336 for (int i = 0; i < 32; i++) { | 1343 for (int i = 0; i < 32; i++) { |
1337 Handle<String> name = MakeName("prop", i); | 1344 Handle<String> name = MakeName("prop", i); |
1338 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), | 1345 map = Map::CopyWithField(map, name, any_type, NONE, kMutable, |
1339 INSERT_TRANSITION).ToHandleChecked(); | 1346 Representation::Smi(), INSERT_TRANSITION) |
| 1347 .ToHandleChecked(); |
1340 } | 1348 } |
1341 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, | 1349 split_map = |
1342 Representation::Double(), | 1350 Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, kMutable, |
1343 INSERT_TRANSITION).ToHandleChecked(); | 1351 Representation::Double(), INSERT_TRANSITION) |
| 1352 .ToHandleChecked(); |
1344 } | 1353 } |
1345 Handle<LayoutDescriptor> split_layout_descriptor( | 1354 Handle<LayoutDescriptor> split_layout_descriptor( |
1346 split_map->layout_descriptor(), isolate); | 1355 split_map->layout_descriptor(), isolate); |
1347 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true)); | 1356 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true)); |
1348 CHECK(split_layout_descriptor->IsSlowLayout()); | 1357 CHECK(split_layout_descriptor->IsSlowLayout()); |
1349 CHECK(split_map->owns_descriptors()); | 1358 CHECK(split_map->owns_descriptors()); |
1350 | 1359 |
1351 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, | 1360 Handle<Map> map1 = |
1352 NONE, Representation::Double(), | 1361 Map::CopyWithField(split_map, MakeString("foo"), any_type, NONE, kMutable, |
1353 INSERT_TRANSITION).ToHandleChecked(); | 1362 Representation::Double(), INSERT_TRANSITION) |
| 1363 .ToHandleChecked(); |
1354 CHECK(!split_map->owns_descriptors()); | 1364 CHECK(!split_map->owns_descriptors()); |
1355 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); | 1365 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); |
1356 | 1366 |
1357 // Layout descriptors should be shared with |split_map|. | 1367 // Layout descriptors should be shared with |split_map|. |
1358 CHECK(map1->owns_descriptors()); | 1368 CHECK(map1->owns_descriptors()); |
1359 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); | 1369 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); |
1360 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true)); | 1370 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true)); |
1361 | 1371 |
1362 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, | 1372 Handle<Map> map2 = |
1363 NONE, Representation::Tagged(), | 1373 Map::CopyWithField(split_map, MakeString("bar"), any_type, NONE, kMutable, |
1364 INSERT_TRANSITION).ToHandleChecked(); | 1374 Representation::Tagged(), INSERT_TRANSITION) |
| 1375 .ToHandleChecked(); |
1365 | 1376 |
1366 // Layout descriptors should not be shared with |split_map|. | 1377 // Layout descriptors should not be shared with |split_map|. |
1367 CHECK(map2->owns_descriptors()); | 1378 CHECK(map2->owns_descriptors()); |
1368 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); | 1379 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); |
1369 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true)); | 1380 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true)); |
1370 } | 1381 } |
1371 | 1382 |
1372 | 1383 |
1373 static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, | 1384 static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, |
1374 int tagged_descriptor, int double_descriptor, | 1385 int tagged_descriptor, int double_descriptor, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 | 1535 |
1525 Handle<FieldType> any_type = FieldType::Any(isolate); | 1536 Handle<FieldType> any_type = FieldType::Any(isolate); |
1526 | 1537 |
1527 CompileRun("function func() { return 1; }"); | 1538 CompileRun("function func() { return 1; }"); |
1528 | 1539 |
1529 Handle<JSObject> func = GetObject("func"); | 1540 Handle<JSObject> func = GetObject("func"); |
1530 | 1541 |
1531 Handle<Map> map = Map::Create(isolate, 10); | 1542 Handle<Map> map = Map::Create(isolate, 10); |
1532 map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE, | 1543 map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE, |
1533 INSERT_TRANSITION).ToHandleChecked(); | 1544 INSERT_TRANSITION).ToHandleChecked(); |
1534 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, | 1545 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable, |
1535 Representation::Double(), | 1546 Representation::Double(), INSERT_TRANSITION) |
1536 INSERT_TRANSITION).ToHandleChecked(); | 1547 .ToHandleChecked(); |
1537 map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, | 1548 map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, kMutable, |
1538 Representation::Tagged(), | 1549 Representation::Tagged(), INSERT_TRANSITION) |
1539 INSERT_TRANSITION).ToHandleChecked(); | 1550 .ToHandleChecked(); |
1540 | 1551 |
1541 // Shift fields right by turning constant property to a field. | 1552 // Shift fields right by turning constant property to a field. |
1542 Handle<Map> new_map = Map::ReconfigureProperty( | 1553 Handle<Map> new_map = Map::ReconfigureProperty( |
1543 map, 0, kData, NONE, Representation::Tagged(), any_type); | 1554 map, 0, kData, NONE, Representation::Tagged(), any_type); |
1544 | 1555 |
1545 if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { | 1556 if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { |
1546 TestWriteBarrier(map, new_map, 2, 1); | 1557 TestWriteBarrier(map, new_map, 2, 1); |
1547 } else { | 1558 } else { |
1548 CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); | 1559 CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); |
1549 TestIncrementalWriteBarrier(map, new_map, 2, 1); | 1560 TestIncrementalWriteBarrier(map, new_map, 2, 1); |
(...skipping 12 matching lines...) Expand all Loading... |
1562 | 1573 |
1563 // TODO(ishell): add respective tests for property kind reconfiguring from | 1574 // TODO(ishell): add respective tests for property kind reconfiguring from |
1564 // accessor field to double, once accessor fields are supported by | 1575 // accessor field to double, once accessor fields are supported by |
1565 // Map::ReconfigureProperty(). | 1576 // Map::ReconfigureProperty(). |
1566 | 1577 |
1567 | 1578 |
1568 // TODO(ishell): add respective tests for fast property removal case once | 1579 // TODO(ishell): add respective tests for fast property removal case once |
1569 // Map::ReconfigureProperty() supports that. | 1580 // Map::ReconfigureProperty() supports that. |
1570 | 1581 |
1571 #endif | 1582 #endif |
OLD | NEW |