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"); | 621 // Handle<String> func_name = factory->InternalizeUtf8String("func"); |
620 Handle<JSFunction> func = factory->NewFunction(func_name); | 622 // Handle<JSFunction> func = factory->NewFunction(func_name); |
Toon Verwaest
2017/02/09 16:06:09
delete
Igor Sheludko
2017/02/09 17:08:14
Done.
| |
621 | 623 |
622 Handle<DescriptorArray> descriptors = | 624 Handle<DescriptorArray> descriptors = |
623 DescriptorArray::Allocate(isolate, 0, kPropsCount); | 625 DescriptorArray::Allocate(isolate, 0, kPropsCount); |
624 | 626 |
625 Handle<Map> map = Map::Create(isolate, inobject_properties); | 627 Handle<Map> map = Map::Create(isolate, inobject_properties); |
626 map->InitializeDescriptors(*descriptors, | 628 map->InitializeDescriptors(*descriptors, |
627 LayoutDescriptor::FastPointerLayout()); | 629 LayoutDescriptor::FastPointerLayout()); |
628 | 630 |
629 int next_field_offset = 0; | 631 int next_field_offset = 0; |
630 for (int i = 0; i < kPropsCount; i++) { | 632 for (int i = 0; i < kPropsCount; i++) { |
631 EmbeddedVector<char, 64> buffer; | 633 EmbeddedVector<char, 64> buffer; |
632 SNPrintF(buffer, "prop%d", i); | 634 SNPrintF(buffer, "prop%d", i); |
633 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); | 635 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); |
634 | 636 |
635 Handle<LayoutDescriptor> layout_descriptor; | 637 Handle<LayoutDescriptor> layout_descriptor; |
636 TestPropertyKind kind = props[i]; | 638 TestPropertyKind kind = props[i]; |
637 if (kind == PROP_CONSTANT) { | 639 Descriptor d; |
638 Descriptor d = Descriptor::DataConstant(name, func, NONE); | 640 if (kind == PROP_ACCESSOR_INFO) { |
639 layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails()); | 641 Handle<AccessorInfo> info = |
640 descriptors->Append(&d); | 642 Accessors::MakeAccessor(isolate, name, nullptr, nullptr, NONE); |
643 d = Descriptor::AccessorConstant(name, info, NONE); | |
641 | 644 |
642 } else { | 645 } else { |
643 Descriptor d = Descriptor::DataField(name, next_field_offset, NONE, | 646 d = Descriptor::DataField(name, next_field_offset, NONE, |
644 representations[kind]); | 647 representations[kind]); |
645 int field_width_in_words = d.GetDetails().field_width_in_words(); | 648 } |
649 PropertyDetails details = d.GetDetails(); | |
650 layout_descriptor = LayoutDescriptor::ShareAppend(map, details); | |
651 descriptors->Append(&d); | |
652 if (details.location() == kField) { | |
653 int field_width_in_words = details.field_width_in_words(); | |
646 next_field_offset += field_width_in_words; | 654 next_field_offset += field_width_in_words; |
647 layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails()); | |
648 descriptors->Append(&d); | |
649 | 655 |
650 int field_index = d.GetDetails().field_index(); | 656 int field_index = details.field_index(); |
651 bool is_inobject = field_index < map->GetInObjectProperties(); | 657 bool is_inobject = field_index < map->GetInObjectProperties(); |
652 for (int bit = 0; bit < field_width_in_words; bit++) { | 658 for (int bit = 0; bit < field_width_in_words; bit++) { |
653 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), | 659 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), |
654 !layout_descriptor->IsTagged(field_index + bit)); | 660 !layout_descriptor->IsTagged(field_index + bit)); |
655 } | 661 } |
656 CHECK(layout_descriptor->IsTagged(next_field_offset)); | 662 CHECK(layout_descriptor->IsTagged(next_field_offset)); |
657 } | 663 } |
658 map->InitializeDescriptors(*descriptors, *layout_descriptor); | 664 map->InitializeDescriptors(*descriptors, *layout_descriptor); |
659 } | 665 } |
660 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); | 666 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()); | 957 v8::HandleScope scope(CcTest::isolate()); |
952 Isolate* isolate = CcTest::i_isolate(); | 958 Isolate* isolate = CcTest::i_isolate(); |
953 | 959 |
954 const int kFieldCount = 128; | 960 const int kFieldCount = 128; |
955 const int kSplitFieldIndex = 32; | 961 const int kSplitFieldIndex = 32; |
956 const int kTrimmedLayoutDescriptorLength = 64; | 962 const int kTrimmedLayoutDescriptorLength = 64; |
957 | 963 |
958 Handle<FieldType> any_type = FieldType::Any(isolate); | 964 Handle<FieldType> any_type = FieldType::Any(isolate); |
959 Handle<Map> map = Map::Create(isolate, kFieldCount); | 965 Handle<Map> map = Map::Create(isolate, kFieldCount); |
960 for (int i = 0; i < kSplitFieldIndex; i++) { | 966 for (int i = 0; i < kSplitFieldIndex; i++) { |
961 map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, | 967 map = Map::CopyWithField(map, MakeName("prop", i), any_type, NONE, kMutable, |
962 Representation::Smi(), | 968 Representation::Smi(), INSERT_TRANSITION) |
963 INSERT_TRANSITION).ToHandleChecked(); | 969 .ToHandleChecked(); |
964 } | 970 } |
965 map = Map::CopyWithField(map, MakeName("dbl", kSplitFieldIndex), any_type, | 971 map = |
966 NONE, Representation::Double(), | 972 Map::CopyWithField(map, MakeName("dbl", kSplitFieldIndex), any_type, NONE, |
967 INSERT_TRANSITION).ToHandleChecked(); | 973 kMutable, Representation::Double(), INSERT_TRANSITION) |
974 .ToHandleChecked(); | |
968 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); | 975 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true)); |
969 CHECK(map->layout_descriptor()->IsSlowLayout()); | 976 CHECK(map->layout_descriptor()->IsSlowLayout()); |
970 CHECK(map->owns_descriptors()); | 977 CHECK(map->owns_descriptors()); |
971 CHECK_EQ(2, map->layout_descriptor()->length()); | 978 CHECK_EQ(2, map->layout_descriptor()->length()); |
972 | 979 |
973 { | 980 { |
974 // Add transitions to double fields. | 981 // Add transitions to double fields. |
975 v8::HandleScope scope(CcTest::isolate()); | 982 v8::HandleScope scope(CcTest::isolate()); |
976 | 983 |
977 Handle<Map> tmp_map = map; | 984 Handle<Map> tmp_map = map; |
978 for (int i = kSplitFieldIndex + 1; i < kFieldCount; i++) { | 985 for (int i = kSplitFieldIndex + 1; i < kFieldCount; i++) { |
979 tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE, | 986 tmp_map = Map::CopyWithField(tmp_map, MakeName("dbl", i), any_type, NONE, |
980 Representation::Double(), | 987 kMutable, Representation::Double(), |
981 INSERT_TRANSITION).ToHandleChecked(); | 988 INSERT_TRANSITION) |
989 .ToHandleChecked(); | |
982 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 990 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
983 } | 991 } |
984 // Check that descriptors are shared. | 992 // Check that descriptors are shared. |
985 CHECK(tmp_map->owns_descriptors()); | 993 CHECK(tmp_map->owns_descriptors()); |
986 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); | 994 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
987 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); | 995 CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor()); |
988 } | 996 } |
989 CHECK(map->layout_descriptor()->IsSlowLayout()); | 997 CHECK(map->layout_descriptor()->IsSlowLayout()); |
990 CHECK_EQ(4, map->layout_descriptor()->length()); | 998 CHECK_EQ(4, map->layout_descriptor()->length()); |
991 | 999 |
(...skipping 17 matching lines...) Expand all Loading... | |
1009 CHECK(map->layout_descriptor()->IsSlowLayout()); | 1017 CHECK(map->layout_descriptor()->IsSlowLayout()); |
1010 CHECK_EQ(2, map->layout_descriptor()->length()); | 1018 CHECK_EQ(2, map->layout_descriptor()->length()); |
1011 | 1019 |
1012 { | 1020 { |
1013 // Add transitions to tagged fields. | 1021 // Add transitions to tagged fields. |
1014 v8::HandleScope scope(CcTest::isolate()); | 1022 v8::HandleScope scope(CcTest::isolate()); |
1015 | 1023 |
1016 Handle<Map> tmp_map = map; | 1024 Handle<Map> tmp_map = map; |
1017 for (int i = kSplitFieldIndex + 1; i < kFieldCount - 1; i++) { | 1025 for (int i = kSplitFieldIndex + 1; i < kFieldCount - 1; i++) { |
1018 tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type, | 1026 tmp_map = Map::CopyWithField(tmp_map, MakeName("tagged", i), any_type, |
1019 NONE, Representation::Tagged(), | 1027 NONE, kMutable, Representation::Tagged(), |
1020 INSERT_TRANSITION).ToHandleChecked(); | 1028 INSERT_TRANSITION) |
1029 .ToHandleChecked(); | |
1021 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 1030 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
1022 } | 1031 } |
1023 tmp_map = Map::CopyWithField(tmp_map, MakeString("dbl"), any_type, NONE, | 1032 tmp_map = |
1024 Representation::Double(), | 1033 Map::CopyWithField(tmp_map, MakeString("dbl"), any_type, NONE, kMutable, |
1025 INSERT_TRANSITION).ToHandleChecked(); | 1034 Representation::Double(), INSERT_TRANSITION) |
1035 .ToHandleChecked(); | |
1026 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); | 1036 CHECK(tmp_map->layout_descriptor()->IsConsistentWithMap(*tmp_map, true)); |
1027 // Check that descriptors are shared. | 1037 // Check that descriptors are shared. |
1028 CHECK(tmp_map->owns_descriptors()); | 1038 CHECK(tmp_map->owns_descriptors()); |
1029 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); | 1039 CHECK_EQ(map->instance_descriptors(), tmp_map->instance_descriptors()); |
1030 } | 1040 } |
1031 CHECK(map->layout_descriptor()->IsSlowLayout()); | 1041 CHECK(map->layout_descriptor()->IsSlowLayout()); |
1032 } | 1042 } |
1033 | 1043 |
1034 | 1044 |
1035 TEST(DoScavenge) { | 1045 TEST(DoScavenge) { |
1036 CcTest::InitializeVM(); | 1046 CcTest::InitializeVM(); |
1037 v8::HandleScope scope(CcTest::isolate()); | 1047 v8::HandleScope scope(CcTest::isolate()); |
1038 Isolate* isolate = CcTest::i_isolate(); | 1048 Isolate* isolate = CcTest::i_isolate(); |
1039 Factory* factory = isolate->factory(); | 1049 Factory* factory = isolate->factory(); |
1040 | 1050 |
1041 // The plan: create |obj| with double field in new space, do scanvenge so | 1051 // 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 | 1052 // 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 | 1053 // 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. | 1054 // that it didn't crash or corrupt the double value stored in the object. |
1045 | 1055 |
1046 Handle<FieldType> any_type = FieldType::Any(isolate); | 1056 Handle<FieldType> any_type = FieldType::Any(isolate); |
1047 Handle<Map> map = Map::Create(isolate, 10); | 1057 Handle<Map> map = Map::Create(isolate, 10); |
1048 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, | 1058 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable, |
1049 Representation::Double(), | 1059 Representation::Double(), INSERT_TRANSITION) |
1050 INSERT_TRANSITION).ToHandleChecked(); | 1060 .ToHandleChecked(); |
1051 | 1061 |
1052 // Create object in new space. | 1062 // Create object in new space. |
1053 Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); | 1063 Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); |
1054 | 1064 |
1055 Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); | 1065 Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); |
1056 WriteToField(*obj, 0, *heap_number); | 1066 WriteToField(*obj, 0, *heap_number); |
1057 | 1067 |
1058 { | 1068 { |
1059 // Ensure the object is properly set up. | 1069 // Ensure the object is properly set up. |
1060 FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); | 1070 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(); | 1110 PagedSpace* old_space = heap->old_space(); |
1101 | 1111 |
1102 // The plan: create |obj_value| in old space and ensure that it is allocated | 1112 // 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 | 1113 // 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 | 1114 // 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 | 1115 // 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. | 1116 // the tagged value was properly updated after candidates evacuation. |
1107 | 1117 |
1108 Handle<FieldType> any_type = FieldType::Any(isolate); | 1118 Handle<FieldType> any_type = FieldType::Any(isolate); |
1109 Handle<Map> map = Map::Create(isolate, 10); | 1119 Handle<Map> map = Map::Create(isolate, 10); |
1110 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, | 1120 map = Map::CopyWithField(map, MakeName("prop", 0), any_type, NONE, kMutable, |
1111 Representation::Double(), | 1121 Representation::Double(), INSERT_TRANSITION) |
1112 INSERT_TRANSITION).ToHandleChecked(); | 1122 .ToHandleChecked(); |
1113 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, | 1123 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable, |
1114 Representation::Tagged(), | 1124 Representation::Tagged(), INSERT_TRANSITION) |
1115 INSERT_TRANSITION).ToHandleChecked(); | 1125 .ToHandleChecked(); |
1116 | 1126 |
1117 // Create |obj_value| in old space. | 1127 // Create |obj_value| in old space. |
1118 Handle<HeapObject> obj_value; | 1128 Handle<HeapObject> obj_value; |
1119 Page* ec_page; | 1129 Page* ec_page; |
1120 { | 1130 { |
1121 AlwaysAllocateScope always_allocate(isolate); | 1131 AlwaysAllocateScope always_allocate(isolate); |
1122 // Make sure |obj_value| is placed on an old-space evacuation candidate. | 1132 // Make sure |obj_value| is placed on an old-space evacuation candidate. |
1123 heap::SimulateFullSpace(old_space); | 1133 heap::SimulateFullSpace(old_space); |
1124 obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); | 1134 obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
1125 ec_page = Page::FromAddress(obj_value->address()); | 1135 ec_page = Page::FromAddress(obj_value->address()); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1328 CcTest::InitializeVM(); | 1338 CcTest::InitializeVM(); |
1329 v8::HandleScope scope(CcTest::isolate()); | 1339 v8::HandleScope scope(CcTest::isolate()); |
1330 Isolate* isolate = CcTest::i_isolate(); | 1340 Isolate* isolate = CcTest::i_isolate(); |
1331 Handle<FieldType> any_type = FieldType::Any(isolate); | 1341 Handle<FieldType> any_type = FieldType::Any(isolate); |
1332 | 1342 |
1333 Handle<Map> split_map; | 1343 Handle<Map> split_map; |
1334 { | 1344 { |
1335 Handle<Map> map = Map::Create(isolate, 64); | 1345 Handle<Map> map = Map::Create(isolate, 64); |
1336 for (int i = 0; i < 32; i++) { | 1346 for (int i = 0; i < 32; i++) { |
1337 Handle<String> name = MakeName("prop", i); | 1347 Handle<String> name = MakeName("prop", i); |
1338 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), | 1348 map = Map::CopyWithField(map, name, any_type, NONE, kMutable, |
1339 INSERT_TRANSITION).ToHandleChecked(); | 1349 Representation::Smi(), INSERT_TRANSITION) |
1350 .ToHandleChecked(); | |
1340 } | 1351 } |
1341 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, | 1352 split_map = |
1342 Representation::Double(), | 1353 Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, kMutable, |
1343 INSERT_TRANSITION).ToHandleChecked(); | 1354 Representation::Double(), INSERT_TRANSITION) |
1355 .ToHandleChecked(); | |
1344 } | 1356 } |
1345 Handle<LayoutDescriptor> split_layout_descriptor( | 1357 Handle<LayoutDescriptor> split_layout_descriptor( |
1346 split_map->layout_descriptor(), isolate); | 1358 split_map->layout_descriptor(), isolate); |
1347 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true)); | 1359 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map, true)); |
1348 CHECK(split_layout_descriptor->IsSlowLayout()); | 1360 CHECK(split_layout_descriptor->IsSlowLayout()); |
1349 CHECK(split_map->owns_descriptors()); | 1361 CHECK(split_map->owns_descriptors()); |
1350 | 1362 |
1351 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, | 1363 Handle<Map> map1 = |
1352 NONE, Representation::Double(), | 1364 Map::CopyWithField(split_map, MakeString("foo"), any_type, NONE, kMutable, |
1353 INSERT_TRANSITION).ToHandleChecked(); | 1365 Representation::Double(), INSERT_TRANSITION) |
1366 .ToHandleChecked(); | |
1354 CHECK(!split_map->owns_descriptors()); | 1367 CHECK(!split_map->owns_descriptors()); |
1355 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); | 1368 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); |
1356 | 1369 |
1357 // Layout descriptors should be shared with |split_map|. | 1370 // Layout descriptors should be shared with |split_map|. |
1358 CHECK(map1->owns_descriptors()); | 1371 CHECK(map1->owns_descriptors()); |
1359 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); | 1372 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); |
1360 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true)); | 1373 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1, true)); |
1361 | 1374 |
1362 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, | 1375 Handle<Map> map2 = |
1363 NONE, Representation::Tagged(), | 1376 Map::CopyWithField(split_map, MakeString("bar"), any_type, NONE, kMutable, |
1364 INSERT_TRANSITION).ToHandleChecked(); | 1377 Representation::Tagged(), INSERT_TRANSITION) |
1378 .ToHandleChecked(); | |
1365 | 1379 |
1366 // Layout descriptors should not be shared with |split_map|. | 1380 // Layout descriptors should not be shared with |split_map|. |
1367 CHECK(map2->owns_descriptors()); | 1381 CHECK(map2->owns_descriptors()); |
1368 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); | 1382 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); |
1369 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true)); | 1383 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2, true)); |
1370 } | 1384 } |
1371 | 1385 |
1372 | 1386 |
1373 static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, | 1387 static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, |
1374 int tagged_descriptor, int double_descriptor, | 1388 int tagged_descriptor, int double_descriptor, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1524 | 1538 |
1525 Handle<FieldType> any_type = FieldType::Any(isolate); | 1539 Handle<FieldType> any_type = FieldType::Any(isolate); |
1526 | 1540 |
1527 CompileRun("function func() { return 1; }"); | 1541 CompileRun("function func() { return 1; }"); |
1528 | 1542 |
1529 Handle<JSObject> func = GetObject("func"); | 1543 Handle<JSObject> func = GetObject("func"); |
1530 | 1544 |
1531 Handle<Map> map = Map::Create(isolate, 10); | 1545 Handle<Map> map = Map::Create(isolate, 10); |
1532 map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE, | 1546 map = Map::CopyWithConstant(map, MakeName("prop", 0), func, NONE, |
1533 INSERT_TRANSITION).ToHandleChecked(); | 1547 INSERT_TRANSITION).ToHandleChecked(); |
1534 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, | 1548 map = Map::CopyWithField(map, MakeName("prop", 1), any_type, NONE, kMutable, |
1535 Representation::Double(), | 1549 Representation::Double(), INSERT_TRANSITION) |
1536 INSERT_TRANSITION).ToHandleChecked(); | 1550 .ToHandleChecked(); |
1537 map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, | 1551 map = Map::CopyWithField(map, MakeName("prop", 2), any_type, NONE, kMutable, |
1538 Representation::Tagged(), | 1552 Representation::Tagged(), INSERT_TRANSITION) |
1539 INSERT_TRANSITION).ToHandleChecked(); | 1553 .ToHandleChecked(); |
1540 | 1554 |
1541 // Shift fields right by turning constant property to a field. | 1555 // Shift fields right by turning constant property to a field. |
1542 Handle<Map> new_map = Map::ReconfigureProperty( | 1556 Handle<Map> new_map = Map::ReconfigureProperty( |
1543 map, 0, kData, NONE, Representation::Tagged(), any_type); | 1557 map, 0, kData, NONE, Representation::Tagged(), any_type); |
1544 | 1558 |
1545 if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { | 1559 if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { |
1546 TestWriteBarrier(map, new_map, 2, 1); | 1560 TestWriteBarrier(map, new_map, 2, 1); |
1547 } else { | 1561 } else { |
1548 CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); | 1562 CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); |
1549 TestIncrementalWriteBarrier(map, new_map, 2, 1); | 1563 TestIncrementalWriteBarrier(map, new_map, 2, 1); |
(...skipping 12 matching lines...) Expand all Loading... | |
1562 | 1576 |
1563 // TODO(ishell): add respective tests for property kind reconfiguring from | 1577 // TODO(ishell): add respective tests for property kind reconfiguring from |
1564 // accessor field to double, once accessor fields are supported by | 1578 // accessor field to double, once accessor fields are supported by |
1565 // Map::ReconfigureProperty(). | 1579 // Map::ReconfigureProperty(). |
1566 | 1580 |
1567 | 1581 |
1568 // TODO(ishell): add respective tests for fast property removal case once | 1582 // TODO(ishell): add respective tests for fast property removal case once |
1569 // Map::ReconfigureProperty() supports that. | 1583 // Map::ReconfigureProperty() supports that. |
1570 | 1584 |
1571 #endif | 1585 #endif |
OLD | NEW |