aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/gc.c b/gc.c
index 7365b6d6ec..5a4f72d9ff 100644
--- a/gc.c
+++ b/gc.c
@@ -8553,14 +8553,14 @@ gc_compact_after_gc(rb_objspace_t *objspace, int use_toward_empty, int use_doubl
heap_add_pages(objspace, heap_eden, heap_allocated_pages);
}
- VALUE moved_list;
+ VALUE moved_list_head;
VALUE disabled = rb_gc_disable();
if (use_toward_empty) {
- moved_list = gc_compact_heap(objspace, compare_free_slots);
+ moved_list_head = gc_compact_heap(objspace, compare_free_slots);
}
else {
- moved_list = gc_compact_heap(objspace, compare_pinned);
+ moved_list_head = gc_compact_heap(objspace, compare_pinned);
}
heap_eden->freelist = NULL;
@@ -8576,27 +8576,44 @@ gc_compact_after_gc(rb_objspace_t *objspace, int use_toward_empty, int use_doubl
heap_eden->free_pages = NULL;
heap_eden->using_page = NULL;
- while (moved_list) {
+ /* For each moved slot */
+ while (moved_list_head) {
VALUE next_moved;
struct heap_page *page;
- page = GET_HEAP_PAGE(moved_list);
- next_moved = RMOVED(moved_list)->next;
+ page = GET_HEAP_PAGE(moved_list_head);
+ next_moved = RMOVED(moved_list_head)->next;
- RMOVED(moved_list)->flags = 0;
- RMOVED(moved_list)->destination = 0;
- RMOVED(moved_list)->next = 0;
+ /* clear the memory for that moved slot */
+ RMOVED(moved_list_head)->flags = 0;
+ RMOVED(moved_list_head)->destination = 0;
+ RMOVED(moved_list_head)->next = 0;
page->free_slots++;
- heap_page_add_freeobj(objspace, page, moved_list);
+ heap_page_add_freeobj(objspace, page, moved_list_head);
+
if (page->free_slots == page->total_slots && heap_pages_freeable_pages > 0) {
heap_pages_freeable_pages--;
heap_unlink_page(objspace, heap_eden, page);
heap_add_page(objspace, heap_tomb, page);
- } else if (page->free_slots == page->total_slots) {
- page->free_next = NULL;
}
objspace->profile.total_freed_objects++;
- moved_list = next_moved;
+ moved_list_head = next_moved;
+ }
+
+ /* Add any eden pages with free slots back to the free pages list */
+ struct heap_page *page = NULL;
+ list_for_each(&heap_eden->pages, page, page_node) {
+ if (page->free_slots > 0) {
+ heap_add_freepage(objspace, heap_eden, page);
+ } else {
+ page->free_next = NULL;
+ }
+ }
+
+ /* Set up "using_page" if we have any pages with free slots */
+ if (heap_eden->free_pages) {
+ heap_eden->using_page = heap_eden->free_pages;
+ heap_eden->free_pages = heap_eden->free_pages->free_next;
}
if (use_verifier) {