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

Unified Diff: runtime/vm/scavenger.cc

Issue 329163003: Grow new gen (1M -> 4M -> 16M on 32-bit) when there is little garbage. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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/scavenger.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/scavenger.cc
===================================================================
--- runtime/vm/scavenger.cc (revision 37279)
+++ runtime/vm/scavenger.cc (working copy)
@@ -25,6 +25,9 @@
DEFINE_FLAG(int, early_tenuring_threshold, 66,
"When more than this percentage of promotion candidates survive, "
"promote all survivors of next scavenge.");
+DEFINE_FLAG(int, new_gen_garbage_threshold, 90,
+ "Grow new gen when less than this percentage is garbage.");
+DEFINE_FLAG(int, new_gen_growth_factor, 4, "Grow new gen by this factor.");
// Scavenger uses RawObject::kMarkBit to distinguish forwaded and non-forwarded
// objects. The kMarkBit does not intersect with the target address because of
@@ -318,7 +321,7 @@
SemiSpace::~SemiSpace() {
if (reserved_ != NULL) {
#if defined(DEBUG)
- memset(reserved_->address(), 0xf3, size());
+ memset(reserved_->address(), 0xf3, size_in_words() << kWordSizeLog2);
#endif // defined(DEBUG)
delete reserved_;
}
@@ -336,26 +339,28 @@
}
-SemiSpace* SemiSpace::New(intptr_t size) {
+SemiSpace* SemiSpace::New(intptr_t size_in_words) {
{
MutexLocker locker(mutex_);
- if (cache_ != NULL && cache_->size() == size) {
+ // TODO(koda): Cache one entry per size.
+ if (cache_ != NULL && cache_->size_in_words() == size_in_words) {
SemiSpace* result = cache_;
cache_ = NULL;
return result;
}
}
- if (size == 0) {
+ if (size_in_words == 0) {
return new SemiSpace(NULL);
} else {
- VirtualMemory* reserved = VirtualMemory::Reserve(size);
+ intptr_t size_in_bytes = size_in_words << kWordSizeLog2;
+ VirtualMemory* reserved = VirtualMemory::Reserve(size_in_bytes);
if ((reserved == NULL) || !reserved->Commit(VirtualMemory::kReadWrite)) {
// TODO(koda): If cache_ is not empty, we could try to delete it.
delete reserved;
return NULL;
}
#if defined(DEBUG)
- memset(reserved->address(), 0xf3, size);
+ memset(reserved->address(), 0xf3, size_in_bytes);
#endif // defined(DEBUG)
return new SemiSpace(reserved);
}
@@ -383,9 +388,10 @@
Scavenger::Scavenger(Heap* heap,
- intptr_t max_capacity_in_words,
+ intptr_t max_semi_capacity_in_words,
uword object_alignment)
: heap_(heap),
+ max_semi_capacity_in_words_(max_semi_capacity_in_words),
object_alignment_(object_alignment),
scavenging_(false),
gc_time_micros_(0),
@@ -395,8 +401,10 @@
// going to use for forwarding pointers.
ASSERT(Object::tags_offset() == 0);
- const intptr_t semi_space_size = (max_capacity_in_words / 2) * kWordSize;
- to_ = SemiSpace::New(semi_space_size);
+ // Set initial size resulting in a total of three different levels.
+ const intptr_t initial_semi_capacity_in_words = max_semi_capacity_in_words /
+ (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
+ to_ = SemiSpace::New(initial_semi_capacity_in_words);
if (to_ == NULL) {
FATAL("Out of memory.\n");
}
@@ -418,6 +426,20 @@
}
+intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
+ if (stats_history_.Size() == 0) {
+ return old_size_in_words;
+ }
+ double garbage = stats_history_.Get(0).GarbageFraction();
+ if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) {
+ return Utils::Minimum(max_semi_capacity_in_words_,
+ old_size_in_words * FLAG_new_gen_growth_factor);
+ } else {
+ return old_size_in_words;
+ }
+}
+
+
void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) {
if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
(isolate->gc_prologue_callback())();
@@ -425,8 +447,7 @@
// Flip the two semi-spaces so that to_ is always the space for allocating
// objects.
from_ = to_;
- // TODO(koda): Use stats_history_ to decide new to-space size.
- to_ = SemiSpace::New(from_->size());
+ to_ = SemiSpace::New(NewSizeInWords(from_->size_in_words()));
if (to_ == NULL) {
// TODO(koda): We could try to recover (collect old space, wait for another
// isolate to finish scavenge, etc.).
« no previous file with comments | « runtime/vm/scavenger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698