| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/pages.h" | 5 #include "vm/pages.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/compiler_stats.h" | 8 #include "vm/compiler_stats.h" |
| 9 #include "vm/gc_marker.h" | 9 #include "vm/gc_marker.h" |
| 10 #include "vm/gc_sweeper.h" | 10 #include "vm/gc_sweeper.h" |
| (...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 NoHandleScope no_handles(isolate); | 649 NoHandleScope no_handles(isolate); |
| 650 | 650 |
| 651 if (FLAG_print_free_list_before_gc) { | 651 if (FLAG_print_free_list_before_gc) { |
| 652 OS::Print("Data Freelist (before GC):\n"); | 652 OS::Print("Data Freelist (before GC):\n"); |
| 653 freelist_[HeapPage::kData].Print(); | 653 freelist_[HeapPage::kData].Print(); |
| 654 OS::Print("Executable Freelist (before GC):\n"); | 654 OS::Print("Executable Freelist (before GC):\n"); |
| 655 freelist_[HeapPage::kExecutable].Print(); | 655 freelist_[HeapPage::kExecutable].Print(); |
| 656 } | 656 } |
| 657 | 657 |
| 658 if (FLAG_verify_before_gc) { | 658 if (FLAG_verify_before_gc) { |
| 659 OS::PrintErr("Verifying before MarkSweep..."); | 659 OS::PrintErr("Verifying before marking..."); |
| 660 heap_->Verify(); | 660 heap_->Verify(); |
| 661 OS::PrintErr(" done.\n"); | 661 OS::PrintErr(" done.\n"); |
| 662 } | 662 } |
| 663 | 663 |
| 664 const int64_t start = OS::GetCurrentTimeMicros(); | 664 const int64_t start = OS::GetCurrentTimeMicros(); |
| 665 | 665 |
| 666 // Make code pages writable. | 666 // Make code pages writable. |
| 667 WriteProtectCode(false); | 667 WriteProtectCode(false); |
| 668 | 668 |
| 669 // Save old value before GCMarker visits the weak persistent handles. | 669 // Save old value before GCMarker visits the weak persistent handles. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 682 bump_top_ = 0; | 682 bump_top_ = 0; |
| 683 bump_end_ = 0; | 683 bump_end_ = 0; |
| 684 // Reset the freelists and setup sweeping. | 684 // Reset the freelists and setup sweeping. |
| 685 freelist_[HeapPage::kData].Reset(); | 685 freelist_[HeapPage::kData].Reset(); |
| 686 freelist_[HeapPage::kExecutable].Reset(); | 686 freelist_[HeapPage::kExecutable].Reset(); |
| 687 | 687 |
| 688 int64_t mid2 = OS::GetCurrentTimeMicros(); | 688 int64_t mid2 = OS::GetCurrentTimeMicros(); |
| 689 int64_t mid3 = 0; | 689 int64_t mid3 = 0; |
| 690 | 690 |
| 691 { | 691 { |
| 692 if (FLAG_verify_before_gc) { |
| 693 OS::PrintErr("Verifying before sweeping..."); |
| 694 heap_->Verify(kAllowMarked); |
| 695 OS::PrintErr(" done.\n"); |
| 696 } |
| 692 GCSweeper sweeper; | 697 GCSweeper sweeper; |
| 693 | 698 |
| 694 // During stop-the-world phases we should use bulk lock when adding elements | 699 // During stop-the-world phases we should use bulk lock when adding elements |
| 695 // to the free list. | 700 // to the free list. |
| 696 MutexLocker mld(freelist_[HeapPage::kData].mutex()); | 701 MutexLocker mld(freelist_[HeapPage::kData].mutex()); |
| 697 MutexLocker mle(freelist_[HeapPage::kExecutable].mutex()); | 702 MutexLocker mle(freelist_[HeapPage::kExecutable].mutex()); |
| 698 | 703 |
| 699 // Large and executable pages are always swept immediately. | 704 // Large and executable pages are always swept immediately. |
| 700 HeapPage* prev_page = NULL; | 705 HeapPage* prev_page = NULL; |
| 701 HeapPage* page = large_pages_; | 706 HeapPage* page = large_pages_; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 HeapPage* next_page = page->next(); | 742 HeapPage* next_page = page->next(); |
| 738 bool page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); | 743 bool page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); |
| 739 if (page_in_use) { | 744 if (page_in_use) { |
| 740 prev_page = page; | 745 prev_page = page; |
| 741 } else { | 746 } else { |
| 742 FreePage(page, prev_page); | 747 FreePage(page, prev_page); |
| 743 } | 748 } |
| 744 // Advance to the next page. | 749 // Advance to the next page. |
| 745 page = next_page; | 750 page = next_page; |
| 746 } | 751 } |
| 752 if (FLAG_verify_after_gc) { |
| 753 OS::PrintErr("Verifying after sweeping..."); |
| 754 heap_->Verify(kForbidMarked); |
| 755 OS::PrintErr(" done.\n"); |
| 756 } |
| 747 } else { | 757 } else { |
| 748 // Start the concurrent sweeper task now. | 758 // Start the concurrent sweeper task now. |
| 749 GCSweeper::SweepConcurrent( | 759 GCSweeper::SweepConcurrent( |
| 750 isolate, pages_, pages_tail_, &freelist_[HeapPage::kData]); | 760 isolate, pages_, pages_tail_, &freelist_[HeapPage::kData]); |
| 751 } | 761 } |
| 752 } | 762 } |
| 753 | 763 |
| 754 // Make code pages read-only. | 764 // Make code pages read-only. |
| 755 WriteProtectCode(true); | 765 WriteProtectCode(true); |
| 756 | 766 |
| 757 int64_t end = OS::GetCurrentTimeMicros(); | 767 int64_t end = OS::GetCurrentTimeMicros(); |
| 758 | 768 |
| 759 // Record signals for growth control. Include size of external allocations. | 769 // Record signals for growth control. Include size of external allocations. |
| 760 page_space_controller_.EvaluateGarbageCollection(usage_before, usage_, | 770 page_space_controller_.EvaluateGarbageCollection(usage_before, usage_, |
| 761 start, end); | 771 start, end); |
| 762 | 772 |
| 763 heap_->RecordTime(kMarkObjects, mid1 - start); | 773 heap_->RecordTime(kMarkObjects, mid1 - start); |
| 764 heap_->RecordTime(kResetFreeLists, mid2 - mid1); | 774 heap_->RecordTime(kResetFreeLists, mid2 - mid1); |
| 765 heap_->RecordTime(kSweepPages, mid3 - mid2); | 775 heap_->RecordTime(kSweepPages, mid3 - mid2); |
| 766 heap_->RecordTime(kSweepLargePages, end - mid3); | 776 heap_->RecordTime(kSweepLargePages, end - mid3); |
| 767 | 777 |
| 768 if (FLAG_print_free_list_after_gc) { | 778 if (FLAG_print_free_list_after_gc) { |
| 769 OS::Print("Data Freelist (after GC):\n"); | 779 OS::Print("Data Freelist (after GC):\n"); |
| 770 freelist_[HeapPage::kData].Print(); | 780 freelist_[HeapPage::kData].Print(); |
| 771 OS::Print("Executable Freelist (after GC):\n"); | 781 OS::Print("Executable Freelist (after GC):\n"); |
| 772 freelist_[HeapPage::kExecutable].Print(); | 782 freelist_[HeapPage::kExecutable].Print(); |
| 773 } | 783 } |
| 774 | 784 |
| 775 if (FLAG_verify_after_gc) { | |
| 776 OS::PrintErr("Verifying after MarkSweep..."); | |
| 777 heap_->Verify(FLAG_concurrent_sweep ? kAllowMarked : kForbidMarked); | |
| 778 OS::PrintErr(" done.\n"); | |
| 779 } | |
| 780 | |
| 781 // Done, reset the task count. | 785 // Done, reset the task count. |
| 782 { | 786 { |
| 783 MonitorLocker ml(tasks_lock()); | 787 MonitorLocker ml(tasks_lock()); |
| 784 set_tasks(tasks() - 1); | 788 set_tasks(tasks() - 1); |
| 785 ml.Notify(); | 789 ml.Notify(); |
| 786 } | 790 } |
| 787 } | 791 } |
| 788 | 792 |
| 789 | 793 |
| 790 uword PageSpace::TryAllocateDataBumpInternal(intptr_t size, | 794 uword PageSpace::TryAllocateDataBumpInternal(intptr_t size, |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 return 0; | 996 return 0; |
| 993 } else { | 997 } else { |
| 994 ASSERT(total_time >= gc_time); | 998 ASSERT(total_time >= gc_time); |
| 995 int result= static_cast<int>((static_cast<double>(gc_time) / | 999 int result= static_cast<int>((static_cast<double>(gc_time) / |
| 996 static_cast<double>(total_time)) * 100); | 1000 static_cast<double>(total_time)) * 100); |
| 997 return result; | 1001 return result; |
| 998 } | 1002 } |
| 999 } | 1003 } |
| 1000 | 1004 |
| 1001 } // namespace dart | 1005 } // namespace dart |
| OLD | NEW |