summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2019-11-20 14:18:40 -0800
committerAaron Patterson <tenderlove@github.com>2019-11-22 12:42:24 -0800
commit26fd8d962ce42b7eb8d1c1eb43ddfa1ff24dc3aa (patch)
treef677f3ee1a03f7efa1c382594bda8168c1838409 /gc.c
parent3f4199b0af791572b7abf63f33bb3b0b9b53d08f (diff)
Optimize pinned page sorting
Previously we would count the pinned objects on each comparison. Since sorting is O(N log N) and we calculated this on both left and right pages on each comparison this resulted in a extra iterations over the slots.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2688
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index 9329f311d2..d2b4330889 100644
--- a/gc.c
+++ b/gc.c
@@ -844,6 +844,7 @@ enum {
struct heap_page {
short total_slots;
short free_slots;
+ short pinned_slots;
short final_slots;
struct {
unsigned int before_sweep : 1;
@@ -7731,9 +7732,13 @@ count_pinned(struct heap_page *page)
static int
compare_pinned(const void *left, const void *right, void *dummy)
{
- int left_count = count_pinned(*(struct heap_page * const *)left);
- int right_count = count_pinned(*(struct heap_page * const *)right);
- return right_count - left_count;
+ struct heap_page *left_page;
+ struct heap_page *right_page;
+
+ left_page = *(struct heap_page * const *)left;
+ right_page = *(struct heap_page * const *)right;
+
+ return right_page->pinned_slots - left_page->pinned_slots;
}
static int
@@ -7760,6 +7765,7 @@ allocate_page_list(rb_objspace_t *objspace, page_compare_func_t *comparator)
list_for_each(&heap_eden->pages, page, page_node) {
page_list[i++] = page;
+ page->pinned_slots = count_pinned(page);
GC_ASSERT(page != NULL);
}
GC_ASSERT(total_pages > 0);