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

ruby-changes:29953

From: ko1 <ko1@a...>
Date: Tue, 16 Jul 2013 19:29:42 +0900 (JST)
Subject: [ruby-changes:29953] ko1:r42005 (trunk): * gc.c: slim a path of newobj_of().

ko1	2013-07-16 19:29:31 +0900 (Tue, 16 Jul 2013)

  New Revision: 42005

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

  Log:
    * gc.c: slim a path of newobj_of().
    * gc.c (objspace): add a new field objspace::freelist, which contains
      available RVALUEs.
    * gc.c (newobj_of): simply call new function `get_freeobj()'.
      get_freeobj() returns objspace::freelist. If  objspace::freelist
      is not available, refill objspace::freelist with a slot pointed by
      objspace::heap::free_slots.
    * gc.c (before_gc_sweep): clear objspace::freelist.
    * gc.c (slot_sweep): clear slot::freelist.
    * gc.c (heaps_prepare_freeslot): renamed to heaps_prepare_freeslot.
    * gc.c (unlink_free_heap_slot): remove unused function.
    * gc.c (rb_free_const_table): remove unused function.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42004)
+++ ChangeLog	(revision 42005)
@@ -1,3 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jul 16 19:18:51 2013  Koichi Sasada  <ko1@a...>
+
+	* gc.c: slim a path of newobj_of().
+
+	* gc.c (objspace): add a new field objspace::freelist, which contains
+	  available RVALUEs.
+
+	* gc.c (newobj_of): simply call new function `get_freeobj()'.
+	  get_freeobj() returns objspace::freelist. If  objspace::freelist
+	  is not available, refill objspace::freelist with a slot pointed by
+	  objspace::heap::free_slots.
+
+	* gc.c (before_gc_sweep): clear objspace::freelist.
+
+	* gc.c (slot_sweep): clear slot::freelist.
+
+	* gc.c (heaps_prepare_freeslot): renamed to heaps_prepare_freeslot.
+
+	* gc.c (unlink_free_heap_slot): remove unused function.
+
+	* gc.c (rb_free_const_table): remove unused function.
+
 Tue Jul 16 19:05:12 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (big_shift3): Big shift width is not a problem for right
Index: gc.c
===================================================================
--- gc.c	(revision 42004)
+++ gc.c	(revision 42005)
@@ -372,6 +372,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L372
     size_t total_freed_object_num;
     rb_event_flag_t hook_events; /* this place may be affinity with memory cache */
     VALUE gc_stress;
+    RVALUE *freelist;
 
     struct mark_func_data_struct {
 	void *data;
@@ -500,7 +501,6 @@ VALUE *ruby_initial_gc_stress_ptr = &rb_ https://github.com/ruby/ruby/blob/trunk/gc.c#L501
 #endif
 
 #define RANY(o) ((RVALUE*)(o))
-#define has_free_object (objspace->heap.free_slots && objspace->heap.free_slots->freelist)
 
 int ruby_gc_debug_indent = 0;
 VALUE rb_mGC;
@@ -523,8 +523,8 @@ static void init_mark_stack(mark_stack_t https://github.com/ruby/ruby/blob/trunk/gc.c#L523
 static VALUE lazy_sweep_enable(void);
 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_prepare_free_objects(rb_objspace_t *);
 static void mark_tbl(rb_objspace_t *, st_table *);
+static int lazy_sweep(rb_objspace_t *objspace);
 static void rest_sweep(rb_objspace_t *);
 static void gc_mark_stacked_objects(rb_objspace_t *);
 
@@ -732,13 +732,6 @@ allocate_sorted_heaps(rb_objspace_t *obj https://github.com/ruby/ruby/blob/trunk/gc.c#L732
     }
 }
 
-static void
-unlink_free_heap_slot(rb_objspace_t *objspace, struct heaps_slot *slot)
-{
-    objspace->heap.free_slots = slot->free_next;
-    slot->free_next = NULL;
-}
-
 static inline void
 slot_add_freeobj(rb_objspace_t *objspace, struct heaps_slot *slot, VALUE obj)
 {
@@ -919,6 +912,83 @@ heaps_increment(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L912
     return FALSE;
 }
 
+static int
+ready_to_gc(rb_objspace_t *objspace)
+{
+    if (dont_gc || during_gc) {
+	if (!objspace->freelist && !objspace->heap.free_slots) {
+            if (!heaps_increment(objspace)) {
+		set_heaps_increment(objspace);
+                heaps_increment(objspace);
+            }
+	}
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static struct heaps_slot *
+heaps_prepare_freeslot(rb_objspace_t *objspace)
+{
+    if (!GC_ENABLE_LAZY_SWEEP && objspace->flags.dont_lazy_sweep) {
+	if (heaps_increment(objspace) == 0 &&
+	    garbage_collect(objspace, FALSE, TRUE, GPR_FLAG_NEWOBJ) == 0) {
+	    goto err;
+	}
+	goto ok;
+    }
+
+    if (!ready_to_gc(objspace)) return objspace->heap.free_slots;
+
+    during_gc++;
+
+    if ((is_lazy_sweeping(objspace) && lazy_sweep(objspace)) ||
+	heaps_increment(objspace)) {
+	goto ok;
+    }
+
+#if GC_PROFILE_MORE_DETAIL
+    objspace->profile.prepare_time = 0;
+#endif
+
+    if (garbage_collect_body(objspace, 0, 0, GPR_FLAG_NEWOBJ) == 0) {
+      err:
+	during_gc = 0;
+	rb_memerror();
+    }
+  ok:
+    during_gc = 0;
+    return objspace->heap.free_slots;
+}
+
+static inline struct heaps_slot *
+heaps_get_freeslot(rb_objspace_t *objspace)
+{
+    struct heaps_slot *slot;
+
+    slot = objspace->heap.free_slots;
+    while (slot == NULL) {
+	slot = heaps_prepare_freeslot(objspace);
+    }
+    objspace->heap.free_slots = slot->free_next;
+
+    return slot;
+}
+
+static inline VALUE
+get_freeobj(rb_objspace_t *objspace)
+{
+    RVALUE *p = objspace->freelist;
+
+    while (UNLIKELY(p == NULL)) {
+	struct heaps_slot *slot = heaps_get_freeslot(objspace);
+	p = objspace->freelist = slot->freelist;
+    }
+    objspace->freelist = p->as.free.next;
+
+    return (VALUE)p;
+}
+
 void
 rb_objspace_set_event_hook(const rb_event_flag_t event)
 {
@@ -939,7 +1009,6 @@ gc_event_hook_body(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/gc.c#L1009
     } \
 } while (0)
 
-
 static VALUE
 newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
 {
@@ -959,18 +1028,7 @@ newobj_of(VALUE klass, VALUE flags, VALU https://github.com/ruby/ruby/blob/trunk/gc.c#L1028
 	}
     }
 
-    if (UNLIKELY(!has_free_object)) {
-	if (!gc_prepare_free_objects(objspace)) {
-	    during_gc = 0;
-	    rb_memerror();
-	}
-    }
-
-    obj = (VALUE)objspace->heap.free_slots->freelist;
-    objspace->heap.free_slots->freelist = RANY(obj)->as.free.next;
-    if (objspace->heap.free_slots->freelist == NULL) {
-	unlink_free_heap_slot(objspace, objspace->heap.free_slots);
-    }
+    obj = get_freeobj(objspace);
 
     /* OBJSETUP */
     RBASIC(obj)->flags = flags;
@@ -1127,23 +1185,6 @@ rb_free_const_table(st_table *tbl) https://github.com/ruby/ruby/blob/trunk/gc.c#L1185
     st_free_table(tbl);
 }
 
-static int obj_free(rb_objspace_t *, VALUE);
-
-static inline struct heaps_slot *
-add_slot_local_freelist(rb_objspace_t *objspace, RVALUE *p)
-{
-    struct heaps_slot *slot;
-
-    (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
-    p->as.free.flags = 0;
-    slot = GET_HEAP_SLOT(p);
-    p->as.free.next = slot->freelist;
-    slot->freelist = p;
-    rgengc_report(3, objspace, "add_slot_local_freelist: %p (%s) is added to freelist\n", p, obj_type_name((VALUE)p));
-
-    return slot;
-}
-
 static void
 unlink_heap_slot(rb_objspace_t *objspace, struct heaps_slot *slot)
 {
@@ -2218,6 +2259,7 @@ slot_sweep(rb_objspace_t *objspace, stru https://github.com/ruby/ruby/blob/trunk/gc.c#L2259
 
     rgengc_report(1, objspace, "slot_sweep: start.\n");
 
+    sweep_slot->freelist = NULL;
     p = sweep_slot->header->start; pend = p + sweep_slot->header->limit;
     offset = p - NUM_IN_SLOT(p);
     bits = GET_HEAP_MARK_BITS(p);
@@ -2308,21 +2350,6 @@ slot_sweep(rb_objspace_t *objspace, stru https://github.com/ruby/ruby/blob/trunk/gc.c#L2350
     rgengc_report(1, objspace, "slot_sweep: end.\n");
 }
 
-static int
-ready_to_gc(rb_objspace_t *objspace)
-{
-    if (dont_gc || during_gc) {
-	if (!has_free_object) {
-            if (!heaps_increment(objspace)) {
-		set_heaps_increment(objspace);
-                heaps_increment(objspace);
-            }
-	}
-	return FALSE;
-    }
-    return TRUE;
-}
-
 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
 __attribute__((noinline))
 #endif
@@ -2341,6 +2368,7 @@ before_gc_sweep(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L2368
     objspace->heap.sweep_slots = heaps;
     objspace->heap.free_num = 0;
     objspace->heap.free_slots = NULL;
+    objspace->freelist = NULL;
 
     malloc_increase2 += ATOMIC_SIZE_EXCHANGE(malloc_increase,0);
 
@@ -2408,7 +2436,7 @@ lazy_sweep(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L2436
 
 	if (!next) after_gc_sweep(objspace);
 
-        if (has_free_object) {
+        if (objspace->heap.free_slots) {
             result = TRUE;
 	    break;
         }
@@ -2455,7 +2483,7 @@ gc_sweep(rb_objspace_t *objspace, int im https://github.com/ruby/ruby/blob/trunk/gc.c#L2483
 	lazy_sweep(objspace);
     }
 
-    if (!has_free_object) {
+    if (!objspace->heap.free_slots) {
 	/* there is no free after slot_sweep() */
 	set_heaps_increment(objspace);
 	if (!heaps_increment(objspace)) { /* can't allocate additional free objects */
@@ -2465,41 +2493,6 @@ gc_sweep(rb_objspace_t *objspace, int im https://github.com/ruby/ruby/blob/trunk/gc.c#L2493
     }
 }
 
-static int
-gc_prepare_free_objects(rb_objspace_t *objspace)
-{
-    if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_lazy_sweep) {
-	if (heaps_increment(objspace)) {
-	    return TRUE;
-	}
-	else {
-	    return garbage_collect(objspace, FALSE, TRUE, GPR_FLAG_NEWOBJ);
-	}
-    }
-
-    if (!ready_to_gc(objspace)) return TRUE;
-
-    during_gc++;
-
-    if (is_lazy_sweeping(objspace)) {
-	if (lazy_sweep(objspace)) {
-	    during_gc = 0;
-	    return TRUE;
-	}
-    }
-    else {
-        if (heaps_increment(objspace)) {
-	    during_gc = 0;
-            return TRUE;
-        }
-    }
-
-#if GC_PROFILE_MORE_DETAIL
-    objspace->profile.prepare_time = 0;
-#endif
-    return garbage_collect_body(objspace, 0, 0, GPR_FLAG_NEWOBJ);
-}
-
 /* Marking stack */
 
 static void push_mark_stack(mark_stack_t *, VALUE);

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

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