[前][次][番号順一覧][スレッド一覧]

ruby-changes:63529

From: Aaron <ko1@a...>
Date: Fri, 6 Nov 2020 04:13:42 +0900 (JST)
Subject: [ruby-changes:63529] ab5f2fa4fb (master): Refactor verification method

https://git.ruby-lang.org/ruby.git/commit/?id=ab5f2fa4fb

From ab5f2fa4fb5b89a71080cd51e192a3882696fe04 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Thu, 5 Nov 2020 11:13:04 -0800
Subject: Refactor verification method

Combine everything in to one C function

diff --git a/gc.c b/gc.c
index 1c7945a..a80d9fc 100644
--- a/gc.c
+++ b/gc.c
@@ -8512,11 +8512,9 @@ compare_free_slots(const void *left, const void *right, void *dummy) https://github.com/ruby/ruby/blob/trunk/gc.c#L8512
     return left_page->free_slots - right_page->free_slots;
 }
 
-static VALUE
-gc_sort_heap_by_empty_slots(rb_execution_context_t *ec, VALUE self)
+static void
+gc_sort_heap_by_empty_slots(rb_objspace_t *objspace)
 {
-    rb_objspace_t *objspace = &rb_objspace;
-
     size_t total_pages = heap_eden->total_pages;
     size_t size = size_mul_or_raise(total_pages, sizeof(struct heap_page *), rb_eRuntimeError);
     struct heap_page *page = 0, **page_list = malloc(size);
@@ -8524,49 +8522,29 @@ gc_sort_heap_by_empty_slots(rb_execution_context_t *ec, VALUE self) https://github.com/ruby/ruby/blob/trunk/gc.c#L8522
 
     gc_rest(objspace);
 
-    RB_VM_LOCK_ENTER();
-    {
-        list_for_each(&heap_eden->pages, page, page_node) {
-            page_list[i++] = page;
-            GC_ASSERT(page != NULL);
-        }
-        GC_ASSERT(total_pages > 0);
-        GC_ASSERT((size_t)i == total_pages);
-
-        /* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
-         * head of the list, so empty pages will end up at the start of the heap */
-        ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
-
-        /* Reset the eden heap */
-        list_head_init(&objspace->eden_heap.pages);
-        heap_eden->free_pages = NULL;
-
-        for (i = 0; i < total_pages; i++) {
-            list_add(&heap_eden->pages, &page_list[i]->page_node);
-            if (page_list[i]->free_slots != 0) {
-                heap_add_freepage(heap_eden, page_list[i]);
-            }
-        }
-
-        free(page_list);
+    list_for_each(&heap_eden->pages, page, page_node) {
+        page_list[i++] = page;
+        GC_ASSERT(page != NULL);
     }
-    RB_VM_LOCK_LEAVE();
+    GC_ASSERT(total_pages > 0);
+    GC_ASSERT((size_t)i == total_pages);
 
-    return Qnil;
-}
+    /* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
+     * head of the list, so empty pages will end up at the start of the heap */
+    ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
 
-static VALUE
-gc_double_heap_size(rb_execution_context_t *ec, VALUE self)
-{
-    rb_objspace_t *objspace = &rb_objspace;
+    /* Reset the eden heap */
+    list_head_init(&objspace->eden_heap.pages);
+    heap_eden->free_pages = NULL;
 
-    RB_VM_LOCK_ENTER();
-    {
-        heap_add_pages(objspace, heap_eden, heap_allocated_pages);
+    for (i = 0; i < total_pages; i++) {
+        list_add(&heap_eden->pages, &page_list[i]->page_node);
+        if (page_list[i]->free_slots != 0) {
+            heap_add_freepage(heap_eden, page_list[i]);
+        }
     }
-    RB_VM_LOCK_LEAVE();
 
-    return Qnil;
+    free(page_list);
 }
 
 static void
@@ -9272,12 +9250,28 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9250
 }
 
 static VALUE
-gc_check_references_for_moved(rb_execution_context_t *ec, VALUE self)
+gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE toward_empty)
 {
     rb_objspace_t *objspace = &rb_objspace;
+
+    RB_VM_LOCK_ENTER();
+    {
+        if (RTEST(double_heap)) {
+            heap_add_pages(objspace, heap_eden, heap_allocated_pages);
+        }
+
+        if (RTEST(toward_empty)) {
+            gc_sort_heap_by_empty_slots(objspace);
+        }
+    }
+    RB_VM_LOCK_LEAVE();
+
+    gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue);
+
     objspace_reachable_objects_from_root(objspace, root_obj_check_moved_i, NULL);
     objspace_each_objects(objspace, heap_check_moved_i, NULL);
-    return Qnil;
+
+    return gc_compact_stats(ec, self);
 }
 
 VALUE
diff --git a/gc.rb b/gc.rb
index c763fc1..d2b0d8e 100644
--- a/gc.rb
+++ b/gc.rb
@@ -218,17 +218,7 @@ module GC https://github.com/ruby/ruby/blob/trunk/gc.rb#L218
   # object, that object should be pushed on the mark stack, and will
   # make a SEGV.
   def self.verify_compaction_references(toward: nil, double_heap: false)
-    if double_heap
-      Primitive.gc_double_heap_size
-    end
-
-    if toward == :empty
-      Primitive.gc_sort_heap_by_empty_slots
-    end
-
-    Primitive.gc_start_internal true, true, true, true
-    Primitive.gc_check_references_for_moved
-    Primitive.gc_compact_stats
+    Primitive.gc_verify_compaction_references(double_heap, toward == :empty)
   end
 end
 
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]