Chromium Code Reviews| 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 |