| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 // | 24 // |
| 25 // Helper functions. | 25 // Helper functions. |
| 26 // | 26 // |
| 27 | 27 |
| 28 | 28 |
| 29 static void InitializeVerifiedMapDescriptors( | 29 static void InitializeVerifiedMapDescriptors( |
| 30 Map* map, DescriptorArray* descriptors, | 30 Map* map, DescriptorArray* descriptors, |
| 31 LayoutDescriptor* layout_descriptor) { | 31 LayoutDescriptor* layout_descriptor) { |
| 32 map->InitializeDescriptors(descriptors, layout_descriptor); | 32 map->InitializeDescriptors(descriptors, layout_descriptor); |
| 33 #ifdef VERIFY_HEAP | 33 CHECK(layout_descriptor->IsConsistentWithMap(map)); |
| 34 if (FLAG_verify_heap) { | |
| 35 DCHECK(layout_descriptor->IsConsistentWithMap(map)); | |
| 36 } | |
| 37 #endif | |
| 38 } | 34 } |
| 39 | 35 |
| 40 | 36 |
| 41 static Handle<String> MakeString(const char* str) { | 37 static Handle<String> MakeString(const char* str) { |
| 42 Isolate* isolate = CcTest::i_isolate(); | 38 Isolate* isolate = CcTest::i_isolate(); |
| 43 Factory* factory = isolate->factory(); | 39 Factory* factory = isolate->factory(); |
| 44 return factory->InternalizeUtf8String(str); | 40 return factory->InternalizeUtf8String(str); |
| 45 } | 41 } |
| 46 | 42 |
| 47 | 43 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 LayoutDescriptor* layout_desc = *layout_descriptor; | 217 LayoutDescriptor* layout_desc = *layout_descriptor; |
| 222 // Play with the bits but leave it in consistent state with map at the end. | 218 // Play with the bits but leave it in consistent state with map at the end. |
| 223 for (int i = 1; i < kPropsCount - 1; i++) { | 219 for (int i = 1; i < kPropsCount - 1; i++) { |
| 224 layout_desc = layout_desc->SetTaggedForTesting(i, false); | 220 layout_desc = layout_desc->SetTaggedForTesting(i, false); |
| 225 CHECK_EQ(false, layout_desc->IsTagged(i)); | 221 CHECK_EQ(false, layout_desc->IsTagged(i)); |
| 226 layout_desc = layout_desc->SetTaggedForTesting(i, true); | 222 layout_desc = layout_desc->SetTaggedForTesting(i, true); |
| 227 CHECK_EQ(true, layout_desc->IsTagged(i)); | 223 CHECK_EQ(true, layout_desc->IsTagged(i)); |
| 228 } | 224 } |
| 229 CHECK(layout_desc->IsSlowLayout()); | 225 CHECK(layout_desc->IsSlowLayout()); |
| 230 CHECK(!layout_desc->IsFastPointerLayout()); | 226 CHECK(!layout_desc->IsFastPointerLayout()); |
| 231 #ifdef VERIFY_HEAP | 227 CHECK(layout_descriptor->IsConsistentWithMap(*map)); |
| 232 if (FLAG_verify_heap) { | |
| 233 DCHECK(layout_descriptor->IsConsistentWithMap(*map)); | |
| 234 } | |
| 235 #endif | |
| 236 } | 228 } |
| 237 } | 229 } |
| 238 | 230 |
| 239 | 231 |
| 240 static void TestLayoutDescriptorQueries(int layout_descriptor_length, | 232 static void TestLayoutDescriptorQueries(int layout_descriptor_length, |
| 241 int* bit_flip_positions, | 233 int* bit_flip_positions, |
| 242 int max_sequence_length) { | 234 int max_sequence_length) { |
| 243 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting( | 235 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting( |
| 244 CcTest::i_isolate(), layout_descriptor_length); | 236 CcTest::i_isolate(), layout_descriptor_length); |
| 245 layout_descriptor_length = layout_descriptor->capacity(); | 237 layout_descriptor_length = layout_descriptor->capacity(); |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 bool is_inobject = field_index < map->inobject_properties(); | 631 bool is_inobject = field_index < map->inobject_properties(); |
| 640 for (int bit = 0; bit < field_width_in_words; bit++) { | 632 for (int bit = 0; bit < field_width_in_words; bit++) { |
| 641 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), | 633 CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), |
| 642 !layout_descriptor->IsTagged(field_index + bit)); | 634 !layout_descriptor->IsTagged(field_index + bit)); |
| 643 } | 635 } |
| 644 CHECK(layout_descriptor->IsTagged(next_field_offset)); | 636 CHECK(layout_descriptor->IsTagged(next_field_offset)); |
| 645 } | 637 } |
| 646 map->InitializeDescriptors(*descriptors, *layout_descriptor); | 638 map->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 647 } | 639 } |
| 648 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); | 640 Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate); |
| 649 #ifdef VERIFY_HEAP | 641 CHECK(layout_descriptor->IsConsistentWithMap(*map)); |
| 650 if (FLAG_verify_heap) { | |
| 651 DCHECK(layout_descriptor->IsConsistentWithMap(*map)); | |
| 652 } | |
| 653 #endif | |
| 654 return layout_descriptor; | 642 return layout_descriptor; |
| 655 } | 643 } |
| 656 | 644 |
| 657 | 645 |
| 658 TEST(LayoutDescriptorAppend) { | 646 TEST(LayoutDescriptorAppend) { |
| 659 CcTest::InitializeVM(); | 647 CcTest::InitializeVM(); |
| 660 Isolate* isolate = CcTest::i_isolate(); | 648 Isolate* isolate = CcTest::i_isolate(); |
| 661 v8::HandleScope scope(CcTest::isolate()); | 649 v8::HandleScope scope(CcTest::isolate()); |
| 662 | 650 |
| 663 Handle<LayoutDescriptor> layout_descriptor; | 651 Handle<LayoutDescriptor> layout_descriptor; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 int field_width_in_words = details.field_width_in_words(); | 758 int field_width_in_words = details.field_width_in_words(); |
| 771 | 759 |
| 772 bool is_inobject = field_index < map->inobject_properties(); | 760 bool is_inobject = field_index < map->inobject_properties(); |
| 773 for (int bit = 0; bit < field_width_in_words; bit++) { | 761 for (int bit = 0; bit < field_width_in_words; bit++) { |
| 774 CHECK_EQ(is_inobject && details.representation().IsDouble(), | 762 CHECK_EQ(is_inobject && details.representation().IsDouble(), |
| 775 !layout_desc->IsTagged(field_index + bit)); | 763 !layout_desc->IsTagged(field_index + bit)); |
| 776 } | 764 } |
| 777 CHECK(layout_desc->IsTagged(field_index + field_width_in_words)); | 765 CHECK(layout_desc->IsTagged(field_index + field_width_in_words)); |
| 778 } | 766 } |
| 779 } | 767 } |
| 780 #ifdef VERIFY_HEAP | 768 CHECK(map->layout_descriptor()->IsConsistentWithMap(*map)); |
| 781 if (FLAG_verify_heap) { | |
| 782 DCHECK(map->layout_descriptor()->IsConsistentWithMap(*map)); | |
| 783 } | |
| 784 #endif | |
| 785 } | 769 } |
| 786 | 770 |
| 787 Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(), | 771 Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(), |
| 788 isolate); | 772 isolate); |
| 789 #ifdef VERIFY_HEAP | 773 CHECK(layout_descriptor->IsConsistentWithMap(*map)); |
| 790 if (FLAG_verify_heap) { | |
| 791 DCHECK(layout_descriptor->IsConsistentWithMap(*map)); | |
| 792 } | |
| 793 #endif | |
| 794 return layout_descriptor; | 774 return layout_descriptor; |
| 795 } | 775 } |
| 796 | 776 |
| 797 | 777 |
| 798 TEST(LayoutDescriptorAppendIfFastOrUseFull) { | 778 TEST(LayoutDescriptorAppendIfFastOrUseFull) { |
| 799 CcTest::InitializeVM(); | 779 CcTest::InitializeVM(); |
| 800 Isolate* isolate = CcTest::i_isolate(); | 780 Isolate* isolate = CcTest::i_isolate(); |
| 801 v8::HandleScope scope(CcTest::isolate()); | 781 v8::HandleScope scope(CcTest::isolate()); |
| 802 | 782 |
| 803 Handle<LayoutDescriptor> layout_descriptor; | 783 Handle<LayoutDescriptor> layout_descriptor; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 Handle<String> name = MakeName("prop", i); | 1124 Handle<String> name = MakeName("prop", i); |
| 1145 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), | 1125 map = Map::CopyWithField(map, name, any_type, NONE, Representation::Smi(), |
| 1146 INSERT_TRANSITION).ToHandleChecked(); | 1126 INSERT_TRANSITION).ToHandleChecked(); |
| 1147 } | 1127 } |
| 1148 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, | 1128 split_map = Map::CopyWithField(map, MakeString("dbl"), any_type, NONE, |
| 1149 Representation::Double(), | 1129 Representation::Double(), |
| 1150 INSERT_TRANSITION).ToHandleChecked(); | 1130 INSERT_TRANSITION).ToHandleChecked(); |
| 1151 } | 1131 } |
| 1152 Handle<LayoutDescriptor> split_layout_descriptor( | 1132 Handle<LayoutDescriptor> split_layout_descriptor( |
| 1153 split_map->layout_descriptor(), isolate); | 1133 split_map->layout_descriptor(), isolate); |
| 1154 #ifdef VERIFY_HEAP | 1134 CHECK(split_layout_descriptor->IsConsistentWithMap(*split_map)); |
| 1155 if (FLAG_verify_heap) { | |
| 1156 DCHECK(split_layout_descriptor->IsConsistentWithMap(*split_map)); | |
| 1157 } | |
| 1158 #endif | |
| 1159 CHECK(split_layout_descriptor->IsSlowLayout()); | 1135 CHECK(split_layout_descriptor->IsSlowLayout()); |
| 1160 CHECK(split_map->owns_descriptors()); | 1136 CHECK(split_map->owns_descriptors()); |
| 1161 | 1137 |
| 1162 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, | 1138 Handle<Map> map1 = Map::CopyWithField(split_map, MakeString("foo"), any_type, |
| 1163 NONE, Representation::Double(), | 1139 NONE, Representation::Double(), |
| 1164 INSERT_TRANSITION).ToHandleChecked(); | 1140 INSERT_TRANSITION).ToHandleChecked(); |
| 1165 CHECK(!split_map->owns_descriptors()); | 1141 CHECK(!split_map->owns_descriptors()); |
| 1166 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); | 1142 CHECK_EQ(*split_layout_descriptor, split_map->layout_descriptor()); |
| 1167 | 1143 |
| 1168 // Layout descriptors should be shared with |split_map|. | 1144 // Layout descriptors should be shared with |split_map|. |
| 1169 CHECK(map1->owns_descriptors()); | 1145 CHECK(map1->owns_descriptors()); |
| 1170 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); | 1146 CHECK_EQ(*split_layout_descriptor, map1->layout_descriptor()); |
| 1171 #ifdef VERIFY_HEAP | 1147 CHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1)); |
| 1172 if (FLAG_verify_heap) { | |
| 1173 DCHECK(map1->layout_descriptor()->IsConsistentWithMap(*map1)); | |
| 1174 } | |
| 1175 #endif | |
| 1176 | 1148 |
| 1177 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, | 1149 Handle<Map> map2 = Map::CopyWithField(split_map, MakeString("bar"), any_type, |
| 1178 NONE, Representation::Tagged(), | 1150 NONE, Representation::Tagged(), |
| 1179 INSERT_TRANSITION).ToHandleChecked(); | 1151 INSERT_TRANSITION).ToHandleChecked(); |
| 1180 | 1152 |
| 1181 // Layout descriptors should not be shared with |split_map|. | 1153 // Layout descriptors should not be shared with |split_map|. |
| 1182 CHECK(map2->owns_descriptors()); | 1154 CHECK(map2->owns_descriptors()); |
| 1183 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); | 1155 CHECK_NE(*split_layout_descriptor, map2->layout_descriptor()); |
| 1184 #ifdef VERIFY_HEAP | 1156 CHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2)); |
| 1185 if (FLAG_verify_heap) { | |
| 1186 DCHECK(map2->layout_descriptor()->IsConsistentWithMap(*map2)); | |
| 1187 } | |
| 1188 #endif | |
| 1189 } | 1157 } |
| 1190 | 1158 |
| 1191 | 1159 |
| 1192 TEST(StoreBufferScanOnScavenge) { | 1160 TEST(StoreBufferScanOnScavenge) { |
| 1193 CcTest::InitializeVM(); | 1161 CcTest::InitializeVM(); |
| 1194 Isolate* isolate = CcTest::i_isolate(); | 1162 Isolate* isolate = CcTest::i_isolate(); |
| 1195 Factory* factory = isolate->factory(); | 1163 Factory* factory = isolate->factory(); |
| 1196 v8::HandleScope scope(CcTest::isolate()); | 1164 v8::HandleScope scope(CcTest::isolate()); |
| 1197 | 1165 |
| 1198 CompileRun( | 1166 CompileRun( |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 Handle<JSObject> clone(JSObject::cast(clone_obj)); | 1299 Handle<JSObject> clone(JSObject::cast(clone_obj)); |
| 1332 CHECK(heap->old_pointer_space()->Contains(clone->address())); | 1300 CHECK(heap->old_pointer_space()->Contains(clone->address())); |
| 1333 | 1301 |
| 1334 CcTest::heap()->CollectGarbage(NEW_SPACE, "boom"); | 1302 CcTest::heap()->CollectGarbage(NEW_SPACE, "boom"); |
| 1335 | 1303 |
| 1336 // The value in cloned object should not be corrupted by GC. | 1304 // The value in cloned object should not be corrupted by GC. |
| 1337 CHECK_EQ(boom_value, clone->RawFastDoublePropertyAt(index)); | 1305 CHECK_EQ(boom_value, clone->RawFastDoublePropertyAt(index)); |
| 1338 } | 1306 } |
| 1339 | 1307 |
| 1340 #endif | 1308 #endif |
| OLD | NEW |