Flutter Engine
The Flutter Engine
Public Member Functions | Friends | List of all members
dart::PageSpaceController Class Reference

#include <pages.h>

Public Member Functions

 PageSpaceController (Heap *heap, int heap_growth_ratio, int heap_growth_max, int garbage_collection_time_ratio)
 
 ~PageSpaceController ()
 
bool ReachedHardThreshold (SpaceUsage after) const
 
bool ReachedSoftThreshold (SpaceUsage after) const
 
bool ReachedIdleThreshold (SpaceUsage current) const
 
void EvaluateGarbageCollection (SpaceUsage before, SpaceUsage after, int64_t start, int64_t end)
 
void EvaluateAfterLoading (SpaceUsage after)
 
void set_last_usage (SpaceUsage current)
 

Friends

class PageSpace
 

Detailed Description

Definition at line 56 of file pages.h.

Constructor & Destructor Documentation

◆ PageSpaceController()

dart::PageSpaceController::PageSpaceController ( Heap heap,
int  heap_growth_ratio,
int  heap_growth_max,
int  garbage_collection_time_ratio 
)

Definition at line 1556 of file pages.cc.

1560 : heap_(heap),
1561 heap_growth_ratio_(heap_growth_ratio),
1562 desired_utilization_((100.0 - heap_growth_ratio) / 100.0),
1563 heap_growth_max_(heap_growth_max),
1564 garbage_collection_time_ratio_(garbage_collection_time_ratio),
1565 idle_gc_threshold_in_words_(0) {
1566 const intptr_t growth_in_pages = heap_growth_max / 2;
1567 RecordUpdate(last_usage_, last_usage_, growth_in_pages, "initial");
1568}

◆ ~PageSpaceController()

dart::PageSpaceController::~PageSpaceController ( )

Definition at line 1570 of file pages.cc.

1570{}

Member Function Documentation

◆ EvaluateAfterLoading()

void dart::PageSpaceController::EvaluateAfterLoading ( SpaceUsage  after)

Definition at line 1704 of file pages.cc.

1704 {
1705 // Number of pages we can allocate and still be within the desired growth
1706 // ratio.
1707 intptr_t growth_in_pages;
1708 if (desired_utilization_ == 0.0) {
1709 growth_in_pages = heap_growth_max_;
1710 } else {
1711 growth_in_pages = (static_cast<intptr_t>(after.CombinedUsedInWords() /
1712 desired_utilization_) -
1713 (after.CombinedUsedInWords())) /
1715 }
1716
1717 // Apply growth cap.
1718 growth_in_pages =
1719 Utils::Minimum(static_cast<intptr_t>(heap_growth_max_), growth_in_pages);
1720
1721 RecordUpdate(after, after, growth_in_pages, "loaded");
1722}
static T Minimum(T x, T y)
Definition: utils.h:36
static constexpr intptr_t kPageSizeInWords
Definition: page.h:28

◆ EvaluateGarbageCollection()

void dart::PageSpaceController::EvaluateGarbageCollection ( SpaceUsage  before,
SpaceUsage  after,
int64_t  start,
int64_t  end 
)

Definition at line 1599 of file pages.cc.

1602 {
1603 ASSERT(end >= start);
1604 history_.AddGarbageCollectionTime(start, end);
1605 const int gc_time_fraction = history_.GarbageCollectionTimeFraction();
1606
1607 // Assume garbage increases linearly with allocation:
1608 // G = kA, and estimate k from the previous cycle.
1609 const intptr_t allocated_since_previous_gc =
1610 before.CombinedUsedInWords() - last_usage_.CombinedUsedInWords();
1611 intptr_t grow_heap;
1612 if (allocated_since_previous_gc > 0) {
1613 intptr_t garbage =
1614 before.CombinedUsedInWords() - after.CombinedUsedInWords();
1615 // Garbage may be negative if when the OOM reservation is refilled.
1616 garbage = Utils::Maximum(static_cast<intptr_t>(0), garbage);
1617 // It makes no sense to expect that each kb allocated will cause more than
1618 // one kb of garbage, so we clamp k at 1.0.
1619 const double k = Utils::Minimum(
1620 1.0, garbage / static_cast<double>(allocated_since_previous_gc));
1621
1622 const int garbage_ratio = static_cast<int>(k * 100);
1623
1624 // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage.
1625 double t = 1.0 - desired_utilization_;
1626 // If we spend too much time in GC, strive for even more free space.
1627 if (gc_time_fraction > garbage_collection_time_ratio_) {
1628 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0;
1629 }
1630
1631 // Number of pages we can allocate and still be within the desired growth
1632 // ratio.
1633 const intptr_t grow_pages =
1634 (static_cast<intptr_t>(after.CombinedUsedInWords() /
1635 desired_utilization_) -
1636 (after.CombinedUsedInWords())) /
1638 if (garbage_ratio == 0) {
1639 // No garbage in the previous cycle so it would be hard to compute a
1640 // grow_heap size based on estimated garbage so we use growth ratio
1641 // heuristics instead.
1642 grow_heap =
1643 Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), grow_pages);
1644 } else if (garbage_collection_time_ratio_ == 0) {
1645 // Exclude time from the growth policy decision for --deterministic.
1646 grow_heap =
1647 Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), grow_pages);
1648 } else {
1649 // Find minimum 'grow_heap' such that after increasing capacity by
1650 // 'grow_heap' pages and filling them, we expect a GC to be worthwhile.
1651 intptr_t max = heap_growth_max_;
1652 intptr_t min = 0;
1653 intptr_t local_grow_heap = 0;
1654 while (min < max) {
1655 local_grow_heap = (max + min) / 2;
1656 const intptr_t limit =
1657 after.CombinedUsedInWords() + (local_grow_heap * kPageSizeInWords);
1658 const intptr_t allocated_before_next_gc =
1659 limit - (after.CombinedUsedInWords());
1660 const double estimated_garbage = k * allocated_before_next_gc;
1661 if (t <= estimated_garbage / limit) {
1662 max = local_grow_heap - 1;
1663 } else {
1664 min = local_grow_heap + 1;
1665 }
1666 }
1667 local_grow_heap = (max + min) / 2;
1668 grow_heap = local_grow_heap;
1669 ASSERT(grow_heap >= 0);
1670 // If we are going to grow by heap_grow_max_ then ensure that we
1671 // will be growing the heap at least by the growth ratio heuristics.
1672 if (grow_heap >= heap_growth_max_) {
1673 grow_heap = Utils::Maximum(grow_pages, grow_heap);
1674 }
1675 }
1676 } else {
1677 grow_heap = 0;
1678 }
1679 last_usage_ = after;
1680
1681 intptr_t max_capacity_in_words = heap_->old_space()->max_capacity_in_words_;
1682 if (max_capacity_in_words != 0) {
1683 ASSERT(grow_heap >= 0);
1684 // Fraction of asymptote used.
1685 double f = static_cast<double>(after.CombinedUsedInWords() +
1686 (kPageSizeInWords * grow_heap)) /
1687 static_cast<double>(max_capacity_in_words);
1688 ASSERT(f >= 0.0);
1689 // Increase weight at the high end.
1690 f = f * f;
1691 // Fraction of asymptote available.
1692 f = 1.0 - f;
1693 ASSERT(f <= 1.0);
1694 // Discount growth more the closer we get to the desired asymptote.
1695 grow_heap = static_cast<intptr_t>(grow_heap * f);
1696 // Minimum growth step after reaching the asymptote.
1697 intptr_t min_step = (2 * MB) / kPageSize;
1698 grow_heap = Utils::Maximum(min_step, grow_heap);
1699 }
1700
1701 RecordUpdate(before, after, grow_heap, "gc");
1702}
PageSpace * old_space()
Definition: heap.h:63
void AddGarbageCollectionTime(int64_t start, int64_t end)
Definition: pages.cc:1774
intptr_t CombinedUsedInWords() const
Definition: spaces.h:27
static constexpr T Maximum(T x, T y)
Definition: utils.h:41
#define ASSERT(E)
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
constexpr intptr_t MB
Definition: globals.h:530
static constexpr intptr_t kPageSize
Definition: page.h:27

◆ ReachedHardThreshold()

bool dart::PageSpaceController::ReachedHardThreshold ( SpaceUsage  after) const

Definition at line 1572 of file pages.cc.

1572 {
1573 if (heap_growth_ratio_ == 100) {
1574 return false;
1575 }
1576 if ((heap_ != nullptr) && (heap_->mode() == Dart_PerformanceMode_Latency)) {
1577 return false;
1578 }
1579 return after.CombinedUsedInWords() > hard_gc_threshold_in_words_;
1580}
Dart_PerformanceMode mode() const
Definition: heap.h:103
@ Dart_PerformanceMode_Latency
Definition: dart_api.h:1380

◆ ReachedIdleThreshold()

bool dart::PageSpaceController::ReachedIdleThreshold ( SpaceUsage  current) const

Definition at line 1592 of file pages.cc.

1592 {
1593 if (heap_growth_ratio_ == 100) {
1594 return false;
1595 }
1596 return current.CombinedUsedInWords() > idle_gc_threshold_in_words_;
1597}

◆ ReachedSoftThreshold()

bool dart::PageSpaceController::ReachedSoftThreshold ( SpaceUsage  after) const

Definition at line 1582 of file pages.cc.

1582 {
1583 if (heap_growth_ratio_ == 100) {
1584 return false;
1585 }
1586 if ((heap_ != nullptr) && (heap_->mode() == Dart_PerformanceMode_Latency)) {
1587 return false;
1588 }
1589 return after.CombinedUsedInWords() > soft_gc_threshold_in_words_;
1590}

◆ set_last_usage()

void dart::PageSpaceController::set_last_usage ( SpaceUsage  current)
inline

Definition at line 82 of file pages.h.

82{ last_usage_ = current; }

Friends And Related Function Documentation

◆ PageSpace

friend class PageSpace
friend

Definition at line 85 of file pages.h.


The documentation for this class was generated from the following files: