Reviewers: Vyacheslav Egorov,
Description:
Fix the thresholds so that the heap does not grow uncontrollably. This
fixes
the OOM on the 524 test, alllowing the underlying crash issue to become
visible
again.
Please review this at http://codereview.chromium.org/7621014/
SVN Base: http://v8.googlecode.com/svn/branches/experimental/gc/
Affected files:
M src/heap.h
M src/heap.cc
M src/spaces.h
M src/spaces.cc
Index: src/heap.cc
===================================================================
--- src/heap.cc (revision 8902)
+++ src/heap.cc (working copy)
@@ -62,12 +62,6 @@
namespace internal {
-static const intptr_t kMinimumPromotionLimit =
- 2 * (Page::kPageSize > MB ? Page::kPageSize : MB);
-static const intptr_t kMinimumAllocationLimit =
- 8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
-
-
static Mutex* gc_initializer_mutex = OS::CreateMutex();
@@ -121,6 +115,7 @@
#endif // DEBUG
old_gen_promotion_limit_(kMinimumPromotionLimit),
old_gen_allocation_limit_(kMinimumAllocationLimit),
+ old_gen_limit_factor_(1),
external_allocation_limit_(0),
amount_of_external_allocated_memory_(0),
amount_of_external_allocated_memory_at_last_global_gc_(0),
@@ -731,13 +726,11 @@
intptr_t old_gen_size = PromotedSpaceSize();
old_gen_promotion_limit_ =
- old_gen_size +
- Max(kMinimumPromotionLimit, old_gen_size / 3) +
- new_space()->Capacity();
+ Max(new_space()->Capacity() + old_gen_size +
kMinimumPromotionLimit,
+ new_space()->Capacity() + PromotionFactor(old_gen_size));
old_gen_allocation_limit_ =
- old_gen_size +
- Max(kMinimumAllocationLimit, old_gen_size / 2) +
- new_space()->Capacity();
+ Max(new_space()->Capacity() + old_gen_size +
kMinimumAllocationLimit,
+ new_space()->Capacity() + AllocationFactor(old_gen_size));
if (high_survival_rate_during_scavenges &&
IsStableOrIncreasingSurvivalTrend()) {
@@ -747,9 +740,12 @@
// In this case we aggressively raise old generation memory limits to
// postpone subsequent mark-sweep collection and thus trade memory
// space for the mutation speed.
- old_gen_promotion_limit_ *= 2;
- old_gen_allocation_limit_ *= 2;
+ old_gen_limit_factor_ = 2;
+ } else {
+ old_gen_limit_factor_ = 1;
}
+ old_gen_promotion_limit_ *= old_gen_limit_factor_;
+ old_gen_allocation_limit_ *= old_gen_limit_factor_;
old_gen_exhausted_ = false;
} else {
@@ -4250,6 +4246,7 @@
old_gen_promotion_limit_);
PrintF("old_gen_allocation_limit_ %" V8_PTR_PREFIX "d\n",
old_gen_allocation_limit_);
+ PrintF("old_gen_limit_factor_ %d\n", old_gen_limit_factor_);
PrintF("\n");
PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles());
Index: src/heap.h
===================================================================
--- src/heap.h (revision 8902)
+++ src/heap.h (working copy)
@@ -1209,9 +1209,28 @@
(PromotedSpaceSize() + PromotedExternalMemorySize());
}
+ static const intptr_t kMinimumPromotionLimit =
+ 2 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+ static const intptr_t kMinimumAllocationLimit =
+ 8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+ static inline intptr_t PromotionFactor(intptr_t size) {
+ return size + size / 3;
+ }
+ static inline intptr_t AllocationFactor(intptr_t size) {
+ return size + size / 2;
+ }
+
inline void LowerOldGenLimits(intptr_t bytes) {
- old_gen_promotion_limit_ -= bytes;
- old_gen_allocation_limit_ -= bytes;
+ old_gen_promotion_limit_ =
+ Max(old_gen_promotion_limit_ -
+ PromotionFactor(bytes) * old_gen_limit_factor_,
+ (kMinimumAllocationLimit + new_space_.Capacity()) *
+ old_gen_limit_factor_);
+ old_gen_allocation_limit_ =
+ Max(old_gen_allocation_limit_ -
+ AllocationFactor(bytes) * old_gen_limit_factor_,
+ (kMinimumAllocationLimit + new_space_.Capacity()) *
+ old_gen_limit_factor_);
}
// Can be called when the embedding application is idle.
@@ -1458,6 +1477,10 @@
// every allocation in large object space.
intptr_t old_gen_allocation_limit_;
+ // Sometimes the heuristics dictate that those limits are increased.
This
+ // variable records that fact.
+ int old_gen_limit_factor_;
+
// Limit on the amount of externally allocated memory allowed
// between global GCs. If reached a global GC is forced.
intptr_t external_allocation_limit_;
Index: src/spaces.cc
===================================================================
--- src/spaces.cc (revision 8902)
+++ src/spaces.cc (working copy)
@@ -1930,6 +1930,15 @@
SetTop(NULL, NULL);
// Stop lazy sweeping for the space.
+ if (FLAG_trace_gc && first_unswept_page_ != NULL) {
+ int pages = 0;
+ Page* p = last_unswept_page_;
+ do {
+ pages++;
+ p = p->next_page();
+ } while (p != last_unswept_page_);
+ PrintF("Abandoned %d unswept pages\n", pages);
+ }
first_unswept_page_ = last_unswept_page_ = Page::FromAddress(NULL);
// Clear the free list before a full GC---it will be rebuilt afterward.
Index: src/spaces.h
===================================================================
--- src/spaces.h (revision 8902)
+++ src/spaces.h (working copy)
@@ -1434,6 +1434,7 @@
void SetPagesToSweep(Page* first, Page* last) {
first_unswept_page_ = first;
last_unswept_page_ = last;
+ int unswept_pages = 0;
Page* p = first;
do {
@@ -1441,7 +1442,12 @@
// page. We have to set this flag on the pages to indicate this.
p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
p = p->next_page();
+ unswept_pages++;
} while (p != last);
+
+ if (FLAG_trace_gc) {
+ PrintF("Postponing sweep for %d pages\n", unswept_pages);
+ }
}
bool AdvanceSweeper(intptr_t bytes_to_sweep);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev