Index: src/heap/heap.cc |
diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
index 3d8873087ae141f2e2af87079701976d1045ed48..e960e28f4b16e94556c1550f84581a506acefd33 100644 |
--- a/src/heap/heap.cc |
+++ b/src/heap/heap.cc |
@@ -554,6 +554,65 @@ class Heap::PretenuringScope { |
Heap* heap_; |
}; |
+namespace { |
+inline bool MakePretenureDecision( |
+ AllocationSite* site, AllocationSite::PretenureDecision current_decision, |
+ double ratio, bool maximum_size_scavenge) { |
+ // Here we just allow state transitions from undecided or maybe tenure |
+ // to don't tenure, maybe tenure, or tenure. |
+ if ((current_decision == AllocationSite::kUndecided || |
+ current_decision == AllocationSite::kMaybeTenure)) { |
+ if (ratio >= AllocationSite::kPretenureRatio) { |
+ // We just transition into tenure state when the semi-space was at |
+ // maximum capacity. |
+ if (maximum_size_scavenge) { |
+ site->set_deopt_dependent_code(true); |
+ site->set_pretenure_decision(AllocationSite::kTenure); |
+ // Currently we just need to deopt when we make a state transition to |
+ // tenure. |
+ return true; |
+ } |
+ site->set_pretenure_decision(AllocationSite::kMaybeTenure); |
+ } else { |
+ site->set_pretenure_decision(AllocationSite::kDontTenure); |
+ } |
+ } |
+ return false; |
+} |
+ |
+inline bool DigestPretenuringFeedback(Isolate* isolate, AllocationSite* site, |
+ bool maximum_size_scavenge) { |
+ bool deopt = false; |
+ int create_count = site->memento_create_count(); |
+ int found_count = site->memento_found_count(); |
+ bool minimum_mementos_created = |
+ create_count >= AllocationSite::kPretenureMinimumCreated; |
+ double ratio = minimum_mementos_created || FLAG_trace_pretenuring_statistics |
+ ? static_cast<double>(found_count) / create_count |
+ : 0.0; |
+ AllocationSite::PretenureDecision current_decision = |
+ site->pretenure_decision(); |
+ |
+ if (minimum_mementos_created) { |
+ deopt = MakePretenureDecision(site, current_decision, ratio, |
+ maximum_size_scavenge); |
+ } |
+ |
+ if (FLAG_trace_pretenuring_statistics) { |
+ PrintIsolate(isolate, |
+ "pretenuring: AllocationSite(%p): (created, found, ratio) " |
+ "(%d, %d, %f) %s => %s\n", |
+ static_cast<void*>(site), create_count, found_count, ratio, |
+ site->PretenureDecisionName(current_decision), |
+ site->PretenureDecisionName(site->pretenure_decision())); |
+ } |
+ |
+ // Clear feedback calculation fields until the next gc. |
+ site->set_memento_found_count(0); |
+ site->set_memento_create_count(0); |
+ return deopt; |
+} |
+} // namespace |
void Heap::ProcessPretenuringFeedback() { |
bool trigger_deoptimization = false; |
@@ -580,7 +639,7 @@ void Heap::ProcessPretenuringFeedback() { |
DCHECK(site->IsAllocationSite()); |
active_allocation_sites++; |
allocation_mementos_found += found_count; |
- if (site->DigestPretenuringFeedback(maximum_size_scavenge)) { |
+ if (DigestPretenuringFeedback(isolate_, site, maximum_size_scavenge)) { |
trigger_deoptimization = true; |
} |
if (site->GetPretenureMode() == TENURED) { |