OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 #include "src/base/platform/platform.h" | 30 #include "src/base/platform/platform.h" |
31 #include "src/heap/spaces-inl.h" | 31 #include "src/heap/spaces-inl.h" |
32 // FIXME(mstarzinger, marja): This is weird, but required because of the missing | 32 // FIXME(mstarzinger, marja): This is weird, but required because of the missing |
33 // (disallowed) include: src/heap/incremental-marking.h -> src/objects-inl.h | 33 // (disallowed) include: src/heap/incremental-marking.h -> src/objects-inl.h |
34 #include "src/objects-inl.h" | 34 #include "src/objects-inl.h" |
35 #include "src/snapshot/snapshot.h" | 35 #include "src/snapshot/snapshot.h" |
36 #include "src/v8.h" | 36 #include "src/v8.h" |
37 #include "test/cctest/cctest.h" | 37 #include "test/cctest/cctest.h" |
38 #include "test/cctest/heap/heap-tester.h" | 38 #include "test/cctest/heap/heap-tester.h" |
| 39 #include "test/cctest/heap/heap-utils.h" |
39 | 40 |
40 namespace v8 { | 41 namespace v8 { |
41 namespace internal { | 42 namespace internal { |
42 | 43 |
43 #if 0 | 44 #if 0 |
44 static void VerifyRegionMarking(Address page_start) { | 45 static void VerifyRegionMarking(Address page_start) { |
45 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER | 46 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER |
46 Page* p = Page::FromAddress(page_start); | 47 Page* p = Page::FromAddress(page_start); |
47 | 48 |
48 p->SetRegionMarks(Page::kAllRegionsCleanMarks); | 49 p->SetRegionMarks(Page::kAllRegionsCleanMarks); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 // The available value is conservative such that it may report | 476 // The available value is conservative such that it may report |
476 // zero prior to heap exhaustion. | 477 // zero prior to heap exhaustion. |
477 CHECK(lo->Available() < available || available == 0); | 478 CHECK(lo->Available() < available || available == 0); |
478 } | 479 } |
479 | 480 |
480 CHECK(!lo->IsEmpty()); | 481 CHECK(!lo->IsEmpty()); |
481 | 482 |
482 CHECK(lo->AllocateRaw(lo_size, NOT_EXECUTABLE).IsRetry()); | 483 CHECK(lo->AllocateRaw(lo_size, NOT_EXECUTABLE).IsRetry()); |
483 } | 484 } |
484 | 485 |
485 | 486 TEST(SizeOfInitialHeap) { |
486 TEST(SizeOfFirstPageIsLargeEnough) { | |
487 if (i::FLAG_always_opt) return; | 487 if (i::FLAG_always_opt) return; |
488 // Bootstrapping without a snapshot causes more allocations. | 488 // Bootstrapping without a snapshot causes more allocations. |
489 CcTest::InitializeVM(); | 489 CcTest::InitializeVM(); |
490 Isolate* isolate = CcTest::i_isolate(); | 490 Isolate* isolate = CcTest::i_isolate(); |
491 if (!isolate->snapshot_available()) return; | 491 if (!isolate->snapshot_available()) return; |
492 HandleScope scope(isolate); | 492 HandleScope scope(isolate); |
493 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); | 493 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
494 // Skip this test on the custom snapshot builder. | 494 // Skip this test on the custom snapshot builder. |
495 if (!CcTest::global() | 495 if (!CcTest::global() |
496 ->Get(context, v8_str("assertEquals")) | 496 ->Get(context, v8_str("assertEquals")) |
497 .ToLocalChecked() | 497 .ToLocalChecked() |
498 ->IsUndefined()) { | 498 ->IsUndefined()) { |
499 return; | 499 return; |
500 } | 500 } |
501 | 501 |
502 // If this test fails due to enabling experimental natives that are not part | 502 // The limit for each space for an empty isolate containing just the |
503 // of the snapshot, we may need to adjust CalculateFirstPageSizes. | 503 // snapshot. |
| 504 const size_t kMaxInitialSizePerSpace = 2 * MB; |
504 | 505 |
505 // Freshly initialized VM gets by with one page per space. | 506 // Freshly initialized VM gets by with the snapshot size (which is below |
| 507 // kMaxInitialSizePerSpace per space). |
| 508 Heap* heap = isolate->heap(); |
| 509 int page_count[LAST_PAGED_SPACE + 1] = {0, 0, 0, 0}; |
506 for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { | 510 for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { |
507 // Debug code can be very large, so skip CODE_SPACE if we are generating it. | 511 // Debug code can be very large, so skip CODE_SPACE if we are generating it. |
508 if (i == CODE_SPACE && i::FLAG_debug_code) continue; | 512 if (i == CODE_SPACE && i::FLAG_debug_code) continue; |
509 CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages()); | 513 |
| 514 page_count[i] = heap->paged_space(i)->CountTotalPages(); |
| 515 // Check that the initial heap is also below the limit. |
| 516 CHECK_LT(static_cast<size_t>(heap->paged_space(i)->CommittedMemory()), |
| 517 kMaxInitialSizePerSpace); |
510 } | 518 } |
511 | 519 |
512 // Executing the empty script gets by with one page per space. | 520 // Executing the empty script gets by with the same number of pages, i.e., |
| 521 // requires no extra space. |
513 CompileRun("/*empty*/"); | 522 CompileRun("/*empty*/"); |
514 for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { | 523 for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) { |
515 // Debug code can be very large, so skip CODE_SPACE if we are generating it. | 524 // Debug code can be very large, so skip CODE_SPACE if we are generating it. |
516 if (i == CODE_SPACE && i::FLAG_debug_code) continue; | 525 if (i == CODE_SPACE && i::FLAG_debug_code) continue; |
517 CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages()); | 526 CHECK_EQ(page_count[i], isolate->heap()->paged_space(i)->CountTotalPages()); |
518 } | 527 } |
519 | 528 |
520 // No large objects required to perform the above steps. | 529 // No large objects required to perform the above steps. |
521 CHECK(isolate->heap()->lo_space()->IsEmpty()); | 530 CHECK(isolate->heap()->lo_space()->IsEmpty()); |
522 } | 531 } |
523 | 532 |
524 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { | 533 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { |
525 AllocationResult allocation = space->AllocateRawUnaligned(size); | 534 AllocationResult allocation = space->AllocateRawUnaligned(size); |
526 CHECK(!allocation.IsRetry()); | 535 CHECK(!allocation.IsRetry()); |
527 HeapObject* filler = NULL; | 536 HeapObject* filler = NULL; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 | 687 |
679 new_space->RemoveAllocationObserver(&observer1); | 688 new_space->RemoveAllocationObserver(&observer1); |
680 new_space->RemoveAllocationObserver(&observer2); | 689 new_space->RemoveAllocationObserver(&observer2); |
681 | 690 |
682 CHECK_EQ(observer1.count(), 32); | 691 CHECK_EQ(observer1.count(), 32); |
683 CHECK_EQ(observer2.count(), 28); | 692 CHECK_EQ(observer2.count(), 28); |
684 } | 693 } |
685 isolate->Dispose(); | 694 isolate->Dispose(); |
686 } | 695 } |
687 | 696 |
| 697 TEST(ShrinkPageToHighWaterMarkFreeSpaceEnd) { |
| 698 CcTest::InitializeVM(); |
| 699 Isolate* isolate = CcTest::i_isolate(); |
| 700 HandleScope scope(isolate); |
| 701 |
| 702 heap::SealCurrentObjects(CcTest::heap()); |
| 703 |
| 704 // Prepare page that only contains a single object and a trailing FreeSpace |
| 705 // filler. |
| 706 Handle<FixedArray> array = isolate->factory()->NewFixedArray(128, TENURED); |
| 707 Page* page = Page::FromAddress(array->address()); |
| 708 |
| 709 // Reset space so high water mark is consistent. |
| 710 CcTest::heap()->old_space()->ResetFreeList(); |
| 711 CcTest::heap()->old_space()->EmptyAllocationInfo(); |
| 712 |
| 713 HeapObject* filler = |
| 714 HeapObject::FromAddress(array->address() + array->Size()); |
| 715 CHECK(filler->IsFreeSpace()); |
| 716 size_t shrinked = page->ShrinkToHighWaterMark(); |
| 717 size_t should_have_shrinked = |
| 718 RoundDown(static_cast<size_t>(Page::kAllocatableMemory - array->Size()), |
| 719 base::OS::CommitPageSize()); |
| 720 CHECK_EQ(should_have_shrinked, shrinked); |
| 721 } |
| 722 |
| 723 TEST(ShrinkPageToHighWaterMarkNoFiller) { |
| 724 CcTest::InitializeVM(); |
| 725 Isolate* isolate = CcTest::i_isolate(); |
| 726 HandleScope scope(isolate); |
| 727 heap::SealCurrentObjects(CcTest::heap()); |
| 728 |
| 729 const int kFillerSize = 0; |
| 730 std::vector<Handle<FixedArray>> arrays = |
| 731 heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize); |
| 732 Handle<FixedArray> array = arrays.back(); |
| 733 Page* page = Page::FromAddress(array->address()); |
| 734 CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize); |
| 735 |
| 736 // Reset space so high water mark and fillers are consistent. |
| 737 CcTest::heap()->old_space()->ResetFreeList(); |
| 738 CcTest::heap()->old_space()->EmptyAllocationInfo(); |
| 739 |
| 740 const size_t shrinked = page->ShrinkToHighWaterMark(); |
| 741 CHECK_EQ(0, shrinked); |
| 742 } |
| 743 |
| 744 TEST(ShrinkPageToHighWaterMarkOneWordFiller) { |
| 745 CcTest::InitializeVM(); |
| 746 Isolate* isolate = CcTest::i_isolate(); |
| 747 HandleScope scope(isolate); |
| 748 |
| 749 heap::SealCurrentObjects(CcTest::heap()); |
| 750 |
| 751 const int kFillerSize = kPointerSize; |
| 752 std::vector<Handle<FixedArray>> arrays = |
| 753 heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize); |
| 754 Handle<FixedArray> array = arrays.back(); |
| 755 Page* page = Page::FromAddress(array->address()); |
| 756 CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize); |
| 757 |
| 758 // Reset space so high water mark and fillers are consistent. |
| 759 CcTest::heap()->old_space()->ResetFreeList(); |
| 760 CcTest::heap()->old_space()->EmptyAllocationInfo(); |
| 761 |
| 762 HeapObject* filler = |
| 763 HeapObject::FromAddress(array->address() + array->Size()); |
| 764 CHECK_EQ(filler->map(), CcTest::heap()->one_pointer_filler_map()); |
| 765 |
| 766 const size_t shrinked = page->ShrinkToHighWaterMark(); |
| 767 CHECK_EQ(0, shrinked); |
| 768 } |
| 769 |
| 770 TEST(ShrinkPageToHighWaterMarkTwoWordFiller) { |
| 771 CcTest::InitializeVM(); |
| 772 Isolate* isolate = CcTest::i_isolate(); |
| 773 HandleScope scope(isolate); |
| 774 |
| 775 heap::SealCurrentObjects(CcTest::heap()); |
| 776 |
| 777 const int kFillerSize = 2 * kPointerSize; |
| 778 std::vector<Handle<FixedArray>> arrays = |
| 779 heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize); |
| 780 Handle<FixedArray> array = arrays.back(); |
| 781 Page* page = Page::FromAddress(array->address()); |
| 782 CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize); |
| 783 |
| 784 // Reset space so high water mark and fillers are consistent. |
| 785 CcTest::heap()->old_space()->ResetFreeList(); |
| 786 CcTest::heap()->old_space()->EmptyAllocationInfo(); |
| 787 |
| 788 HeapObject* filler = |
| 789 HeapObject::FromAddress(array->address() + array->Size()); |
| 790 CHECK_EQ(filler->map(), CcTest::heap()->two_pointer_filler_map()); |
| 791 |
| 792 const size_t shrinked = page->ShrinkToHighWaterMark(); |
| 793 CHECK_EQ(0, shrinked); |
| 794 } |
| 795 |
688 } // namespace internal | 796 } // namespace internal |
689 } // namespace v8 | 797 } // namespace v8 |
OLD | NEW |