OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 | 2 |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "execution.h" | 7 #include "execution.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
10 #include "global-handles.h" | 10 #include "global-handles.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 // Check ToString for Numbers | 170 // Check ToString for Numbers |
171 CheckNumber(1.1, "1.1"); | 171 CheckNumber(1.1, "1.1"); |
172 | 172 |
173 CheckFindCodeObject(); | 173 CheckFindCodeObject(); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 TEST(Tagging) { | 177 TEST(Tagging) { |
178 InitializeVM(); | 178 InitializeVM(); |
179 int request = 24; | 179 int request = 24; |
180 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); | 180 CHECK_EQ(request, static_cast<int>(OBJECT_SIZE_ALIGN(request))); |
181 CHECK(Smi::FromInt(42)->IsSmi()); | 181 CHECK(Smi::FromInt(42)->IsSmi()); |
182 CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure()); | 182 CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure()); |
183 CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested()); | 183 CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested()); |
184 CHECK_EQ(NEW_SPACE, | 184 CHECK_EQ(NEW_SPACE, |
185 Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space()); | 185 Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space()); |
186 CHECK_EQ(OLD_POINTER_SPACE, | 186 CHECK_EQ(OLD_POINTER_SPACE, |
187 Failure::RetryAfterGC(request, | 187 Failure::RetryAfterGC(request, |
188 OLD_POINTER_SPACE)->allocation_space()); | 188 OLD_POINTER_SPACE)->allocation_space()); |
189 CHECK(Failure::Exception()->IsFailure()); | 189 CHECK(Failure::Exception()->IsFailure()); |
190 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); | 190 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 array->SetElement(0, *name); | 659 array->SetElement(0, *name); |
660 CHECK_EQ(Smi::FromInt(1), array->length()); | 660 CHECK_EQ(Smi::FromInt(1), array->length()); |
661 CHECK_EQ(array->GetElement(0), *name); | 661 CHECK_EQ(array->GetElement(0), *name); |
662 | 662 |
663 // Set array length with larger than smi value. | 663 // Set array length with larger than smi value. |
664 Handle<Object> length = | 664 Handle<Object> length = |
665 Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 665 Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
666 array->SetElementsLength(*length); | 666 array->SetElementsLength(*length); |
667 | 667 |
668 uint32_t int_length = 0; | 668 uint32_t int_length = 0; |
669 CHECK(length->ToArrayIndex(&int_length)); | 669 CHECK(Array::IndexFromObject(*length, &int_length)); |
670 CHECK_EQ(*length, array->length()); | 670 CHECK_EQ(*length, array->length()); |
671 CHECK(array->HasDictionaryElements()); // Must be in slow mode. | 671 CHECK(array->HasDictionaryElements()); // Must be in slow mode. |
672 | 672 |
673 // array[length] = name. | 673 // array[length] = name. |
674 array->SetElement(int_length, *name); | 674 array->SetElement(int_length, *name); |
675 uint32_t new_int_length = 0; | 675 uint32_t new_int_length = 0; |
676 CHECK(array->length()->ToArrayIndex(&new_int_length)); | 676 CHECK(Array::IndexFromObject(array->length(), &new_int_length)); |
677 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); | 677 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); |
678 CHECK_EQ(array->GetElement(int_length), *name); | 678 CHECK_EQ(array->GetElement(int_length), *name); |
679 CHECK_EQ(array->GetElement(0), *name); | 679 CHECK_EQ(array->GetElement(0), *name); |
680 } | 680 } |
681 | 681 |
682 | 682 |
683 TEST(JSObjectCopy) { | 683 TEST(JSObjectCopy) { |
684 InitializeVM(); | 684 InitializeVM(); |
685 | 685 |
686 v8::HandleScope sc; | 686 v8::HandleScope sc; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 Address next_page = current_page + Page::kPageSize; | 823 Address next_page = current_page + Page::kPageSize; |
824 int bytes_to_page = static_cast<int>(next_page - current_top); | 824 int bytes_to_page = static_cast<int>(next_page - current_top); |
825 if (bytes_to_page <= FixedArray::kHeaderSize) { | 825 if (bytes_to_page <= FixedArray::kHeaderSize) { |
826 // Alas, need to cross another page to be able to | 826 // Alas, need to cross another page to be able to |
827 // put desired value. | 827 // put desired value. |
828 next_page += Page::kPageSize; | 828 next_page += Page::kPageSize; |
829 bytes_to_page = static_cast<int>(next_page - current_top); | 829 bytes_to_page = static_cast<int>(next_page - current_top); |
830 } | 830 } |
831 CHECK(bytes_to_page > FixedArray::kHeaderSize); | 831 CHECK(bytes_to_page > FixedArray::kHeaderSize); |
832 | 832 |
833 intptr_t* flags_ptr = &Page::FromAddress(next_page)->flags_; | 833 int* flags_ptr = &Page::FromAddress(next_page)->flags; |
834 Address flags_addr = reinterpret_cast<Address>(flags_ptr); | 834 Address flags_addr = reinterpret_cast<Address>(flags_ptr); |
835 | 835 |
836 int bytes_to_allocate = | 836 int bytes_to_allocate = |
837 static_cast<int>(flags_addr - current_top) + kPointerSize; | 837 static_cast<int>(flags_addr - current_top) + kPointerSize; |
838 | 838 |
839 int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) / | 839 int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) / |
840 kPointerSize; | 840 kPointerSize; |
841 CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements)); | 841 CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements)); |
842 FixedArray* array = FixedArray::cast( | 842 FixedArray* array = FixedArray::cast( |
843 Heap::AllocateFixedArray(n_elements)); | 843 Heap::AllocateFixedArray(n_elements)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 InitializeVM(); | 881 InitializeVM(); |
882 | 882 |
883 // Increase the chance of 'bump-the-pointer' allocation in old space. | 883 // Increase the chance of 'bump-the-pointer' allocation in old space. |
884 bool force_compaction = true; | 884 bool force_compaction = true; |
885 Heap::CollectAllGarbage(force_compaction); | 885 Heap::CollectAllGarbage(force_compaction); |
886 | 886 |
887 v8::HandleScope scope; | 887 v8::HandleScope scope; |
888 | 888 |
889 // The plan: create JSObject which references objects in new space. | 889 // The plan: create JSObject which references objects in new space. |
890 // Then clone this object (forcing it to go into old space) and check | 890 // Then clone this object (forcing it to go into old space) and check |
891 // that region dirty marks are updated correctly. | 891 // that only bits pertaining to the object are updated in remembered set. |
892 | 892 |
893 // Step 1: prepare a map for the object. We add 1 inobject property to it. | 893 // Step 1: prepare a map for the object. We add 1 inobject property to it. |
894 Handle<JSFunction> object_ctor(Top::global_context()->object_function()); | 894 Handle<JSFunction> object_ctor(Top::global_context()->object_function()); |
895 CHECK(object_ctor->has_initial_map()); | 895 CHECK(object_ctor->has_initial_map()); |
896 Handle<Map> object_map(object_ctor->initial_map()); | 896 Handle<Map> object_map(object_ctor->initial_map()); |
897 // Create a map with single inobject property. | 897 // Create a map with single inobject property. |
898 Handle<Map> my_map = Factory::CopyMap(object_map, 1); | 898 Handle<Map> my_map = Factory::CopyMap(object_map, 1); |
899 int n_properties = my_map->inobject_properties(); | 899 int n_properties = my_map->inobject_properties(); |
900 CHECK_GT(n_properties, 0); | 900 CHECK_GT(n_properties, 0); |
901 | 901 |
(...skipping 22 matching lines...) Expand all Loading... |
924 | 924 |
925 CHECK(!Heap::always_allocate()); | 925 CHECK(!Heap::always_allocate()); |
926 Object* array = Heap::AllocateFixedArray(fixed_array_len); | 926 Object* array = Heap::AllocateFixedArray(fixed_array_len); |
927 CHECK(!array->IsFailure()); | 927 CHECK(!array->IsFailure()); |
928 CHECK(new_space->Contains(array)); | 928 CHECK(new_space->Contains(array)); |
929 | 929 |
930 Object* object = Heap::AllocateJSObjectFromMap(*my_map); | 930 Object* object = Heap::AllocateJSObjectFromMap(*my_map); |
931 CHECK(!object->IsFailure()); | 931 CHECK(!object->IsFailure()); |
932 CHECK(new_space->Contains(object)); | 932 CHECK(new_space->Contains(object)); |
933 JSObject* jsobject = JSObject::cast(object); | 933 JSObject* jsobject = JSObject::cast(object); |
934 CHECK_EQ(0, FixedArray::cast(jsobject->elements())->length()); | 934 CHECK_EQ(0, jsobject->elements()->length()); |
935 CHECK_EQ(0, jsobject->properties()->length()); | 935 CHECK_EQ(0, jsobject->properties()->length()); |
936 // Create a reference to object in new space in jsobject. | 936 // Create a reference to object in new space in jsobject. |
937 jsobject->FastPropertyAtPut(-1, array); | 937 jsobject->FastPropertyAtPut(-1, array); |
938 | 938 |
939 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); | 939 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr)); |
940 | 940 |
941 // Step 4: clone jsobject, but force always allocate first to create a clone | 941 // Step 4: clone jsobject, but force always allocate first to create a clone |
942 // in old pointer space. | 942 // in old pointer space. |
943 Address old_pointer_space_top = Heap::old_pointer_space()->top(); | 943 Address old_pointer_space_top = Heap::old_pointer_space()->top(); |
944 AlwaysAllocateScope aa_scope; | 944 AlwaysAllocateScope aa_scope; |
945 Object* clone_obj = Heap::CopyJSObject(jsobject); | 945 Object* clone_obj = Heap::CopyJSObject(jsobject); |
946 CHECK(!object->IsFailure()); | 946 CHECK(!object->IsFailure()); |
947 JSObject* clone = JSObject::cast(clone_obj); | 947 JSObject* clone = JSObject::cast(clone_obj); |
948 if (clone->address() != old_pointer_space_top) { | 948 if (clone->address() != old_pointer_space_top) { |
949 // Alas, got allocated from free list, we cannot do checks. | 949 // Alas, got allocated from free list, we cannot do checks. |
950 return; | 950 return; |
951 } | 951 } |
952 CHECK(Heap::old_pointer_space()->Contains(clone->address())); | 952 CHECK(Heap::old_pointer_space()->Contains(clone->address())); |
953 | 953 |
954 // Step 5: verify validity of region dirty marks. | 954 // Step 5: verify validity of remembered set. |
955 Address clone_addr = clone->address(); | 955 Address clone_addr = clone->address(); |
956 Page* page = Page::FromAddress(clone_addr); | 956 Page* page = Page::FromAddress(clone_addr); |
957 // Check that region covering inobject property 1 is marked dirty. | 957 // Check that remembered set tracks a reference from inobject property 1. |
958 CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize))); | 958 CHECK(page->IsRSetSet(clone_addr, object_size - kPointerSize)); |
| 959 // Probe several addresses after the object. |
| 960 for (int i = 0; i < 7; i++) { |
| 961 int offset = object_size + i * kPointerSize; |
| 962 if (clone_addr + offset >= page->ObjectAreaEnd()) { |
| 963 break; |
| 964 } |
| 965 CHECK(!page->IsRSetSet(clone_addr, offset)); |
| 966 } |
959 } | 967 } |
OLD | NEW |