Index: src/heap.cc |
=================================================================== |
--- src/heap.cc (revision 4248) |
+++ src/heap.cc (working copy) |
@@ -562,23 +562,18 @@ |
EnsureFromSpaceIsCommitted(); |
- // Perform mark-sweep with optional compaction. |
if (collector == MARK_COMPACTOR) { |
+ // Perform mark-sweep with optional compaction. |
MarkCompact(tracer); |
- } |
- // Always perform a scavenge to make room in new space. |
- Scavenge(); |
- |
- // Update the old space promotion limits after the scavenge due to |
- // promotions during scavenge. |
- if (collector == MARK_COMPACTOR) { |
int old_gen_size = PromotedSpaceSize(); |
old_gen_promotion_limit_ = |
old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3); |
old_gen_allocation_limit_ = |
old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2); |
old_gen_exhausted_ = false; |
+ } else { |
+ Scavenge(); |
} |
Counters::objs_since_last_young.Set(0); |
@@ -764,6 +759,17 @@ |
#endif |
+void Heap::CheckNewSpaceExpansionCriteria() { |
+ if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
+ survived_since_last_expansion_ > new_space_.Capacity()) { |
+ // Grow the size of new space if there is room to grow and enough |
+ // data has survived scavenge since the last expansion. |
+ new_space_.Grow(); |
+ survived_since_last_expansion_ = 0; |
+ } |
+} |
+ |
+ |
void Heap::Scavenge() { |
#ifdef DEBUG |
if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); |
@@ -780,13 +786,7 @@ |
// Used for updating survived_since_last_expansion_ at function end. |
int survived_watermark = PromotedSpaceSize(); |
- if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
- survived_since_last_expansion_ > new_space_.Capacity()) { |
- // Grow the size of new space if there is room to grow and enough |
- // data has survived scavenge since the last expansion. |
- new_space_.Grow(); |
- survived_since_last_expansion_ = 0; |
- } |
+ CheckNewSpaceExpansionCriteria(); |
// Flip the semispaces. After flipping, to space is empty, from space has |
// live objects. |
@@ -837,15 +837,17 @@ |
new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
- ScavengeExternalStringTable(); |
+ UpdateNewSpaceReferencesInExternalStringTable( |
+ &UpdateNewSpaceReferenceInExternalStringTableEntry); |
+ |
ASSERT(new_space_front == new_space_.top()); |
// Set age mark. |
new_space_.set_age_mark(new_space_.top()); |
// Update how much has survived scavenge. |
- survived_since_last_expansion_ += |
- (PromotedSpaceSize() - survived_watermark) + new_space_.Size(); |
+ IncrementYoungSurvivorsCounter( |
+ (PromotedSpaceSize() - survived_watermark) + new_space_.Size()); |
LOG(ResourceEvent("scavenge", "end")); |
@@ -853,7 +855,22 @@ |
} |
-void Heap::ScavengeExternalStringTable() { |
+String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Object** p) { |
+ MapWord first_word = HeapObject::cast(*p)->map_word(); |
+ |
+ if (!first_word.IsForwardingAddress()) { |
+ // Unreachable external string can be finalized. |
+ FinalizeExternalString(String::cast(*p)); |
+ return NULL; |
+ } |
+ |
+ // String is still reachable. |
+ return String::cast(first_word.ToForwardingAddress()); |
+} |
+ |
+ |
+void Heap::UpdateNewSpaceReferencesInExternalStringTable( |
+ ExternalStringTableUpdaterCallback updater_func) { |
ExternalStringTable::Verify(); |
if (ExternalStringTable::new_space_strings_.is_empty()) return; |
@@ -864,16 +881,10 @@ |
for (Object** p = start; p < end; ++p) { |
ASSERT(Heap::InFromSpace(*p)); |
- MapWord first_word = HeapObject::cast(*p)->map_word(); |
+ String* target = updater_func(p); |
- if (!first_word.IsForwardingAddress()) { |
- // Unreachable external string can be finalized. |
- FinalizeExternalString(String::cast(*p)); |
- continue; |
- } |
+ if (target == NULL) continue; |
- // String is still reachable. |
- String* target = String::cast(first_word.ToForwardingAddress()); |
ASSERT(target->IsExternalString()); |
if (Heap::InNewSpace(target)) { |