| 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 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 HeapMapAsJSONVisitor printer(&page_map); | 769 HeapMapAsJSONVisitor printer(&page_map); |
| 770 page->VisitObjects(&printer); | 770 page->VisitObjects(&printer); |
| 771 } | 771 } |
| 772 } | 772 } |
| 773 } | 773 } |
| 774 #endif // PRODUCT | 774 #endif // PRODUCT |
| 775 | 775 |
| 776 | 776 |
| 777 bool PageSpace::ShouldCollectCode() { | 777 bool PageSpace::ShouldCollectCode() { |
| 778 // Try to collect code if enough time has passed since the last attempt. | 778 // Try to collect code if enough time has passed since the last attempt. |
| 779 const int64_t start = OS::GetCurrentTimeMicros(); | 779 const int64_t start = OS::GetCurrentMonotonicMicros(); |
| 780 const int64_t last_code_collection_in_us = | 780 const int64_t last_code_collection_in_us = |
| 781 page_space_controller_.last_code_collection_in_us(); | 781 page_space_controller_.last_code_collection_in_us(); |
| 782 | 782 |
| 783 if ((start - last_code_collection_in_us) > | 783 if ((start - last_code_collection_in_us) > |
| 784 FLAG_code_collection_interval_in_us) { | 784 FLAG_code_collection_interval_in_us) { |
| 785 if (FLAG_log_code_drop) { | 785 if (FLAG_log_code_drop) { |
| 786 OS::Print("Trying to detach code.\n"); | 786 OS::Print("Trying to detach code.\n"); |
| 787 } | 787 } |
| 788 page_space_controller_.set_last_code_collection_in_us(start); | 788 page_space_controller_.set_last_code_collection_in_us(start); |
| 789 return true; | 789 return true; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 OS::Print("Executable Freelist (before GC):\n"); | 845 OS::Print("Executable Freelist (before GC):\n"); |
| 846 freelist_[HeapPage::kExecutable].Print(); | 846 freelist_[HeapPage::kExecutable].Print(); |
| 847 } | 847 } |
| 848 | 848 |
| 849 if (FLAG_verify_before_gc) { | 849 if (FLAG_verify_before_gc) { |
| 850 OS::PrintErr("Verifying before marking..."); | 850 OS::PrintErr("Verifying before marking..."); |
| 851 heap_->VerifyGC(); | 851 heap_->VerifyGC(); |
| 852 OS::PrintErr(" done.\n"); | 852 OS::PrintErr(" done.\n"); |
| 853 } | 853 } |
| 854 | 854 |
| 855 const int64_t start = OS::GetCurrentTimeMicros(); | 855 const int64_t start = OS::GetCurrentMonotonicMicros(); |
| 856 | 856 |
| 857 // Make code pages writable. | 857 // Make code pages writable. |
| 858 WriteProtectCode(false); | 858 WriteProtectCode(false); |
| 859 | 859 |
| 860 // Save old value before GCMarker visits the weak persistent handles. | 860 // Save old value before GCMarker visits the weak persistent handles. |
| 861 SpaceUsage usage_before = GetCurrentUsage(); | 861 SpaceUsage usage_before = GetCurrentUsage(); |
| 862 | 862 |
| 863 // Mark all reachable old-gen objects. | 863 // Mark all reachable old-gen objects. |
| 864 bool collect_code = FLAG_collect_code && ShouldCollectCode() && | 864 bool collect_code = FLAG_collect_code && ShouldCollectCode() && |
| 865 !isolate->HasAttemptedReload(); | 865 !isolate->HasAttemptedReload(); |
| 866 GCMarker marker(heap_); | 866 GCMarker marker(heap_); |
| 867 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code); | 867 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code); |
| 868 usage_.used_in_words = marker.marked_words(); | 868 usage_.used_in_words = marker.marked_words(); |
| 869 | 869 |
| 870 int64_t mid1 = OS::GetCurrentTimeMicros(); | 870 int64_t mid1 = OS::GetCurrentMonotonicMicros(); |
| 871 | 871 |
| 872 // Abandon the remainder of the bump allocation block. | 872 // Abandon the remainder of the bump allocation block. |
| 873 AbandonBumpAllocation(); | 873 AbandonBumpAllocation(); |
| 874 // Reset the freelists and setup sweeping. | 874 // Reset the freelists and setup sweeping. |
| 875 freelist_[HeapPage::kData].Reset(); | 875 freelist_[HeapPage::kData].Reset(); |
| 876 freelist_[HeapPage::kExecutable].Reset(); | 876 freelist_[HeapPage::kExecutable].Reset(); |
| 877 | 877 |
| 878 int64_t mid2 = OS::GetCurrentTimeMicros(); | 878 int64_t mid2 = OS::GetCurrentMonotonicMicros(); |
| 879 int64_t mid3 = 0; | 879 int64_t mid3 = 0; |
| 880 | 880 |
| 881 { | 881 { |
| 882 if (FLAG_verify_before_gc) { | 882 if (FLAG_verify_before_gc) { |
| 883 OS::PrintErr("Verifying before sweeping..."); | 883 OS::PrintErr("Verifying before sweeping..."); |
| 884 heap_->VerifyGC(kAllowMarked); | 884 heap_->VerifyGC(kAllowMarked); |
| 885 OS::PrintErr(" done.\n"); | 885 OS::PrintErr(" done.\n"); |
| 886 } | 886 } |
| 887 GCSweeper sweeper; | 887 GCSweeper sweeper; |
| 888 | 888 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 915 bool page_in_use = sweeper.SweepPage(page, freelist, true); | 915 bool page_in_use = sweeper.SweepPage(page, freelist, true); |
| 916 if (page_in_use) { | 916 if (page_in_use) { |
| 917 prev_page = page; | 917 prev_page = page; |
| 918 } else { | 918 } else { |
| 919 FreePage(page, prev_page); | 919 FreePage(page, prev_page); |
| 920 } | 920 } |
| 921 // Advance to the next page. | 921 // Advance to the next page. |
| 922 page = next_page; | 922 page = next_page; |
| 923 } | 923 } |
| 924 | 924 |
| 925 mid3 = OS::GetCurrentTimeMicros(); | 925 mid3 = OS::GetCurrentMonotonicMicros(); |
| 926 | 926 |
| 927 if (!FLAG_concurrent_sweep) { | 927 if (!FLAG_concurrent_sweep) { |
| 928 // Sweep all regular sized pages now. | 928 // Sweep all regular sized pages now. |
| 929 prev_page = NULL; | 929 prev_page = NULL; |
| 930 page = pages_; | 930 page = pages_; |
| 931 while (page != NULL) { | 931 while (page != NULL) { |
| 932 HeapPage* next_page = page->next(); | 932 HeapPage* next_page = page->next(); |
| 933 bool page_in_use = | 933 bool page_in_use = |
| 934 sweeper.SweepPage(page, &freelist_[page->type()], true); | 934 sweeper.SweepPage(page, &freelist_[page->type()], true); |
| 935 if (page_in_use) { | 935 if (page_in_use) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 948 } else { | 948 } else { |
| 949 // Start the concurrent sweeper task now. | 949 // Start the concurrent sweeper task now. |
| 950 GCSweeper::SweepConcurrent(isolate, pages_, pages_tail_, | 950 GCSweeper::SweepConcurrent(isolate, pages_, pages_tail_, |
| 951 &freelist_[HeapPage::kData]); | 951 &freelist_[HeapPage::kData]); |
| 952 } | 952 } |
| 953 } | 953 } |
| 954 | 954 |
| 955 // Make code pages read-only. | 955 // Make code pages read-only. |
| 956 WriteProtectCode(true); | 956 WriteProtectCode(true); |
| 957 | 957 |
| 958 int64_t end = OS::GetCurrentTimeMicros(); | 958 int64_t end = OS::GetCurrentMonotonicMicros(); |
| 959 | 959 |
| 960 // Record signals for growth control. Include size of external allocations. | 960 // Record signals for growth control. Include size of external allocations. |
| 961 page_space_controller_.EvaluateGarbageCollection( | 961 page_space_controller_.EvaluateGarbageCollection( |
| 962 usage_before, GetCurrentUsage(), start, end); | 962 usage_before, GetCurrentUsage(), start, end); |
| 963 | 963 |
| 964 heap_->RecordTime(kMarkObjects, mid1 - start); | 964 heap_->RecordTime(kMarkObjects, mid1 - start); |
| 965 heap_->RecordTime(kResetFreeLists, mid2 - mid1); | 965 heap_->RecordTime(kResetFreeLists, mid2 - mid1); |
| 966 heap_->RecordTime(kSweepPages, mid3 - mid2); | 966 heap_->RecordTime(kSweepPages, mid3 - mid2); |
| 967 heap_->RecordTime(kSweepLargePages, end - mid3); | 967 heap_->RecordTime(kSweepLargePages, end - mid3); |
| 968 | 968 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 int heap_growth_ratio, | 1110 int heap_growth_ratio, |
| 1111 int heap_growth_max, | 1111 int heap_growth_max, |
| 1112 int garbage_collection_time_ratio) | 1112 int garbage_collection_time_ratio) |
| 1113 : heap_(heap), | 1113 : heap_(heap), |
| 1114 is_enabled_(false), | 1114 is_enabled_(false), |
| 1115 grow_heap_(heap_growth_max / 2), | 1115 grow_heap_(heap_growth_max / 2), |
| 1116 heap_growth_ratio_(heap_growth_ratio), | 1116 heap_growth_ratio_(heap_growth_ratio), |
| 1117 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), | 1117 desired_utilization_((100.0 - heap_growth_ratio) / 100.0), |
| 1118 heap_growth_max_(heap_growth_max), | 1118 heap_growth_max_(heap_growth_max), |
| 1119 garbage_collection_time_ratio_(garbage_collection_time_ratio), | 1119 garbage_collection_time_ratio_(garbage_collection_time_ratio), |
| 1120 last_code_collection_in_us_(OS::GetCurrentTimeMicros()) {} | 1120 last_code_collection_in_us_(OS::GetCurrentMonotonicMicros()) {} |
| 1121 | 1121 |
| 1122 | 1122 |
| 1123 PageSpaceController::~PageSpaceController() {} | 1123 PageSpaceController::~PageSpaceController() {} |
| 1124 | 1124 |
| 1125 | 1125 |
| 1126 bool PageSpaceController::NeedsGarbageCollection(SpaceUsage after) const { | 1126 bool PageSpaceController::NeedsGarbageCollection(SpaceUsage after) const { |
| 1127 if (!is_enabled_) { | 1127 if (!is_enabled_) { |
| 1128 return false; | 1128 return false; |
| 1129 } | 1129 } |
| 1130 if (heap_growth_ratio_ == 100) { | 1130 if (heap_growth_ratio_ == 100) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 return 0; | 1261 return 0; |
| 1262 } else { | 1262 } else { |
| 1263 ASSERT(total_time >= gc_time); | 1263 ASSERT(total_time >= gc_time); |
| 1264 int result = static_cast<int>( | 1264 int result = static_cast<int>( |
| 1265 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); | 1265 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); |
| 1266 return result; | 1266 return result; |
| 1267 } | 1267 } |
| 1268 } | 1268 } |
| 1269 | 1269 |
| 1270 } // namespace dart | 1270 } // namespace dart |
| OLD | NEW |