From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.1 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id DBBD11F516 for ; Fri, 22 Jun 2018 08:10:17 +0000 (UTC) From: Eric Wong To: spew@80x24.org Subject: [PATCH] MRU wip Date: Fri, 22 Jun 2018 08:10:17 +0000 Message-Id: <20180622081017.20225-1-e@80x24.org> List-Id: --- gc.c | 145 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 55 deletions(-) diff --git a/gc.c b/gc.c index feac07279aa..14a103b75cf 100644 --- a/gc.c +++ b/gc.c @@ -541,7 +541,7 @@ typedef struct rb_objspace { rb_event_flag_t hook_events; size_t total_allocated_objects; - + struct list_head mru_pages; /* part of eden_heap */ rb_heap_t eden_heap; rb_heap_t tomb_heap; /* heap for zombies and ghosts */ @@ -1047,8 +1047,8 @@ tick(void) static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj); static int rgengc_remember(rb_objspace_t *objspace, VALUE obj); -static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap); -static void rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap); +static void rgengc_mark_and_rememberset_clear(const struct list_head *); +static void rgengc_rememberset_mark(rb_objspace_t *objspace); static inline int RVALUE_FLAGS_AGE(VALUE flags) @@ -1332,6 +1332,7 @@ rb_objspace_alloc(void) #endif malloc_limit = gc_params.malloc_limit_min; list_head_init(&objspace->eden_heap.pages); + list_head_init(&objspace->mru_pages); list_head_init(&objspace->tomb_heap.pages); return objspace; @@ -3632,8 +3633,11 @@ gc_mode_transition(rb_objspace_t *objspace, enum gc_mode mode) } static void -gc_sweep_start_heap(rb_objspace_t *objspace, rb_heap_t *heap) +gc_sweep_start_heap(rb_objspace_t *objspace) { + rb_heap_t *heap = heap_eden; + /* fprintf(stderr, "start\n"); */ + list_prepend_list(&heap->pages, &objspace->mru_pages); heap->sweeping_page = list_top(&heap->pages, struct heap_page, page_node); heap->free_pages = NULL; #if GC_ENABLE_INCREMENTAL_MARK @@ -3658,7 +3662,7 @@ static void gc_sweep_start(rb_objspace_t *objspace) { gc_mode_transition(objspace, gc_mode_sweeping); - gc_sweep_start_heap(objspace, heap_eden); + gc_sweep_start_heap(objspace); } static void @@ -3722,6 +3726,8 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap) } } else { + list_del(&sweep_page->page_node); + list_add(&objspace->mru_pages, &sweep_page->page_node); heap_add_freepage(objspace, heap, sweep_page); break; } @@ -3793,6 +3799,7 @@ gc_sweep(rb_objspace_t *objspace) struct heap_page *page = NULL; gc_sweep_start(objspace); + VM_ASSERT(list_empty(&objspace->mru_pages)); list_for_each(&heap_eden->pages, page, page_node) { page->flags.before_sweep = TRUE; } @@ -5272,7 +5279,7 @@ gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj) } static int -gc_verify_heap_pages_(rb_objspace_t *objspace, struct list_head *head) +gc_verify_heap_pages_(rb_objspace_t *objspace, const struct list_head *head) { int remembered_old_objects = 0; struct heap_page *page = 0; @@ -5290,8 +5297,9 @@ static int gc_verify_heap_pages(rb_objspace_t *objspace) { int remembered_old_objects = 0; - remembered_old_objects = gc_verify_heap_pages_(objspace, &heap_eden->pages); - remembered_old_objects = gc_verify_heap_pages_(objspace, &heap_tomb->pages); + remembered_old_objects += gc_verify_heap_pages_(objspace, &objspace->mru_pages); + remembered_old_objects += gc_verify_heap_pages_(objspace, &heap_eden->pages); + remembered_old_objects += gc_verify_heap_pages_(objspace, &heap_tomb->pages); return remembered_old_objects; } @@ -5412,14 +5420,15 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark) objspace->rgengc.old_objects = 0; objspace->rgengc.last_major_gc = objspace->profile.count; objspace->marked_slots = 0; - rgengc_mark_and_rememberset_clear(objspace, heap_eden); + rgengc_mark_and_rememberset_clear(&objspace->mru_pages); + rgengc_mark_and_rememberset_clear(&heap_eden->pages); } else { objspace->flags.during_minor_gc = TRUE; objspace->marked_slots = objspace->rgengc.old_objects + objspace->rgengc.uncollectible_wb_unprotected_objects; /* uncollectible objects are marked already */ objspace->profile.minor_gc_count++; - rgengc_rememberset_mark(objspace, heap_eden); + rgengc_rememberset_mark(objspace); } #endif @@ -5430,37 +5439,43 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark) #if GC_ENABLE_INCREMENTAL_MARK static void -gc_marks_wb_unprotected_objects(rb_objspace_t *objspace) +gc_marks_wb_unprotected_objects_head(rb_objspace_t *objspace, + const struct list_head *head) { struct heap_page *page = 0; - list_for_each(&heap_eden->pages, page, page_node) { - bits_t *mark_bits = page->mark_bits; - bits_t *wbun_bits = page->wb_unprotected_bits; - RVALUE *p = page->start; - RVALUE *offset = p - NUM_IN_PAGE(p); - size_t j; - - for (j=0; j>= 1; - } while (bits); - } - } + list_for_each(head, page, page_node) { + bits_t *mark_bits = page->mark_bits; + bits_t *wbun_bits = page->wb_unprotected_bits; + RVALUE *p = page->start; + RVALUE *offset = p - NUM_IN_PAGE(p); + size_t j; + + for (j=0; j>= 1; + } while (bits); + } + } } - +} +static void +gc_marks_wb_unprotected_objects(rb_objspace_t *objspace) +{ + gc_marks_wb_unprotected_objects_head(objspace, &objspace->mru_pages); + gc_marks_wb_unprotected_objects_head(objspace, &heap_eden->pages); gc_mark_stacked_objects_all(objspace); } @@ -5823,18 +5838,22 @@ rgengc_remembered(rb_objspace_t *objspace, VALUE obj) #ifndef PROFILE_REMEMBERSET_MARK #define PROFILE_REMEMBERSET_MARK 0 #endif +struct rset_mark_prof { + int has_old; + int has_shady; + int has_both; + int skip; +}; static void -rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap) +rgengc_rememberset_mark_head(rb_objspace_t *objspace, + const struct list_head *head, + struct rset_mark_prof *prof) { size_t j; struct heap_page *page = 0; -#if PROFILE_REMEMBERSET_MARK - int has_old = 0, has_shady = 0, has_both = 0, skip = 0; -#endif - gc_report(1, objspace, "rgengc_rememberset_mark: start\n"); - list_for_each(&heap->pages, page, page_node) { + list_for_each(head, page, page_node) { if (page->flags.has_remembered_objects | page->flags.has_uncollectible_shady_objects) { RVALUE *p = page->start; RVALUE *offset = p - NUM_IN_PAGE(p); @@ -5842,11 +5861,15 @@ rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap) bits_t *marking_bits = page->marking_bits; bits_t *uncollectible_bits = page->uncollectible_bits; bits_t *wb_unprotected_bits = page->wb_unprotected_bits; -#if PROFILE_REMEMBERSET_MARK - if (page->flags.has_remembered_objects && page->flags.has_uncollectible_shady_objects) has_both++; - else if (page->flags.has_remembered_objects) has_old++; - else if (page->flags.has_uncollectible_shady_objects) has_shady++; -#endif + if (prof) { + if (page->flags.has_remembered_objects && + page->flags.has_uncollectible_shady_objects) + prof->has_both++; + else if (page->flags.has_remembered_objects) + prof->has_old++; + else if (page->flags.has_uncollectible_shady_objects) + prof->has_shady++; + } for (j=0; jskip++; } -#endif } +} +static void +rgengc_rememberset_mark(rb_objspace_t *objspace) +{ #if PROFILE_REMEMBERSET_MARK - fprintf(stderr, "%d\t%d\t%d\t%d\n", has_both, has_old, has_shady, skip); + struct rset_mark_prof profile = { 0 }; + struct rset_mark_prof *prof = &profile; +#else + struct rset_mark_prof *prof = 0; #endif + gc_report(1, objspace, "rgengc_rememberset_mark: start\n"); + rgengc_rememberset_mark_head(objspace, &objspace->mru_pages, prof); + rgengc_rememberset_mark_head(objspace, &heap_eden->pages, prof); + if (prof) { + fprintf(stderr, "%d\t%d\t%d\t%d\n", + prof->has_both, prof->has_old, prof->has_shady, prof->skip); + } gc_report(1, objspace, "rgengc_rememberset_mark: finished\n"); } static void -rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap) +rgengc_mark_and_rememberset_clear(const struct list_head *head) { struct heap_page *page = 0; - list_for_each(&heap->pages, page, page_node) { + list_for_each(head, page, page_node) { memset(&page->mark_bits[0], 0, HEAP_PAGE_BITMAP_SIZE); memset(&page->marking_bits[0], 0, HEAP_PAGE_BITMAP_SIZE); memset(&page->uncollectible_bits[0], 0, HEAP_PAGE_BITMAP_SIZE); -- EW