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

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: 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
« runtime/vm/pages.h ('K') | « 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..82ea65df96e9498c0c29cb072bd8638e478c9b1d 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);
@@ -64,7 +71,9 @@ RawObject* HeapPage::FindObject(FindObjectVisitor* visitor) const {
}
-PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable)
+PageSpace::PageSpace(Heap* heap,
+ intptr_t max_capacity,
+ bool is_executable)
Ivan Posva 2012/05/29 23:27:37 ?
cshapiro 2012/05/30 17:56:24 More noise. Done.
: freelist_(),
heap_(heap),
pages_(NULL),
@@ -76,7 +85,12 @@ PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable)
in_use_(0),
count_(0),
is_executable_(is_executable),
- sweeping_(false) { }
+ sweeping_(false),
+ is_growth_controlled_(false),
+ page_space_controller_(FLAG_heap_growth_space_ratio,
+ FLAG_heap_growth_rate,
+ FLAG_heap_growth_time_ratio) {
+}
PageSpace::~PageSpace() {
@@ -187,7 +201,10 @@ uword PageSpace::TryAllocate(intptr_t size) {
result = TryBumpAllocate(size);
if (result == 0) {
result = freelist_.TryAllocate(size);
- if ((result == 0) && CanIncreaseCapacity(kPageSize)) {
+ if ((result == 0) &&
+ (is_growth_controlled_ != true ||
+ page_space_controller_.CanGrowPageSpace()) &&
+ CanIncreaseCapacity(kPageSize)) {
AllocatePage();
result = TryBumpAllocate(size);
ASSERT(result != 0);
@@ -288,6 +305,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_);
@@ -331,7 +349,10 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
}
// Record data and print if requested.
+ int64_t end = OS::GetCurrentTimeMillis();
Ivan Posva 2012/05/29 23:27:37 Why not use the timer object?
cshapiro 2012/05/30 17:56:24 Okay. The timer does not directly provide this da
intptr_t in_use_before = in_use_;
+ page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use,
+ start, end);
in_use_ = in_use;
timer.Stop();
@@ -357,4 +378,89 @@ 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() {
+ if (heap_growth_ratio_ == 100) {
Ivan Posva 2012/05/29 23:27:37 For debugging we might want to add a always_grow_t
cshapiro 2012/05/30 17:56:24 Or, I could suppress the enabling of the controlle
+ return true;
+ }
+ if (grow_heap_ == 0) {
Ivan Posva 2012/05/29 23:27:37 <= 0
cshapiro 2012/05/30 17:56:24 Done.
+ return false;
+ }
+ grow_heap_ -= 1;
+ 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
« runtime/vm/pages.h ('K') | « runtime/vm/pages.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698