Commit 5e87a099 authored by ulan's avatar ulan Committed by Commit bot

New algorithm for selecting evacuation candidates

This lifts the sqrt(n) limit on number of evacuation candidates,
replaces O(n * sqrt(n)) algorithm with O(n*log(n)) algorithm, and
removes hard-coded constants.

Evacuation candidates are selected as follows:

1) Sort pages from the most free to the least free.

2) Select the first m pages as evacuation candidates such that m is as
large as possible under the two conditions:

- The total size of live objects in the first m pages does not exceed
the given limit. This is based on the assumption that the evacuation cost is
proportional to the total size of moved objects.

- The fragmentation of the (m+1)-th page does not exceed the given
limit.

Review URL: https://codereview.chromium.org/1038313003

Cr-Commit-Position: refs/heads/master@{#28651}
parent 1fb83a2f
This diff is collapsed.
......@@ -1055,14 +1055,6 @@ int PagedSpace::CountTotalPages() {
}
void PagedSpace::ObtainFreeListStatistics(Page* page, SizeStats* sizes) {
sizes->huge_size_ = page->available_in_huge_free_list();
sizes->small_size_ = page->available_in_small_free_list();
sizes->medium_size_ = page->available_in_medium_free_list();
sizes->large_size_ = page->available_in_large_free_list();
}
void PagedSpace::ResetFreeListStatistics() {
PageIterator page_iterator(this);
while (page_iterator.has_next()) {
......
......@@ -678,11 +678,11 @@ class MemoryChunk {
base::AtomicWord parallel_sweeping_;
// PagedSpace free-list statistics.
intptr_t available_in_small_free_list_;
intptr_t available_in_medium_free_list_;
intptr_t available_in_large_free_list_;
intptr_t available_in_huge_free_list_;
intptr_t non_available_small_blocks_;
int available_in_small_free_list_;
int available_in_medium_free_list_;
int available_in_large_free_list_;
int available_in_huge_free_list_;
int non_available_small_blocks_;
static MemoryChunk* Initialize(Heap* heap, Address base, size_t size,
Address area_start, Address area_end,
......@@ -776,16 +776,22 @@ class Page : public MemoryChunk {
void ResetFreeListStatistics();
int LiveBytesFromFreeList() {
return area_size() - non_available_small_blocks_ -
available_in_small_free_list_ - available_in_medium_free_list_ -
available_in_large_free_list_ - available_in_huge_free_list_;
}
#define FRAGMENTATION_STATS_ACCESSORS(type, name) \
type name() { return name##_; } \
void set_##name(type name) { name##_ = name; } \
void add_##name(type name) { name##_ += name; }
FRAGMENTATION_STATS_ACCESSORS(intptr_t, non_available_small_blocks)
FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_small_free_list)
FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_medium_free_list)
FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_large_free_list)
FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_huge_free_list)
FRAGMENTATION_STATS_ACCESSORS(int, non_available_small_blocks)
FRAGMENTATION_STATS_ACCESSORS(int, available_in_small_free_list)
FRAGMENTATION_STATS_ACCESSORS(int, available_in_medium_free_list)
FRAGMENTATION_STATS_ACCESSORS(int, available_in_large_free_list)
FRAGMENTATION_STATS_ACCESSORS(int, available_in_huge_free_list)
#undef FRAGMENTATION_STATS_ACCESSORS
......@@ -1700,18 +1706,6 @@ class PagedSpace : public Space {
// Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory() override;
struct SizeStats {
intptr_t Total() {
return small_size_ + medium_size_ + large_size_ + huge_size_;
}
intptr_t small_size_;
intptr_t medium_size_;
intptr_t large_size_;
intptr_t huge_size_;
};
void ObtainFreeListStatistics(Page* p, SizeStats* sizes);
void ResetFreeListStatistics();
// Sets the capacity, the available space and the wasted space to zero.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment