Commit def729b6 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Change to limit the amount of space we waste due to fragmentation

in old space. Before this change we would compute the fragmentation 
limit before the GC, but that means that we take all the garbage 
into account - and consequently we almost never hit the limit (because 
we have a lot of garbage).

This change changes the policy to compact on the *next* GC if we
determine that we have too much fragmentation after doing a GC.
We'll do a GC if we've wasted more than 1MB and more than 15% of
the old space size.

This can be further improved by computing whether or not to compact
during the marking phase.
Review URL: http://codereview.chromium.org/202008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2841 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6621a438
......@@ -41,6 +41,7 @@ namespace internal {
bool MarkCompactCollector::force_compaction_ = false;
bool MarkCompactCollector::compacting_collection_ = false;
bool MarkCompactCollector::compact_on_next_gc_ = false;
int MarkCompactCollector::previous_marked_count_ = 0;
GCTracer* MarkCompactCollector::tracer_ = NULL;
......@@ -104,35 +105,15 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
// variable.
tracer_ = tracer;
static const int kFragmentationLimit = 50; // Percent.
#ifdef DEBUG
ASSERT(state_ == IDLE);
state_ = PREPARE_GC;
#endif
ASSERT(!FLAG_always_compact || !FLAG_never_compact);
compacting_collection_ = FLAG_always_compact || force_compaction_;
// We compact the old generation if it gets too fragmented (ie, we could
// recover an expected amount of space by reclaiming the waste and free
// list blocks). We always compact when the flag --gc-global is true
// because objects do not get promoted out of new space on non-compacting
// GCs.
if (!compacting_collection_) {
int old_gen_recoverable = 0;
int old_gen_used = 0;
OldSpaces spaces;
while (OldSpace* space = spaces.next()) {
old_gen_recoverable += space->Waste() + space->AvailableFree();
old_gen_used += space->Size();
}
int old_gen_fragmentation =
static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
if (old_gen_fragmentation > kFragmentationLimit) {
compacting_collection_ = true;
}
}
compacting_collection_ =
FLAG_always_compact || force_compaction_ || compact_on_next_gc_;
compact_on_next_gc_ = false;
if (FLAG_never_compact) compacting_collection_ = false;
if (FLAG_collect_maps) CreateBackPointers();
......@@ -173,6 +154,31 @@ void MarkCompactCollector::Finish() {
// GC, because it relies on the new address of certain old space
// objects (empty string, illegal builtin).
StubCache::Clear();
// If we've just compacted old space there's no reason to check the
// fragmentation limit. Just return.
if (HasCompacted()) return;
// We compact the old generation on the next GC if it has gotten too
// fragmented (ie, we could recover an expected amount of space by
// reclaiming the waste and free list blocks).
static const int kFragmentationLimit = 15; // Percent.
static const int kFragmentationAllowed = 1 * MB; // Absolute.
int old_gen_recoverable = 0;
int old_gen_used = 0;
OldSpaces spaces;
while (OldSpace* space = spaces.next()) {
old_gen_recoverable += space->Waste() + space->AvailableFree();
old_gen_used += space->Size();
}
int old_gen_fragmentation =
static_cast<int>((old_gen_recoverable * 100.0) / old_gen_used);
if (old_gen_fragmentation > kFragmentationLimit &&
old_gen_recoverable > kFragmentationAllowed) {
compact_on_next_gc_ = true;
}
}
......
......@@ -130,6 +130,9 @@ class MarkCompactCollector: public AllStatic {
// Global flag indicating whether spaces were compacted on the last GC.
static bool compacting_collection_;
// Global flag indicating whether spaces will be compacted on the next GC.
static bool compact_on_next_gc_;
// The number of objects left marked at the end of the last completed full
// GC (expected to be zero).
static int previous_marked_count_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment