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

ruby-changes:35362

From: ko1 <ko1@a...>
Date: Mon, 8 Sep 2014 13:11:19 +0900 (JST)
Subject: [ruby-changes:35362] ko1:r47444 (trunk): * gc.c: add incremental GC algorithm. [Feature #10137]

ko1	2014-09-08 13:11:00 +0900 (Mon, 08 Sep 2014)

  New Revision: 47444

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47444

  Log:
    * gc.c: add incremental GC algorithm. [Feature #10137]
      Please refer this ticket for details.
      This change also introduces the following changes.
      * Remove RGENGC_AGE2_PROMOTION and introduce object age (0 to 3).
        Age can be count with FL_PROMOTE0 and FL_PROMOTE1 flags in
        RBasic::flags (2 bit). Age == 3 objects become old objects.
      * WB_PROTECTED flag in RBasic to WB_UNPROTECTED bitmap.
      * LONG_LIVED bitmap to represent living objects while minor GCs
        It specifies (1) Old objects and (2) remembered shady objects.
      * Introduce rb_objspace_t::marked_objects which counts marked
        objects in current marking phase. marking count is needed to
        introduce incremental marking.
      * rename mark related function and sweep related function to
        gc_(marks|sweep)_(start|finish|step|rest|continue).
      * rename rgengc_report() to gc_report().
      * Add obj_info() function to get cstr of object details.
      * Add MEASURE_LINE() macro to measure execution time of specific line.
      * and many small fixes.
    * include/ruby/ruby.h: add flag USE_RINCGC.
      Now USE_RINCGC can be set only with USE_RGENGC.
    * include/ruby/ruby.h: introduce FL_PROMOTED0 and add FL_PROMOTED1
      to count object age.
    * include/ruby/ruby.h: rewrite write barriers for incremental marking.
    * debug.c: catch up flag name changes.
    * internal.h: add rb_gc_writebarrier_remember() instead of
      rb_gc_writebarrier_remember_promoted().
    * array.c (ary_memcpy0): use rb_gc_writebarrier_remember().
    * array.c (rb_ary_modify): ditto.
    * hash.c (rb_hash_keys): ditto.
    * hash.c (rb_hash_values): ditto.
    * object.c (init_copy): use rb_copy_wb_protected_attribute() because
      FL_WB_PROTECTED is moved from RBasic::flags.
    * test/objspace/test_objspace.rb: catch up ObjectSpace.dump() changes.

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/debug.c
    trunk/gc.c
    trunk/hash.c
    trunk/include/ruby/ruby.h
    trunk/internal.h
    trunk/object.c
    trunk/test/objspace/test_objspace.rb
Index: array.c
===================================================================
--- array.c	(revision 47443)
+++ array.c	(revision 47444)
@@ -172,25 +172,18 @@ ary_memcpy0(VALUE ary, long beg, long ar https://github.com/ruby/ruby/blob/trunk/array.c#L172
 #if 1
     assert(!ARY_SHARED_P(buff_owner_ary));
 
-    if (OBJ_PROMOTED(buff_owner_ary)) {
-	if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
-	    rb_gc_writebarrier_remember_promoted(buff_owner_ary);
-	    RARRAY_PTR_USE(ary, ptr, {
-		MEMCPY(ptr+beg, argv, VALUE, argc);
-	    });
-	}
-	else {
-	    int i;
-	    RARRAY_PTR_USE(ary, ptr, {
-		for (i=0; i<argc; i++) {
-		    RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
-		}
-	    });
-	}
+    if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
+	rb_gc_writebarrier_remember(buff_owner_ary);
+	RARRAY_PTR_USE(ary, ptr, {
+	    MEMCPY(ptr+beg, argv, VALUE, argc);
+	});
     }
     else {
+	int i;
 	RARRAY_PTR_USE(ary, ptr, {
-	    MEMCPY(ptr+beg, argv, VALUE, argc);
+	    for (i=0; i<argc; i++) {
+		RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
+	    }
 	});
     }
 #else
@@ -355,10 +348,7 @@ rb_ary_modify(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L348
             ARY_SET_PTR(ary, ptr);
         }
 
-	/* TODO: age2 promotion, OBJ_PROMOTED() checks not infant. */
-	if (OBJ_PROMOTED(ary) && !OBJ_PROMOTED(shared)) {
-	    rb_gc_writebarrier_remember_promoted(ary);
-	}
+	rb_gc_writebarrier_remember(ary);
     }
 }
 
Index: debug.c
===================================================================
--- debug.c	(revision 47443)
+++ debug.c	(revision 47444)
@@ -33,8 +33,8 @@ const union { https://github.com/ruby/ruby/blob/trunk/debug.c#L33
         RUBY_ENC_CODERANGE_7BIT    = ENC_CODERANGE_7BIT,
         RUBY_ENC_CODERANGE_VALID   = ENC_CODERANGE_VALID,
         RUBY_ENC_CODERANGE_BROKEN  = ENC_CODERANGE_BROKEN,
-        RUBY_FL_WB_PROTECTED     = FL_WB_PROTECTED,
-        RUBY_FL_PROMOTED    = FL_PROMOTED,
+        RUBY_FL_PROMOTED0   = FL_PROMOTED0,
+        RUBY_FL_PROMOTED1   = FL_PROMOTED1,
         RUBY_FL_FINALIZE    = FL_FINALIZE,
         RUBY_FL_TAINT       = FL_TAINT,
         RUBY_FL_EXIVAR      = FL_EXIVAR,
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 47443)
+++ include/ruby/ruby.h	(revision 47444)
@@ -710,6 +710,13 @@ VALUE rb_obj_setup(VALUE obj, VALUE klas https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L710
 
 #ifndef USE_RGENGC
 #define USE_RGENGC 1
+#ifndef USE_RINCGC
+#define USE_RINCGC 1
+#endif
+#endif
+
+#if USE_RGENGC == 0
+#define USE_RINCGC 0
 #endif
 
 #ifndef RGENGC_WB_PROTECTED_ARRAY
@@ -1068,7 +1075,8 @@ struct RStruct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1075
 
 #define FL_SINGLETON FL_USER0
 #define FL_WB_PROTECTED (((VALUE)1)<<5)
-#define FL_PROMOTED  (((VALUE)1)<<6)
+#define FL_PROMOTED0 (((VALUE)1)<<5)
+#define FL_PROMOTED1 (((VALUE)1)<<6)
 #define FL_FINALIZE  (((VALUE)1)<<7)
 #define FL_TAINT     (((VALUE)1)<<8)
 #define FL_UNTRUSTED FL_TAINT
@@ -1122,16 +1130,20 @@ struct RStruct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1130
 #define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
 
 #if USE_RGENGC
-#define OBJ_PROMOTED(x)             (SPECIAL_CONST_P(x) ? 0 : FL_TEST_RAW((x), FL_PROMOTED))
-#define OBJ_WB_PROTECTED(x)         (SPECIAL_CONST_P(x) ? 1 : FL_TEST_RAW((x), FL_WB_PROTECTED))
+#define OBJ_PROMOTED_RAW(x)         ((RBASIC(x)->flags & (FL_PROMOTED0|FL_PROMOTED1)) == (FL_PROMOTED0|FL_PROMOTED1))
+#define OBJ_PROMOTED(x)             (SPECIAL_CONST_P(x) ? 0 : OBJ_PROMOTED_RAW(x))
 #define OBJ_WB_UNPROTECT(x)         rb_obj_wb_unprotect(x, __FILE__, __LINE__)
 
-void rb_gc_writebarrier(VALUE a, VALUE b);
-void rb_gc_writebarrier_unprotect_promoted(VALUE obj);
+#if USE_RINCGC
+int rb_gc_writebarrier_incremental(VALUE a, VALUE b);
+#else
+#define rb_gc_writebarrier_incremental(a, b) 0
+#endif
+void rb_gc_writebarrier_generational(VALUE a, VALUE b);
+void rb_gc_writebarrier_unprotect(VALUE obj);
 
 #else /* USE_RGENGC */
 #define OBJ_PROMOTED(x)             0
-#define OBJ_WB_PROTECTED(x)         0
 #define OBJ_WB_UNPROTECT(x)         rb_obj_wb_unprotect(x, __FILE__, __LINE__)
 #endif
 
@@ -1164,15 +1176,8 @@ rb_obj_wb_unprotect(VALUE x, RB_UNUSED_V https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1176
 #ifdef RGENGC_LOGGING_WB_UNPROTECT
     RGENGC_LOGGING_WB_UNPROTECT((void *)x, filename, line);
 #endif
-
 #if USE_RGENGC
-    /* `x' should be an RVALUE object */
-    if (FL_TEST_RAW((x), FL_WB_PROTECTED)) {
-	if (FL_TEST_RAW((x), FL_PROMOTED)) {
-	    rb_gc_writebarrier_unprotect_promoted(x);
-	}
-	RBASIC(x)->flags &= ~FL_WB_PROTECTED;
-    }
+    rb_gc_writebarrier_unprotect(x);
 #endif
     return x;
 }
@@ -1185,9 +1190,12 @@ rb_obj_written(VALUE a, RB_UNUSED_VAR(VA https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1190
 #endif
 
 #if USE_RGENGC
-    /* `a' should be an RVALUE object */
-    if (FL_TEST_RAW((a), FL_PROMOTED) && !SPECIAL_CONST_P(b)) {
-	rb_gc_writebarrier(a, b);
+    if (!SPECIAL_CONST_P(b)) {
+	if (rb_gc_writebarrier_incremental(a, b) == 0) {
+	    if (OBJ_PROMOTED_RAW(a) && !OBJ_PROMOTED_RAW(b)) {
+		rb_gc_writebarrier_generational(a, b);
+	    }
+	}
     }
 #endif
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47443)
+++ ChangeLog	(revision 47444)
@@ -1,3 +1,53 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Sep  8 12:01:39 2014  Koichi Sasada  <ko1@a...>
+
+	* gc.c: add incremental GC algorithm. [Feature #10137]
+
+	  Please refer this ticket for details.
+
+	  This change also introduces the following changes.
+
+	  * Remove RGENGC_AGE2_PROMOTION and introduce object age (0 to 3).
+	    Age can be count with FL_PROMOTE0 and FL_PROMOTE1 flags in
+	    RBasic::flags (2 bit). Age == 3 objects become old objects.
+	  * WB_PROTECTED flag in RBasic to WB_UNPROTECTED bitmap.
+	  * LONG_LIVED bitmap to represent living objects while minor GCs
+	    It specifies (1) Old objects and (2) remembered shady objects.
+	  * Introduce rb_objspace_t::marked_objects which counts marked
+	    objects in current marking phase. marking count is needed to
+	    introduce incremental marking.
+	  * rename mark related function and sweep related function to
+	    gc_(marks|sweep)_(start|finish|step|rest|continue).
+	  * rename rgengc_report() to gc_report().
+	  * Add obj_info() function to get cstr of object details.
+	  * Add MEASURE_LINE() macro to measure execution time of specific line.
+	  * and many small fixes.
+
+	* include/ruby/ruby.h: add flag USE_RINCGC.
+	  Now USE_RINCGC can be set only with USE_RGENGC.
+
+	* include/ruby/ruby.h: introduce FL_PROMOTED0 and add FL_PROMOTED1
+	  to count object age.
+
+	* include/ruby/ruby.h: rewrite write barriers for incremental marking.
+
+	* debug.c: catch up flag name changes.
+
+	* internal.h: add rb_gc_writebarrier_remember() instead of
+	  rb_gc_writebarrier_remember_promoted().
+
+	* array.c (ary_memcpy0): use rb_gc_writebarrier_remember().
+
+	* array.c (rb_ary_modify): ditto.
+
+	* hash.c (rb_hash_keys): ditto.
+
+	* hash.c (rb_hash_values): ditto.
+
+	* object.c (init_copy): use rb_copy_wb_protected_attribute() because
+	  FL_WB_PROTECTED is moved from RBasic::flags.
+
+	* test/objspace/test_objspace.rb: catch up ObjectSpace.dump() changes.
+
 Sun Sep  7 12:47:06 2014  Tanaka Akira  <akr@f...>
 
 	* process.c: PTHREAD_CANCEL_DISABLE is not defined on Android.
Index: object.c
===================================================================
--- object.c	(revision 47443)
+++ object.c	(revision 47444)
@@ -282,6 +282,8 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L282
     }
 }
 
+void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
+
 static void
 init_copy(VALUE dest, VALUE obj)
 {
@@ -290,6 +292,7 @@ init_copy(VALUE dest, VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L292
     }
     RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
     RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
+    rb_copy_wb_protected_attribute(dest, obj);
     rb_copy_generic_ivar(dest, obj);
     rb_gc_copy_finalizer(dest, obj);
     if (RB_TYPE_P(obj, T_OBJECT)) {
@@ -331,8 +334,8 @@ rb_obj_clone(VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L334
         rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
     }
     clone = rb_obj_alloc(rb_obj_class(obj));
-    RBASIC(clone)->flags &= (FL_TAINT|FL_PROMOTED|FL_WB_PROTECTED);
-    RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_PROMOTED|FL_FREEZE|FL_FINALIZE|FL_WB_PROTECTED);
+    RBASIC(clone)->flags &= (FL_TAINT);
+    RBASIC(clone)->flags |= RBASIC(obj)->flags & ~(FL_PROMOTED0|FL_PROMOTED1|FL_FREEZE|FL_FINALIZE);
 
     singleton = rb_singleton_class_clone_and_attach(obj, clone);
     RBASIC_SET_CLASS(clone, singleton);
Index: gc.c
===================================================================
--- gc.c	(revision 47443)
+++ gc.c	(revision 47444)
@@ -143,6 +143,19 @@ rb_gc_guarded_ptr_val(volatile VALUE *pt https://github.com/ruby/ruby/blob/trunk/gc.c#L143
 #define GC_OLDMALLOC_LIMIT_MAX (128 * 1024 * 1024 /* 128MB */)
 #endif
 
+#ifndef PRINT_MEASURE_LINE
+#define PRINT_MEASURE_LINE 0
+#endif
+#ifndef PRINT_ENTER_EXIT_TICK
+#define PRINT_ENTER_EXIT_TICK 0
+#endif
+#ifndef PRINT_ROOT_TICKS
+#define PRINT_ROOT_TICKS 0
+#endif
+
+#define USE_TICK_T                 (PRINT_ENTER_EXIT_TICK || PRINT_MEASURE_LINE)
+#define TICK_TYPE 1
+
 typedef struct {
     size_t heap_init_slots;
     size_t heap_free_slots;
@@ -199,9 +212,10 @@ static ruby_gc_params_t gc_params = { https://github.com/ruby/ruby/blob/trunk/gc.c#L212
 /* RGENGC_CHECK_MODE
  * 0: disable all assertions
  * 1: enable assertions (to debug RGenGC)
- * 2: enable generational bits check (for debugging)
- * 3: enable livness check
- * 4: show all references
+ * 2: enable internal consistency check at each GC (for debugging)
+ * 3: enable internal consistency check at each GC steps (for debugging)
+ * 4: enable livness check
+ * 5: show all references
  */
 #ifndef RGENGC_CHECK_MODE
 #define RGENGC_CHECK_MODE  0
@@ -216,15 +230,6 @@ static ruby_gc_params_t gc_params = { https://github.com/ruby/ruby/blob/trunk/gc.c#L230
 #define RGENGC_PROFILE     0
 #endif
 
-/* RGENGC_AGE2_PROMOTION
- * Enable/disable age2 promotion strategy
- * 0: Infant gen -> Old gen
- * 1: Infant gen -> Young -> Old gen
- */
-#ifndef RGENGC_AGE2_PROMOTION
-#define RGENGC_AGE2_PROMOTION 1
-#endif
-
 /* RGENGC_ESTIMATE_OLDMALLOC
  * Enable/disable to estimate increase size of malloc'ed size by old objects.
  * If estimation exceeds threshold, then will invoke full GC.
@@ -235,13 +240,26 @@ static ruby_gc_params_t gc_params = { https://github.com/ruby/ruby/blob/trunk/gc.c#L240
 #define RGENGC_ESTIMATE_OLDMALLOC 1
 #endif
 
+/* RGENGC_FORCE_MAJOR_GC
+ * Force major/full GC if this macro is not 0.
+ */
+#ifndef RGENGC_FORCE_MAJOR_GC
+#define RGENGC_FORCE_MAJOR_GC 0
+#endif
+
 #else /* USE_RGENGC */
 
+#ifdef RGENGC_DEBUG
+#undef RGENGC_DEBUG
+#endif
 #define RGENGC_DEBUG       0
+#ifdef RGENGC_CHECK_MODE
+#undef RGENGC_CHECK_MODE
+#endif
 #define RGENGC_CHECK_MODE  0
 #define RGENGC_PROFILE     0
-#define RGENGC_AGE2_PROMOTION    0
 #define RGENGC_ESTIMATE_OLDMALLOC 0
+#define RGENGC_FORCE_MAJOR_GC 0
 
 #endif /* USE_RGENGC */
 
@@ -251,6 +269,9 @@ static ruby_gc_params_t gc_params = { https://github.com/ruby/ruby/blob/trunk/gc.c#L269
 #ifndef GC_PROFILE_DETAIL_MEMORY
 #define GC_PROFILE_DETAIL_MEMORY 0
 #endif
+#ifndef GC_ENABLE_INCREMENTAL_MARK
+#define GC_ENABLE_INCREMENTAL_MARK USE_RINCGC
+#endif
 #ifndef GC_ENABLE_LAZY_SWEEP
 #define GC_ENABLE_LAZY_SWEEP   1
 #endif
@@ -409,8 +430,8 @@ typedef struct stack_chunk { https://github.com/ruby/ruby/blob/trunk/gc.c#L430
 typedef struct mark_stack {
     stack_chunk_t *chunk;
     stack_chunk_t *cache;
-    size_t index;
-    size_t limit;
+    int index;
+    int limit;
     size_t cache_size;
     size_t unused_cache_size;
 } mark_stack_t;
@@ -420,11 +441,19 @@ typedef struct rb_heap_struct { https://github.com/ruby/ruby/blob/trunk/gc.c#L441
     struct heap_page *free_pages;
     struct heap_page *using_page;
     struct heap_page *sweep_pages;
+    struct heap_page *pooled_pages;
+
     RVALUE *freelist;
     size_t page_length;      /* total page count in a heap */
     size_t total_slots;      /* total slot count (page_length * HEAP_OBJ_LIMIT) */
 } rb_heap_t;
 
+enum gc_stat {
+    none,
+    marking,
+    sweeping
+};
+
 typedef struct rb_objspace {
     struct {
 	size_t limit;
@@ -435,6 +464,11 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L464
 #endif
     } malloc_params;
 
+    enum gc_stat stat;
+    size_t marked_objects;
+
+    int immediate_sweep;
+
     rb_heap_t eden_heap;
     rb_heap_t tomb_heap; /* heap for zombies and ghosts */
 
@@ -458,7 +492,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L492
 
     struct {
 	int dont_gc;
-	int dont_lazy_sweep;
+	int dont_incremental;
 	int during_gc;
 	rb_atomic_t finalizing;
     } flags;
@@ -484,9 +518,6 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L518
 	size_t generated_shady_object_count;
 	size_t shade_operation_count;
 	size_t promote_infant_count;
-#if RGENGC_AGE2_PROMOTION
-	size_t promote_young_count;
-#endif
 	size_t remembered_normal_object_count;
 	size_t remembered_shady_object_count;
 
@@ -495,9 +526,6 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L526
 	size_t generated_shady_object_count_types[RUBY_T_MASK];
 	size_t shade_operation_count_types[RUBY_T_MASK];
 	size_t promote_infant_types[RUBY_T_MASK];
-#if RGENGC_AGE2_PROMOTION
-	size_t promote_young_types[RUBY_T_MASK];
-#endif
 	size_t remembered_normal_object_count_types[RUBY_T_MASK];
 	size_t remembered_shady_object_count_types[RUBY_T_MASK];
 #endif
@@ -534,10 +562,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L562
 	size_t remembered_shady_object_limit;
 	size_t old_object_count;
 	size_t old_object_limit;
-
-#if RGENGC_AGE2_PROMOTION
-	size_t young_object_count;
-#endif
+	size_t old_object_count_at_gc_start;
 
 #if RGENGC_ESTIMATE_OLDMALLOC
 	size_t oldmalloc_increase;
@@ -550,6 +575,12 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L575
 #endif
     } rgengc;
 #endif /* USE_RGENGC */
+
+#if USE_RINCGC
+    struct {
+	int during_incremental_marking;
+    } rincgc;
+#endif
 } rb_objspace_t;
 
 
@@ -571,38 +602,56 @@ enum { https://github.com/ruby/ruby/blob/trunk/gc.c#L602
 
 struct heap_page {
     struct heap_page_body *body;
-    RVALUE *freelist;
-    RVALUE *start;
-    size_t final_slots;
-    size_t limit;
-    struct heap_page *next;
     struct heap_page *prev;
-    struct heap_page *free_next;
     rb_heap_t *heap;
-    int before_sweep;
+    int total_slots;
+    int free_slots;
+    int final_slots;
+
+    struct heap_page *free_next;
+    RVALUE *start;
+    RVALUE *freelist;
+    struct heap_page *next;
 
+    struct {
+	unsigned int before_sweep : 1;
+	unsigned int has_remembered_objects : 1;
+	unsigned int has_long_lived_shady_objects : 1;
+    } flags;
+
+#if USE_RGENGC
+    bits_t wb_unprotected_bits[HEAP_BITMAP_LIMIT];
+#endif
+    /* the following three bitmaps are cleared at the beggining of full GC */
     bits_t mark_bits[HEAP_BITMAP_LIMIT];
 #if USE_RGENGC
-    bits_t rememberset_bits[HEAP_BITMAP_LIMIT];
-    bits_t oldgen_bits[HEAP_BITMAP_LIMIT];
+    bits_t long_lived_bits[HEAP_BITMAP_LIMIT];
+    bits_t marking_bits[HEAP_BITMAP_LIMIT];
 #endif
 };
 
-#define GET_PAGE_BODY(x)             ((struct heap_page_body *)((bits_t)(x) & ~(HEAP_ALIGN_MASK)))
-#define GET_PAGE_HEADER(x)           (&GET_PAGE_BODY(x)->header)
-#define GET_HEAP_PAGE(x)             (GET_PAGE_HEADER(x)->page)
-#define GET_HEAP_MARK_BITS(x)        (&GET_HEAP_PAGE(x)->mark_bits[0])
-#define GET_HEAP_REMEMBERSET_BITS(x) (&GET_HEAP_PAGE(x)->rememberset_bits[0])
-#define GET_HEAP_OLDGEN_BITS(x)      (&GET_HEAP_PAGE(x)->oldgen_bits[0])
-#define NUM_IN_PAGE(p)               (((bits_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE))
-#define BITMAP_INDEX(p)              (NUM_IN_PAGE(p) / BITS_BITLENGTH )
-#define BITMAP_OFFSET(p)             (NUM_IN_PAGE(p) & (BITS_BITLENGTH-1))
-#define BITMAP_BIT(p)                ((bits_t)1 << BITMAP_OFFSET(p))
+#define GET_PAGE_BODY(x)   ((struct heap_page_body *)((bits_t)(x) & ~(HEAP_ALIGN_MASK)))
+#define GET_PAGE_HEADER(x) (&GET_PAGE_BODY(x)->header)
+#define GET_HEAP_PAGE(x)   (GET_PAGE_HEADER(x)->page)
+
+#define NUM_IN_PAGE(p)   (((bits_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE))
+#define BITMAP_INDEX(p)  (NUM_IN_PAGE(p) / BITS_BITLENGTH )
+#define BITMAP_OFFSET(p) (NUM_IN_PAGE(p) & (BITS_BITLENGTH-1))
+#define BITMAP_BIT(p)    ((bits_t)1 << BITMAP_OFFSET(p))
+
 /* Bitmap Operations */
 #define MARKED_IN_BITMAP(bits, p)    ((bits)[BITMAP_INDEX(p)] & BITMAP_BIT(p))
 #define MARK_IN_BITMAP(bits, p)      ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] | BITMAP_BIT(p))
 #define CLEAR_IN_BITMAP(bits, p)     ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] & ~BITMAP_BIT(p))
 
+/* getting bitmap */
+#define GET_HEAP_MARK_BITS(x)           (&GET_HEAP_PAGE(x)->mark_bits[0])
+#if USE_RGENGC
+#define GET_HEAP_LONG_LIVED_BITS(x)     (&GET_HEAP_PAGE(x)->long_lived_bits[0])
+#define GET_HEAP_WB_UNPROTECTED_BITS(x) (&GET_HEAP_PAGE(x)->wb_unprotected_bits[0])
+#define GET_HEAP_MARKING_BITS(x)        (&GET_HEAP_PAGE(x)->marking_bits[0])
+#endif
+
 /* Aliases */
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
 #define rb_objspace (*GET_VM()->objspace)
@@ -636,7 +685,21 @@ VALUE *ruby_initial_gc_stress_ptr = &rb_ https://github.com/ruby/ruby/blob/trunk/gc.c#L685
 #define global_list		objspace->global_list
 #define ruby_gc_stress		objspace->gc_stress
 
-#define is_lazy_sweeping(heap) ((heap)->sweep_pages != 0)
+#define is_marking(objspace)             ((objspace)->stat == marking)
+#define is_sweeping(objspace)            ((objspace)->stat == sweeping)
+#define is_full_marking(objspace)        ((objspace)->rgengc.during_minor_gc == FALSE)
+#if GC_ENABLE_INCREMENTAL_MARK
+#define is_incremental_marking(objspace) ((objspace)->rincgc.during_incremental_marking != FALSE)
+#else
+#define is_incremental_marking(objspace) 0
+#endif
+#define is_lazy_sweeping(heap)           (GC_ENABLE_LAZY_SWEEP       && (heap)->sweep_pages != 0)
+#if GC_ENABLE_INCREMENTAL_MARK
+#define will_be_incremental_marking(objspace) ((objspace)->rgengc.need_major_gc != GPR_FLAG_NONE)
+#else
+#define will_be_incremental_marking(objspace) 0
+#endif
+
 #if SIZEOF_LONG == SIZEOF_VOIDP
 # define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG)
 # define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) /* unset FIXNUM_FLAG */
@@ -676,22 +739,48 @@ static void aligned_free(void *); https://github.com/ruby/ruby/blob/trunk/gc.c#L739
 
 static void init_mark_stack(mark_stack_t *stack);
 
-static VALUE lazy_sweep_enable(void);
 static int ready_to_gc(rb_objspace_t *objspace);
-static int heap_ready_to_gc(rb_objspace_t *objspace, rb_heap_t *heap);
-static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_sweep, int reason);
-static int garbage_collect_body(rb_objspace_t *, int full_mark, int immediate_sweep, int reason);
-static int gc_heap_lazy_sweep(rb_objspace_t *objspace, rb_heap_t *heap);
-static void gc_rest_sweep(rb_objspace_t *objspace);
-static void gc_heap_rest_sweep(rb_objspace_t *objspace, rb_heap_t *heap);
 
-static void gc_mark_stacked_objects(rb_objspace_t *);
+static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_mark, int immediate_sweep, int reason);
+
+static int  gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mar (... truncated)

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

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