| Index: src/heap.cc
|
| diff --git a/src/heap.cc b/src/heap.cc
|
| index 52711584363977303d682436a0cec6f746e7cfff..60b425c2bb566c82526fdfc4006737223a874428 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(NOT_TENURED);
|
| + } 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,39 @@ void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer,
|
| }
|
|
|
|
|
| +void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) {
|
| + Object* cur = allocation_sites_list();
|
| + while (cur->IsAllocationSite()) {
|
| + AllocationSite* casted = AllocationSite::cast(cur);
|
| + if (casted->GetPretenureMode() == flag) {
|
| + 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.
|
| + ResetAllAllocationSitesDependentCode(TENURED);
|
| + 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.
|
|
|