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

ruby-changes:29076

From: tarui <ko1@a...>
Date: Fri, 7 Jun 2013 11:33:48 +0900 (JST)
Subject: [ruby-changes:29076] tarui:r41128 (trunk): * gc.c: use oldgen bitmap as initial mark bitmap when mijor gc.

tarui	2013-06-07 11:32:57 +0900 (Fri, 07 Jun 2013)

  New Revision: 41128

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

  Log:
    * gc.c: use oldgen bitmap as initial mark bitmap when mijor gc.
      so can skip oldgen bitmap check around mark & sweep.
    * gc.c (slot_sweep_body): change scan algorithm for performance:
      from object's pointer base to bitmap one.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41127)
+++ ChangeLog	(revision 41128)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jun  7 11:28:37 2013  Masaya Tarui  <tarui@r...>
+
+	* gc.c: use oldgen bitmap as initial mark bitmap when mijor gc.
+	  so can skip oldgen bitmap check around mark & sweep.
+	* gc.c (slot_sweep_body): change scan algorithm for performance:
+	  from object's pointer base to bitmap one.
+
 Fri Jun  7 11:25:56 2013  Masaya Tarui  <tarui@r...>
 
 	* gc.c: introduce oldgen bitmap for preparing performance tuning.
Index: gc.c
===================================================================
--- gc.c	(revision 41127)
+++ gc.c	(revision 41128)
@@ -490,7 +490,7 @@ static const char *obj_type_name(VALUE o https://github.com/ruby/ruby/blob/trunk/gc.c#L490
 #if USE_RGENGC
 static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj);
 static void rgengc_remember(rb_objspace_t *objspace, VALUE obj);
-static void rgengc_rememberset_clear(rb_objspace_t *objspace);
+static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace);
 static size_t rgengc_rememberset_mark(rb_objspace_t *objspace);
 
 #define FL_TEST2(x,f)         ((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? (rb_bug("FL_TEST2: SPECIAL_CONST"), 0) : FL_TEST_RAW((x),(f)))
@@ -2122,97 +2122,88 @@ gc_clear_slot_bits(struct heaps_slot *sl https://github.com/ruby/ruby/blob/trunk/gc.c#L2122
     memset(slot->header->mark_bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
 }
 
-static size_t
-objspace_live_num(rb_objspace_t *objspace)
+#if USE_RGENGC
+static void
+gc_setup_mark_bits(struct heaps_slot *slot)
 {
-    return objspace->total_allocated_object_num - objspace->total_freed_object_num;
+    memcpy(slot->header->mark_bits, slot->header->oldgen_bits, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
 }
+#endif
 
-static inline int
-living_object_p(rb_objspace_t *objspace, VALUE p, uintptr_t *bits, const int during_minor_gc)
+static size_t
+objspace_live_num(rb_objspace_t *objspace)
 {
-#if USE_RGENGC
-    int reason = 0;
-
-    if (during_minor_gc) {
-	if (MARKED_IN_BITMAP(bits, p)) {
-	    reason = 1;
-	}
-	else if (RVALUE_PROMOTED(p)) {
-	    reason = 2;
-	}
-    }
-    else {
-	if (MARKED_IN_BITMAP(bits, p)) {
-	    reason = 1;
-	}
-    }
-
-    if (RGENGC_DEBUG && reason > 0) {
-	rgengc_report(5, objspace, "living_object_p: %p (%s) is living (%s).\n",
-		      (void *)p, obj_type_name(p), reason == 1 ? "marked" : "promoted");
-    }
-
-    if (RGENGC_CHECK_MODE && reason == 0 && rgengc_remembered(objspace, p)) {
-	rb_bug("living_object_p: %p (%s) is remembered, but not marked.\n", (void *)p, obj_type_name(p));
-    }
-
-    return reason != 0;
-#else /* USE_RGENGC */
-    return MARKED_IN_BITMAP(bits, p) != 0;
-#endif
+    return objspace->total_allocated_object_num - objspace->total_freed_object_num;
 }
 
 static inline void
 slot_sweep_body(rb_objspace_t *objspace, struct heaps_slot *sweep_slot, const int during_minor_gc)
 {
+    int i;
     size_t empty_num = 0, freed_num = 0, final_num = 0;
-    RVALUE *p, *pend;
+    RVALUE *p, *pend,*offset;
     RVALUE *final = deferred_final_list;
     int deferred;
-    uintptr_t *bits;
+    uintptr_t *bits, bitset;
 
     rgengc_report(3, objspace, "slot_sweep_body: start.\n");
 
     p = sweep_slot->header->start; pend = p + sweep_slot->header->limit;
+    offset = p - NUM_IN_SLOT(p);
     bits = GET_HEAP_MARK_BITS(p);
-    while (p < pend) {
-	if (!living_object_p(objspace, (VALUE)p, bits, during_minor_gc) && BUILTIN_TYPE(p) != T_ZOMBIE) {
-            if (p->as.basic.flags) {
-		rgengc_report(3, objspace, "slot_sweep_body: free %p (%s)\n", p, obj_type_name((VALUE)p));
 
+    /* create guard : fill 1 out-of-range */
+    bits[BITMAP_INDEX(p)] |= BITMAP_BIT(p)-1;
+    bits[BITMAP_INDEX(pend)] |= ~(BITMAP_BIT(pend) - 1);
+
+    for(i=0;i<HEAP_BITMAP_LIMIT;i++){
+	bitset = ~bits[i];
+	if(bitset){
+	    p = offset  + i * (sizeof(uintptr_t) *  CHAR_BIT);
+	    do {
+		if ((bitset & 1) && BUILTIN_TYPE(p) != T_ZOMBIE) {
+		    if (p->as.basic.flags) {
+			rgengc_report(3, objspace, "slot_sweep_body: free %p (%s)\n", p, obj_type_name((VALUE)p));
 #if USE_RGENGC && RGENGC_CHECK_MODE
-		if (objspace->rgengc.during_minor_gc && RVALUE_PROMOTED(p)) rb_bug("slot_sweep_body: %p (%s) is promoted.\n", p, obj_type_name((VALUE)p));
-		if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("slot_sweep_body: %p (%s) is remembered.\n", p, obj_type_name((VALUE)p));
+			if (objspace->rgengc.during_minor_gc && RVALUE_PROMOTED(p)) rb_bug("slot_sweep_body: %p (%s) is promoted.\n", p, obj_type_name((VALUE)p));
+			if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("slot_sweep_body: %p (%s) is remembered.\n", p, obj_type_name((VALUE)p));
 #endif
-
-		if ((deferred = obj_free(objspace, (VALUE)p)) ||
-                    (FL_TEST(p, FL_FINALIZE))) {
-                    if (!deferred) {
-                        p->as.free.flags = T_ZOMBIE;
-                        RDATA(p)->dfree = 0;
-                    }
-                    p->as.free.next = deferred_final_list;
-                    deferred_final_list = p;
-                    assert(BUILTIN_TYPE(p) == T_ZOMBIE);
-                    final_num++;
-                }
-                else {
-                    (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
-                    p->as.free.flags = 0;
-                    p->as.free.next = sweep_slot->freelist;
-                    sweep_slot->freelist = p;
-		    rgengc_report(3, objspace, "slot_sweep_body: %p (%s) is added to freelist\n", p, obj_type_name((VALUE)p));
-                    freed_num++;
-                }
-            }
-            else {
-                empty_num++;
-            }
-        }
-        p++;
+			if ((deferred = obj_free(objspace, (VALUE)p)) ||
+			    (FL_TEST(p, FL_FINALIZE))) {
+			    if (!deferred) {
+				p->as.free.flags = T_ZOMBIE;
+				
+				RDATA(p)->dfree = 0;
+			    }
+			    p->as.free.next = deferred_final_list;
+			    deferred_final_list = p;
+			    assert(BUILTIN_TYPE(p) == T_ZOMBIE);
+			    final_num++;
+			}
+			else {
+			    (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
+			    p->as.free.flags = 0;
+			    p->as.free.next = sweep_slot->freelist;
+			    sweep_slot->freelist = p;
+			    rgengc_report(3, objspace, "slot_sweep_body: %p (%s) is added to freelist\n", p, obj_type_name((VALUE)p));
+			    freed_num++;
+			}
+		    }
+		    else {
+			empty_num++;
+		    }
+		}
+		p++;
+		bitset >>= 1;
+	    } while (bitset);
+	}
     }
+#if USE_RGENGC
+    gc_setup_mark_bits(sweep_slot);
+#else
     gc_clear_slot_bits(sweep_slot);
+#endif
+
     if (final_num + freed_num + empty_num == sweep_slot->header->limit &&
         objspace->heap.free_num > objspace->heap.do_heap_free) {
         RVALUE *pp;
@@ -3005,15 +2996,6 @@ gc_mark(rb_objspace_t *objspace, VALUE p https://github.com/ruby/ruby/blob/trunk/gc.c#L2996
     if (LIKELY(objspace->mark_func_data == 0)) {
 	rgengc_check_shady(objspace, ptr);
 	if (!gc_mark_ptr(objspace, ptr)) return; /* already marked */
-#if USE_RGENGC
-	if (objspace->rgengc.during_minor_gc) {
-	    /* only minor gc skip marking promoted objects */
-	    if (RVALUE_PROMOTED(ptr)) {
-		rgengc_report(3, objspace, "gc_mark: %p (%s) was promoted.\n", ptr, obj_type_name((VALUE)ptr));
-		return; /* old gen */
-	    }
-	}
-#endif /* USE_RGENGC */
 	push_mark_stack(&objspace->mark_stack, ptr);
     }
     else {
@@ -3386,7 +3368,7 @@ gc_marks_body(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3368
     }
     else {
 	objspace->profile.major_gc_count++;
-	rgengc_rememberset_clear(objspace);
+	rgengc_mark_and_rememberset_clear(objspace);
     }
 #endif
 
@@ -3514,7 +3496,6 @@ gc_marks(rb_objspace_t *objspace, int mi https://github.com/ruby/ruby/blob/trunk/gc.c#L3496
 	/* setup marking */
 	prev_mark_func_data = objspace->mark_func_data;
 	objspace->mark_func_data = 0;
-
 	objspace->count++;
 
 	SET_STACK_END;
@@ -3626,10 +3607,10 @@ rgengc_rememberset_mark(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L3607
 	    if(bits[j]){
 		p = offset  + j * (sizeof(uintptr_t) *  CHAR_BIT);
 		bitset = bits[j];
-		while (bitset) {
+		do {
 		    if (bitset & 1) {
-			if (gc_mark_ptr(objspace, (VALUE)p))
-			    push_mark_stack(&objspace->mark_stack, (VALUE) p);
+			gc_mark_ptr(objspace, (VALUE)p);
+			push_mark_stack(&objspace->mark_stack, (VALUE) p);
 			rgengc_report(2, objspace, "rgengc_rememberset_mark: mark %p (%s)\n", p, obj_type_name((VALUE)p));
 
 			if (!RVALUE_SHADY(p)) {
@@ -3641,8 +3622,8 @@ rgengc_rememberset_mark(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L3622
 			}
 		    }
 		    p++;
-		    bitset>>=1;
-		}
+		    bitset >>= 1;
+		} while (bitset);
 	    }
 	}
     }
@@ -3653,13 +3634,13 @@ rgengc_rememberset_mark(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L3634
 }
 
 static void
-rgengc_rememberset_clear(rb_objspace_t *objspace)
+rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace)
 {
     size_t i;
 
     for (i=0; i<heaps_used; i++) {
-	uintptr_t *bits = objspace->heap.sorted[i]->rememberset_bits;
-	memset(bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
+	memset(objspace->heap.sorted[i]->mark_bits,        0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
+	memset(objspace->heap.sorted[i]->rememberset_bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t));
     }
 }
 

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

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