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

ruby-changes:29401

From: ko1 <ko1@a...>
Date: Thu, 20 Jun 2013 05:44:45 +0900 (JST)
Subject: [ruby-changes:29401] ko1:r41453 (trunk): * gc.c: Accumulate sweep time to GC time.

ko1	2013-06-20 05:43:33 +0900 (Thu, 20 Jun 2013)

  New Revision: 41453

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

  Log:
    * gc.c: Accumulate sweep time to GC time.
      Now [GC time] is [mark time] + [sweep time] + [misc].
      ([GC time] >= [mark time] + [sweep time])
    * gc.c (gc_prof_sweep_slot_timer_start/stop): rename to
      gc_prof_sweep_timer_start/stop and locate at lazy_sweep().
    * gc.c (elapsed_time_from): add a utility function.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41452)
+++ ChangeLog	(revision 41453)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jun 20 05:38:56 2013  Koichi Sasada  <ko1@a...>
+
+	* gc.c: Accumulate sweep time to GC time.
+	  Now [GC time] is [mark time] + [sweep time] + [misc].
+	  ([GC time] >= [mark time] + [sweep time])
+
+	* gc.c (gc_prof_sweep_slot_timer_start/stop): rename to
+	  gc_prof_sweep_timer_start/stop and locate at lazy_sweep().
+
+	* gc.c (elapsed_time_from): add a utility function.
+
 Thu Jun 20 05:08:53 2013  Koichi Sasada  <ko1@a...>
 
 	* gc.c (gc_marks): fix wrong option. FALSE means major/full GC.
Index: gc.c
===================================================================
--- gc.c	(revision 41452)
+++ gc.c	(revision 41453)
@@ -501,8 +501,8 @@ static inline void gc_prof_timer_start(r https://github.com/ruby/ruby/blob/trunk/gc.c#L501
 static inline void gc_prof_timer_stop(rb_objspace_t *);
 static inline void gc_prof_mark_timer_start(rb_objspace_t *);
 static inline void gc_prof_mark_timer_stop(rb_objspace_t *);
-static inline void gc_prof_sweep_slot_timer_start(rb_objspace_t *);
-static inline void gc_prof_sweep_slot_timer_stop(rb_objspace_t *);
+static inline void gc_prof_sweep_timer_start(rb_objspace_t *);
+static inline void gc_prof_sweep_timer_stop(rb_objspace_t *);
 static inline void gc_prof_set_malloc_info(rb_objspace_t *);
 
 static const char *obj_type_name(VALUE obj);
@@ -2311,7 +2311,6 @@ static void https://github.com/ruby/ruby/blob/trunk/gc.c#L2311
 slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
 {
     rgengc_report(1, objspace, "slot_sweep: start\n");
-    gc_prof_sweep_slot_timer_start(objspace);
     {
 #if USE_RGENGC
 	if (objspace->rgengc.during_minor_gc) {
@@ -2324,7 +2323,6 @@ slot_sweep(rb_objspace_t *objspace, stru https://github.com/ruby/ruby/blob/trunk/gc.c#L2323
 	slot_sweep_body(objspace, sweep_slot, FALSE);
 #endif
     }
-    gc_prof_sweep_slot_timer_stop(objspace);
     rgengc_report(1, objspace, "slot_sweep: end\n");
 }
 
@@ -2410,6 +2408,9 @@ static int https://github.com/ruby/ruby/blob/trunk/gc.c#L2408
 lazy_sweep(rb_objspace_t *objspace)
 {
     struct heaps_slot *next;
+    int result = FALSE;
+
+    gc_prof_sweep_timer_start(objspace);
 
     heaps_increment(objspace);
     while (objspace->heap.sweep_slots) {
@@ -2420,10 +2421,14 @@ lazy_sweep(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L2421
 	if (!next) after_gc_sweep(objspace);
 
         if (has_free_object) {
-            return TRUE;
+            result = TRUE;
+	    break;
         }
     }
-    return FALSE;
+
+    gc_prof_sweep_timer_stop(objspace);
+
+    return result;
 }
 
 static void
@@ -3442,7 +3447,7 @@ gc_marks_body(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3447
     struct gc_list *list;
 
     /* start marking */
-    rgengc_report(1, objspace, "gc_marks_body: start.\n");
+    rgengc_report(1, objspace, "gc_marks_body: start (%s)\n", minor_gc ? "minor" : "major");
 
     objspace->rgengc.parent_object_is_promoted = FALSE;
     objspace->rgengc.parent_object = Qundef;
@@ -3459,53 +3464,60 @@ gc_marks_body(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3464
     }
 #endif
 
+#if RGENGC_CHECK_MODE > 1
+#define MARK_CHECKPOINT do {objspace->rgengc.parent_object = INT2FIX(__LINE__);} while (0)
+#else
+#define MARK_CHECKPOINT
+#endif
+
+    MARK_CHECKPOINT;
     SET_STACK_END;
     th->vm->self ? rb_gc_mark(th->vm->self) : rb_vm_mark(th->vm);
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     mark_tbl(objspace, finalizer_table);
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     mark_current_machine_context(objspace, th);
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_gc_mark_symbols();
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_gc_mark_encodings();
 
     /* mark protected global variables */
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     for (list = global_List; list; list = list->next) {
 	rb_gc_mark_maybe(*list->varptr);
     }
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_mark_end_proc();
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_gc_mark_global_tbl();
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     mark_tbl(objspace, rb_class_tbl);
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
     /* mark generic instance variables for special constants */
+    MARK_CHECKPOINT;
     rb_mark_generic_ivar_tbl();
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_gc_mark_parser();
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = INT2FIX(__LINE__);
+    MARK_CHECKPOINT;
     rb_gc_mark_unlinked_live_method_entries(th->vm);
 
-    if (RGENGC_CHECK_MODE > 1) objspace->rgengc.parent_object = Qundef;
-
     /* marking-loop */
     gc_mark_stacked_objects(objspace);
 
+#undef MARK_CHECKPOINT
+
     /* cleanup */
-    rgengc_report(1, objspace, "gc_marks_body: end.\n");
+    rgengc_report(1, objspace, "gc_marks_body: end (%s)\n", minor_gc ? "minor" : "major");
 }
 
 static uintptr_t *
@@ -4971,28 +4983,35 @@ gc_prof_timer_start(rb_objspace_t *objsp https://github.com/ruby/ruby/blob/trunk/gc.c#L4983
 #if GC_PROFILE_MORE_DETAIL
 	record->prepare_time = objspace->profile.prepare_time;
 #endif
-	record->gc_time = getrusage_time();
-	record->gc_invoke_time = record->gc_time - objspace->profile.invoke_time;
+	record->gc_time = 0;
+	record->gc_invoke_time = getrusage_time();
 	record->flags = reason | ((ruby_gc_stress && !ruby_disable_gc_stress) ? GPR_FLAG_STRESS : 0);
     }
 }
 
+static double
+elapsed_time_from(double time)
+{
+    double now = getrusage_time();
+    if (now > time) {
+	return now - time;
+    }
+    else {
+	return 0;
+    }
+}
+
 static inline void
 gc_prof_timer_stop(rb_objspace_t *objspace)
 {
     if (objspace->profile.run) {
-        double gc_time = 0;
 	gc_profile_record *record = gc_prof_record(objspace);
-
-        gc_time = getrusage_time() - record->gc_time;
-        if (gc_time < 0) gc_time = 0;
-
-        record->gc_time = gc_time;
+	record->gc_time = elapsed_time_from(record->gc_invoke_time);
+	record->gc_invoke_time -= objspace->profile.invoke_time;
         gc_prof_set_heap_info(objspace, record);
     }
 }
 
-
 static inline void
 gc_prof_mark_timer_start(rb_objspace_t *objspace)
 {
@@ -5014,47 +5033,46 @@ gc_prof_mark_timer_stop(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L5033
     }
 #if GC_PROFILE_MORE_DETAIL
     if (objspace->profile.run) {
-        double mark_time = 0;
         gc_profile_record *record = gc_prof_record(objspace);
-
-	mark_time = getrusage_time() - record->gc_mark_time;
-        if (mark_time < 0) mark_time = 0;
-	record->gc_mark_time = mark_time;
+	record->gc_mark_time = elapsed_time_from(record->gc_mark_time);
     }
 #endif
 }
 
 static inline void
-gc_prof_sweep_slot_timer_start(rb_objspace_t *objspace)
+gc_prof_sweep_timer_start(rb_objspace_t *objspace)
 {
     if (RUBY_DTRACE_GC_SWEEP_BEGIN_ENABLED()) {
 	RUBY_DTRACE_GC_SWEEP_BEGIN();
     }
-#if GC_PROFILE_MORE_DETAIL
     if (objspace->profile.run) {
-	objspace->profile.gc_sweep_start_time = getrusage_time();
+	if (record->gc_time > 0 || GC_PROFILE_MORE_DETAIL) {
+	    objspace->profile.gc_sweep_start_time = getrusage_time();
+	}
     }
-#endif
 }
 
 static inline void
-gc_prof_sweep_slot_timer_stop(rb_objspace_t *objspace)
+gc_prof_sweep_timer_stop(rb_objspace_t *objspace)
 {
     if (RUBY_DTRACE_GC_SWEEP_END_ENABLED()) {
 	RUBY_DTRACE_GC_SWEEP_END();
     }
-#if GC_PROFILE_MORE_DETAIL
     if (objspace->profile.run) {
-        double sweep_time = 0;
-        gc_profile_record *record = gc_prof_record(objspace);
+	double sweep_time;
+	gc_profile_record *record = gc_prof_record(objspace);
 
-        sweep_time = getrusage_time() - objspace->profile.gc_sweep_start_time;
-	if (sweep_time < 0) sweep_time = 0;
-	record->gc_sweep_time += sweep_time;
+	if (record->gc_time > 0 || GC_PROFILE_MORE_DETAIL) {
+	    /* need to accumulate for lazy sweep */
+	    sweep_time = elapsed_time_from(objspace->profile.gc_sweep_start_time);
+	    record->gc_time += sweep_time;
+	}
 
+#if GC_PROFILE_MORE_DETAIL
+	record->gc_sweep_time += sweep_time;
 	if (deferred_final_list) record->flags |= GPR_FLAG_HAVE_FINALIZE;
-    }
 #endif
+    }
 }
 
 static inline void

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

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