Revision: 8918
Author: [email protected]
Date: Fri Aug 12 02:21:47 2011
Log: 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.
Review URL: http://codereview.chromium.org/7621014
http://code.google.com/p/v8/source/detail?r=8918
Modified:
/branches/experimental/gc/src/heap.cc
/branches/experimental/gc/src/heap.h
/branches/experimental/gc/src/spaces.cc
/branches/experimental/gc/src/spaces.h
=======================================
--- /branches/experimental/gc/src/heap.cc Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/heap.cc Fri Aug 12 02:21:47 2011
@@ -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,8 @@
#endif // DEBUG
old_gen_promotion_limit_(kMinimumPromotionLimit),
old_gen_allocation_limit_(kMinimumAllocationLimit),
+ old_gen_limit_factor_(1),
+ size_of_old_gen_at_last_old_space_gc_(0),
external_allocation_limit_(0),
amount_of_external_allocated_memory_(0),
amount_of_external_allocated_memory_at_last_global_gc_(0),
@@ -729,15 +725,7 @@
UpdateSurvivalRateTrend(start_new_space_size);
- intptr_t old_gen_size = PromotedSpaceSize();
- old_gen_promotion_limit_ =
- old_gen_size +
- Max(kMinimumPromotionLimit, old_gen_size / 3) +
- new_space()->Capacity();
- old_gen_allocation_limit_ =
- old_gen_size +
- Max(kMinimumAllocationLimit, old_gen_size / 2) +
- new_space()->Capacity();
+ size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize();
if (high_survival_rate_during_scavenges &&
IsStableOrIncreasingSurvivalTrend()) {
@@ -747,9 +735,15 @@
// 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_ =
+ OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
+ old_gen_allocation_limit_ =
+ OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
old_gen_exhausted_ = false;
} else {
@@ -4250,6 +4244,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());
=======================================
--- /branches/experimental/gc/src/heap.h Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/heap.h Fri Aug 12 02:21:47 2011
@@ -1209,9 +1209,38 @@
(PromotedSpaceSize() + PromotedExternalMemorySize());
}
- inline void LowerOldGenLimits(intptr_t bytes) {
- old_gen_promotion_limit_ -= bytes;
- old_gen_allocation_limit_ -= bytes;
+ static const intptr_t kMinimumPromotionLimit =
+ 2 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+ static const intptr_t kMinimumAllocationLimit =
+ 8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+
+ // When we sweep lazily we initially guess that there is no garbage on
the
+ // heap and set the limits for the next GC accordingly. As we sweep we
find
+ // out that some of the pages contained garbage and we have to adjust
+ // downwards the size of the heap. This means the limits that control
the
+ // timing of the next GC also need to be adjusted downwards.
+ void LowerOldGenLimits(intptr_t adjustment) {
+ size_of_old_gen_at_last_old_space_gc_ -= adjustment;
+ old_gen_promotion_limit_ =
+ OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
+ old_gen_allocation_limit_ =
+ OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
+ }
+
+ intptr_t OldGenPromotionLimit(intptr_t old_gen_size) {
+ intptr_t limit =
+ Max(old_gen_size + old_gen_size / 3, kMinimumPromotionLimit);
+ limit += new_space_.Capacity();
+ limit *= old_gen_limit_factor_;
+ return limit;
+ }
+
+ intptr_t OldGenAllocationLimit(intptr_t old_gen_size) {
+ intptr_t limit =
+ Max(old_gen_size + old_gen_size / 2, kMinimumAllocationLimit);
+ limit += new_space_.Capacity();
+ limit *= old_gen_limit_factor_;
+ return limit;
}
// Can be called when the embedding application is idle.
@@ -1458,6 +1487,13 @@
// 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_;
+
+ // Used to adjust the limits that control the timing of the next GC.
+ intptr_t size_of_old_gen_at_last_old_space_gc_;
+
// Limit on the amount of externally allocated memory allowed
// between global GCs. If reached a global GC is forced.
intptr_t external_allocation_limit_;
=======================================
--- /branches/experimental/gc/src/spaces.cc Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/spaces.cc Fri Aug 12 02:21:47 2011
@@ -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.
=======================================
--- /branches/experimental/gc/src/spaces.h Wed Aug 10 05:50:30 2011
+++ /branches/experimental/gc/src/spaces.h Fri Aug 12 02:21:47 2011
@@ -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_verbose) {
+ 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