Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 52711584363977303d682436a0cec6f746e7cfff..2169e51f23552fb17e107d424572feae10ea8343 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -506,7 +506,8 @@ void Heap::RepairFreeListsAfterBoot() { |
| void Heap::ProcessPretenuringFeedback() { |
| - if (FLAG_allocation_site_pretenuring) { |
| + if (FLAG_allocation_site_pretenuring && |
| + new_space_high_promotion_mode_active_) { |
| int tenure_decisions = 0; |
| int dont_tenure_decisions = 0; |
| int allocation_mementos_found = 0; |
| @@ -514,7 +515,7 @@ void Heap::ProcessPretenuringFeedback() { |
| int active_allocation_sites = 0; |
| // If the scratchpad overflowed, we have to iterate over the allocation |
| - // stites list. |
| + // sites list. |
| bool use_scratchpad = |
| allocation_sites_scratchpad_length < kAllocationSiteScratchpadSize; |
| @@ -1100,12 +1101,15 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, |
| PrintPID("Limited new space size due to high promotion rate: %d MB\n", |
| new_space_.InitialCapacity() / MB); |
| } |
| - // Support for global pre-tenuring uses the high promotion mode as a |
| - // heuristic indicator of whether to pretenure or not, we trigger |
| - // deoptimization here to take advantage of pre-tenuring as soon as |
| - // possible. |
| + // The high promotion mode is our indicator to turn on pretenuring. We have |
| + // to deoptimize all optimized code in global pretenuring mode and all |
| + // code which should be tenured in local pretenuring mode. |
| if (FLAG_pretenuring) { |
| - isolate_->stack_guard()->FullDeopt(); |
| + if (FLAG_allocation_site_pretenuring) { |
| + ResetAllAllocationSitesDependentCode(); |
| + } else { |
| + isolate_->stack_guard()->FullDeopt(); |
| + } |
| } |
| } else if (new_space_high_promotion_mode_active_ && |
| IsStableOrDecreasingSurvivalTrend() && |
| @@ -1118,9 +1122,9 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, |
| PrintPID("Unlimited new space size due to low promotion rate: %d MB\n", |
| new_space_.MaximumCapacity() / MB); |
| } |
| - // Trigger deoptimization here to turn off pre-tenuring as soon as |
| + // Trigger deoptimization here to turn off global pretenuring as soon as |
| // possible. |
| - if (FLAG_pretenuring) { |
| + if (FLAG_pretenuring && !FLAG_allocation_site_pretenuring) { |
| isolate_->stack_guard()->FullDeopt(); |
| } |
| } |
| @@ -1212,6 +1216,8 @@ void Heap::MarkCompact(GCTracer* tracer) { |
| gc_state_ = MARK_COMPACT; |
| LOG(isolate_, ResourceEvent("markcompact", "begin")); |
| + uint64_t size_of_objects_before_gc = SizeOfObjects(); |
| + |
| mark_compact_collector_.Prepare(tracer); |
| ms_count_++; |
| @@ -1228,6 +1234,10 @@ void Heap::MarkCompact(GCTracer* tracer) { |
| isolate_->counters()->objs_since_last_full()->Set(0); |
| flush_monomorphic_ics_ = false; |
| + |
| + if (FLAG_allocation_site_pretenuring) { |
| + EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc); |
| + } |
| } |
| @@ -1966,6 +1976,49 @@ void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer, |
| } |
| +void Heap::ResetAllTenuredAllocationSitesDependentCode() { |
| + Object* cur = allocation_sites_list(); |
| + while (cur->IsAllocationSite()) { |
| + AllocationSite* casted = AllocationSite::cast(cur); |
| + if (casted->GetPretenureMode() == TENURED) { |
| + casted->ResetPretenureDecision(); |
| + } |
| + cur = casted->weak_next(); |
| + } |
| +} |
| + |
| + |
| +void Heap::ResetAllAllocationSitesDependentCode() { |
|
mvstanton
2014/01/09 15:33:30
nit: ResetAllTenuredAllocationSitesDependentCode()
Hannes Payer (out of office)
2014/01/09 16:01:09
Done. Thanks for this comment. ALL is actually not
|
| + Object* cur = allocation_sites_list(); |
| + while (cur->IsAllocationSite()) { |
| + AllocationSite* casted = AllocationSite::cast(cur); |
| + casted->ResetPretenureDecision(); |
| + cur = casted->weak_next(); |
| + } |
| +} |
| + |
| + |
| +void Heap::EvaluateOldSpaceLocalPretenuring( |
| + uint64_t size_of_objects_before_gc) { |
| + uint64_t size_of_objects_after_gc = SizeOfObjects(); |
| + double old_generation_survival_rate = |
| + (static_cast<double>(size_of_objects_after_gc) * 100) / |
| + static_cast<double>(size_of_objects_before_gc); |
| + |
| + if (old_generation_survival_rate < kOldSurvivalRateLowThreshold) { |
| + // Too many objects died in the old generation, pretenuring of wrong |
| + // allocation sites may be the cause for that. We have to deopt all |
| + // dependent code registered in the allocation sites to re-evaluate |
| + // our pretenuring decisions. |
| + ResetAllTenuredAllocationSitesDependentCode(); |
| + if (FLAG_trace_pretenuring) { |
| + PrintF("Deopt all allocation sites dependent code due to low survival " |
| + "rate in the old generation %f\n", old_generation_survival_rate); |
| + } |
| + } |
| +} |
| + |
| + |
| void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
| DisallowHeapAllocation no_allocation; |
| // All external strings are listed in the external string table. |