Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: runtime/vm/pages.cc

Issue 10442073: Implement growth policy for old space using time and space signals. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address review comments Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/pages.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/pages.cc
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 9194db706929bba0878cf8cb99152001e32b1dba..877397a284e1babce05cd06e09c923df38a91b8e 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -12,6 +12,13 @@
namespace dart {
+DEFINE_FLAG(int, heap_growth_space_ratio, 10,
+ "The desired maximum percentage of free space after GC");
+DEFINE_FLAG(int, heap_growth_time_ratio, 3,
+ "The desired maximum percentage of time spent in GC");
+DEFINE_FLAG(int, heap_growth_rate, 4,
+ "The size the heap is grown, in heap pages");
+
HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) {
ASSERT(memory->size() > VirtualMemory::PageSize());
memory->Commit(is_executable);
@@ -76,7 +83,11 @@ PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable)
in_use_(0),
count_(0),
is_executable_(is_executable),
- sweeping_(false) { }
+ sweeping_(false),
+ page_space_controller_(FLAG_heap_growth_space_ratio,
+ FLAG_heap_growth_rate,
+ FLAG_heap_growth_time_ratio) {
+}
PageSpace::~PageSpace() {
@@ -187,7 +198,9 @@ uword PageSpace::TryAllocate(intptr_t size) {
result = TryBumpAllocate(size);
if (result == 0) {
result = freelist_.TryAllocate(size);
- if ((result == 0) && CanIncreaseCapacity(kPageSize)) {
+ if ((result == 0) &&
+ page_space_controller_.CanGrowPageSpace(kPageSize) &&
Ivan Posva 2012/05/30 20:21:24 Number of pages or byte size?
cshapiro 2012/05/30 23:39:54 Byte size. Done.
+ CanIncreaseCapacity(kPageSize)) {
AllocatePage();
result = TryBumpAllocate(size);
ASSERT(result != 0);
@@ -288,6 +301,7 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
Timer timer(FLAG_verbose_gc, "MarkSweep");
timer.Start();
+ int64_t start = OS::GetCurrentTimeMillis();
// Mark all reachable old-gen objects.
GCMarker marker(heap_);
@@ -335,6 +349,12 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
in_use_ = in_use;
timer.Stop();
+
+ // Record signals for growth control.
+ int64_t elapsed = timer.TotalElapsedTime() * kMicrosecondsPerMillisecond;
Ivan Posva 2012/05/30 20:21:24 As discussed this will only work if --verbose_gc i
cshapiro 2012/05/30 23:39:54 Made unconditional. Done.
+ page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use,
+ start, start + elapsed);
+
if (FLAG_verbose_gc) {
const intptr_t KB2 = KB / 2;
OS::PrintErr("Mark-Sweep[%d]: %lldus (%dK -> %dK, %dK)\n",
@@ -357,4 +377,92 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
sweeping_ = false;
}
+
+PageSpaceController::PageSpaceController(int heap_growth_ratio,
+ int heap_growth_rate,
+ int garbage_collection_time_ratio)
+ : grow_heap_(heap_growth_rate),
+ heap_growth_ratio_(heap_growth_ratio),
+ heap_growth_rate_(heap_growth_rate),
+ garbage_collection_time_ratio_(garbage_collection_time_ratio) {
+}
+
+
+PageSpaceController::~PageSpaceController() {}
+
+
+bool PageSpaceController::CanGrowPageSpace(intptr_t num_pages) {
Ivan Posva 2012/05/30 20:21:24 num_pages or byte size?
cshapiro 2012/05/30 23:39:54 Done.
+ if (is_disabled_) {
+ return true;
+ }
+ if (heap_growth_ratio_ == 100) {
+ return true;
+ }
+ if (grow_heap_ <= 0) {
+ return false;
+ }
+ grow_heap_ -= num_pages;
+ return true;
+}
+
+
+void PageSpaceController::EvaluateGarbageCollection(
+ size_t in_use_before, size_t in_use_after, int64_t start, int64_t end) {
+ ASSERT(in_use_before >= in_use_after);
+ ASSERT(end >= start);
+ history_.AddGarbageCollectionTime(start, end);
+ int collected_garbage_ratio =
+ static_cast<int>((static_cast<double>(in_use_before - in_use_after) /
+ static_cast<double>(in_use_before)) * 100);
+ if ((collected_garbage_ratio > heap_growth_ratio_) &&
+ (history_.GarbageCollectionTimeFraction() <
+ garbage_collection_time_ratio_)) {
+ grow_heap_ = 0;
+ } else {
+ grow_heap_ = heap_growth_rate_;
+ }
+}
+
+
+PageSpaceGarbageCollectionHistory::PageSpaceGarbageCollectionHistory()
+ : index_(0) {
+ for (uint32_t i = 0; i < kHistoryLength; i++) {
+ start_[i] = 0;
+ end_[i] = 0;
+ }
+}
+
+
+void PageSpaceGarbageCollectionHistory::
+ AddGarbageCollectionTime(uint64_t start, uint64_t end) {
+ int index = index_ % kHistoryLength;
+ start_[index] = start;
+ end_[index] = end;
+ index_++;
+}
+
+
+int PageSpaceGarbageCollectionHistory::GarbageCollectionTimeFraction() {
+ int current;
+ int previous;
+ uint64_t gc_time = 0;
+ uint64_t total_time = 0;
+ for (uint32_t i = 1; i < kHistoryLength; i++) {
+ current = (index_ - i) % kHistoryLength;
+ previous = (index_ - 1 - i) % kHistoryLength;
+ if (end_[previous] == 0) {
+ break;
+ }
+ // iterate over the circular buffer in reverse order
+ gc_time += end_[current] - start_[current];
+ total_time += end_[current] - end_[previous];
+ }
+ if (total_time == 0) {
+ return 0;
+ } else {
+ return static_cast<int>((static_cast<double>(gc_time) /
+ static_cast<double>(total_time))*100);
+ }
+}
+
} // namespace dart
« no previous file with comments | « runtime/vm/pages.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698