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

ruby-changes:67221

From: Peter <ko1@a...>
Date: Mon, 23 Aug 2021 23:55:14 +0900 (JST)
Subject: [ruby-changes:67221] eddd369e73 (master): Revert "[Feature #18045] Implement size classes for GC"

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

From eddd369e7378ec762cf81a226aec1a2b8719bf7a Mon Sep 17 00:00:00 2001
From: Peter Zhu <peter@p...>
Date: Mon, 23 Aug 2021 10:49:14 -0400
Subject: Revert "[Feature #18045] Implement size classes for GC"

This reverts commits 48ff7a9f3e47bffb3e4d067a12ba9b936261caa0
and b2e2cf2dedd104acad8610721db5e4d341f135ef because it is causing
crashes in SPARC solaris and i386 debian.
---
 class.c                            |    3 +-
 ext/objspace/objspace.c            |    2 +
 gc.c                               | 1428 +++++++++++++++++-------------------
 include/ruby/internal/value_type.h |    2 +
 internal/gc.h                      |    6 +-
 misc/lldb_cruby.py                 |   10 +-
 vm_eval.c                          |    1 +
 7 files changed, 692 insertions(+), 760 deletions(-)

diff --git a/class.c b/class.c
index 4c469ff..5fa51df 100644
--- a/class.c
+++ b/class.c
@@ -185,7 +185,8 @@ class_alloc(VALUE flags, VALUE klass) https://github.com/ruby/ruby/blob/trunk/class.c#L185
     RVARGC_NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | FL_PROMOTED1 /* start from age == 2 */ | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0), payload_size);
 
 #if USE_RVARGC
-    obj->ptr = (rb_classext_t *)rb_gc_rvargc_object_data((VALUE)obj);
+    obj->ptr = (rb_classext_t *)rb_rvargc_payload_data_ptr((VALUE)obj + rb_slot_size());
+    RB_OBJ_WRITTEN(obj, Qundef, (VALUE)obj + rb_slot_size());
 #else
     obj->ptr = ZALLOC(rb_classext_t);
 #endif
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 3fa4fd2..72d1eb8 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -66,6 +66,7 @@ total_i(VALUE v, void *ptr) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L66
       case T_IMEMO:
       case T_ICLASS:
       case T_NODE:
+      case T_PAYLOAD:
       case T_ZOMBIE:
           return;
       default:
@@ -224,6 +225,7 @@ type2sym(enum ruby_value_type i) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L225
 	CASE_TYPE(T_ICLASS);
         CASE_TYPE(T_MOVED);
 	CASE_TYPE(T_ZOMBIE);
+	CASE_TYPE(T_PAYLOAD);
 #undef CASE_TYPE
       default: rb_bug("type2sym: unknown type (%d)", i);
     }
diff --git a/gc.c b/gc.c
index 4c28c68..fa4ab44 100644
--- a/gc.c
+++ b/gc.c
@@ -556,6 +556,7 @@ typedef struct gc_profile_record { https://github.com/ruby/ruby/blob/trunk/gc.c#L556
 } gc_profile_record;
 
 #define FL_FROM_FREELIST FL_USER0
+#define FL_FROM_PAYLOAD FL_USER0
 
 struct RMoved {
     VALUE flags;
@@ -569,12 +570,31 @@ struct RMoved { https://github.com/ruby/ruby/blob/trunk/gc.c#L570
 #pragma pack(push, 4) /* == SIZEOF_VALUE: magic for reducing sizeof(RVALUE): 24 -> 20 */
 #endif
 
+struct RPayload {
+    VALUE flags;
+};
+#define RPAYLOAD(obj) ((struct RPayload *)obj)
+static unsigned short
+RPAYLOAD_LEN(VALUE obj)
+{
+    unsigned short len = (unsigned short)(RPAYLOAD(obj)->flags >> FL_USHIFT);
+    return len;
+}
+
+static void
+RPAYLOAD_FLAGS_SET(VALUE obj, unsigned short len)
+{
+    // as len is the only thing in the user bits, we can overwrite it every time
+    RPAYLOAD(obj)->flags = T_PAYLOAD | (len << FL_USHIFT);
+}
+
 typedef struct RVALUE {
     union {
 	struct {
 	    VALUE flags;		/* always 0 for freed obj */
 	    struct RVALUE *next;
 	} free;
+        struct RPayload payload;
         struct RMoved  moved;
 	struct RBasic  basic;
 	struct RObject object;
@@ -660,14 +680,6 @@ typedef struct mark_stack { https://github.com/ruby/ruby/blob/trunk/gc.c#L680
     size_t unused_cache_size;
 } mark_stack_t;
 
-#if USE_RVARGC
-#define SIZE_POOL_COUNT 4
-#else
-#define SIZE_POOL_COUNT 1
-#endif
-#define SIZE_POOL_EDEN_HEAP(size_pool) (&(size_pool)->eden_heap)
-#define SIZE_POOL_TOMB_HEAP(size_pool) (&(size_pool)->tomb_heap)
-
 typedef struct rb_heap_struct {
     struct heap_page *free_pages;
     struct list_head pages;
@@ -681,29 +693,6 @@ typedef struct rb_heap_struct { https://github.com/ruby/ruby/blob/trunk/gc.c#L693
     size_t total_slots;      /* total slot count (about total_pages * HEAP_PAGE_OBJ_LIMIT) */
 } rb_heap_t;
 
-typedef struct rb_size_pool_struct {
-#if USE_RVARGC
-    RVALUE *freelist;
-    struct heap_page *using_page;
-#endif
-
-    short slot_size;
-
-    size_t allocatable_pages;
-
-#if USE_RVARGC
-    /* Sweeping statistics */
-    size_t freed_slots;
-    size_t empty_slots;
-
-    /* Global statistics */
-    size_t force_major_gc_count;
-#endif
-
-    rb_heap_t eden_heap;
-    rb_heap_t tomb_heap;
-} rb_size_pool_t;
-
 enum gc_mode {
     gc_mode_none,
     gc_mode_marking,
@@ -739,7 +728,8 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L728
     size_t total_allocated_objects;
     VALUE next_object_id;
 
-    rb_size_pool_t size_pools[SIZE_POOL_COUNT];
+    rb_heap_t eden_heap;
+    rb_heap_t tomb_heap; /* heap for zombies and ghosts */
 
     struct {
 	rb_atomic_t finalizing;
@@ -899,8 +889,6 @@ struct heap_page { https://github.com/ruby/ruby/blob/trunk/gc.c#L889
 	unsigned int in_tomb : 1;
     } flags;
 
-    rb_size_pool_t *size_pool;
-
     struct heap_page *free_next;
     RVALUE *start;
     RVALUE *freelist;
@@ -953,10 +941,12 @@ VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress; https://github.com/ruby/ruby/blob/trunk/gc.c#L941
 #define heap_pages_sorted_length objspace->heap_pages.sorted_length
 #define heap_pages_lomem	objspace->heap_pages.range[0]
 #define heap_pages_himem	objspace->heap_pages.range[1]
+#define heap_allocatable_pages	objspace->heap_pages.allocatable_pages
 #define heap_pages_freeable_pages	objspace->heap_pages.freeable_pages
 #define heap_pages_final_slots		objspace->heap_pages.final_slots
 #define heap_pages_deferred_final	objspace->heap_pages.deferred_final
-#define size_pools              objspace->size_pools
+#define heap_eden               (&objspace->eden_heap)
+#define heap_tomb               (&objspace->tomb_heap)
 #define during_gc		objspace->flags.during_gc
 #define finalizing		objspace->atomic_flags.finalizing
 #define finalizer_table 	objspace->finalizer_table
@@ -997,69 +987,6 @@ gc_mode_verify(enum gc_mode mode) https://github.com/ruby/ruby/blob/trunk/gc.c#L987
     return mode;
 }
 
-static inline bool
-has_sweeping_pages(rb_objspace_t *objspace)
-{
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        if (size_pools[i].eden_heap.sweeping_page) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static inline size_t
-heap_eden_total_pages(rb_objspace_t *objspace)
-{
-    size_t count = 0;
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        count += size_pools[i].eden_heap.total_pages;
-    }
-    return count;
-}
-
-static inline size_t
-heap_eden_total_slots(rb_objspace_t *objspace)
-{
-    size_t count = 0;
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        count += size_pools[i].eden_heap.total_slots;
-    }
-    return count;
-}
-
-static inline size_t
-heap_tomb_total_pages(rb_objspace_t *objspace)
-{
-    size_t count = 0;
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        count += size_pools[i].tomb_heap.total_pages;
-    }
-    return count;
-}
-
-static inline size_t
-heap_allocatable_pages(rb_objspace_t *objspace)
-{
-    size_t count = 0;
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        count += size_pools[i].allocatable_pages;
-    }
-    return count;
-}
-
-static inline size_t
-heap_allocatable_slots(rb_objspace_t *objspace)
-{
-    size_t count = 0;
-    for (int i = 0; i < SIZE_POOL_COUNT; i++) {
-        rb_size_pool_t *size_pool = &size_pools[i];
-        int slot_size_multiple = size_pool->slot_size / sizeof(RVALUE);
-        count += size_pool->allocatable_pages * HEAP_PAGE_OBJ_LIMIT / slot_size_multiple;
-    }
-    return count;
-}
-
 #define gc_mode(objspace)                gc_mode_verify((enum gc_mode)(objspace)->flags.mode)
 #define gc_mode_set(objspace, mode)      ((objspace)->flags.mode = (unsigned int)gc_mode_verify(mode))
 
@@ -1076,7 +1003,8 @@ heap_allocatable_slots(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L1003
 #else
 #define will_be_incremental_marking(objspace) FALSE
 #endif
-#define is_lazy_sweeping(objspace)           (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(objspace))
+#define has_sweeping_pages(heap)         ((heap)->sweeping_page != 0)
+#define is_lazy_sweeping(heap)           (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(heap))
 
 #if SIZEOF_LONG == SIZEOF_VOIDP
 # define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG)
@@ -1148,14 +1076,14 @@ static void gc_marks(rb_objspace_t *objspace, int full_mark); https://github.com/ruby/ruby/blob/trunk/gc.c#L1076
 static void gc_marks_start(rb_objspace_t *objspace, int full);
 static int  gc_marks_finish(rb_objspace_t *objspace);
 static void gc_marks_rest(rb_objspace_t *objspace);
-static void gc_marks_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
+static void gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap);
 
 static void gc_sweep(rb_objspace_t *objspace);
 static void gc_sweep_start(rb_objspace_t *objspace);
 static void gc_sweep_finish(rb_objspace_t *objspace);
-static int  gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
+static int  gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap);
 static void gc_sweep_rest(rb_objspace_t *objspace);
-static void gc_sweep_continue(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *heap);
+static void gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap);
 
 static inline void gc_mark(rb_objspace_t *objspace, VALUE ptr);
 static inline void gc_pin(rb_objspace_t *objspace, VALUE ptr);
@@ -1362,6 +1290,36 @@ RVALUE_FLAGS_AGE(VALUE flags) https://github.com/ruby/ruby/blob/trunk/gc.c#L1290
     return (int)((flags & (FL_PROMOTED0 | FL_PROMOTED1)) >> RVALUE_AGE_SHIFT);
 }
 
+#if USE_RVARGC
+static VALUE
+payload_or_self(VALUE obj)
+{
+    struct heap_page *p = GET_HEAP_PAGE(obj);
+    VALUE cur = (VALUE)p->start;
+
+    while  (... truncated)

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

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