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

ruby-changes:31215

From: ko1 <ko1@a...>
Date: Tue, 15 Oct 2013 19:22:39 +0900 (JST)
Subject: [ruby-changes:31215] ko1:r43294 (trunk): * gc.h (rb_objspace_reachable_objects_from_root): added.

ko1	2013-10-15 19:22:33 +0900 (Tue, 15 Oct 2013)

  New Revision: 43294

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

  Log:
    * gc.h (rb_objspace_reachable_objects_from_root): added.
      This API provides information which objects are root objects.
      `category' shows what kind of root objects.
    * gc.c (gc_mark_roots): separate from gc_marks_body().

  Modified files:
    trunk/ChangeLog
    trunk/gc.c
    trunk/gc.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 43293)
+++ ChangeLog	(revision 43294)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Oct 15 19:18:13 2013  Koichi Sasada  <ko1@a...>
+
+	* gc.h (rb_objspace_reachable_objects_from_root): added.
+	  This API provides information which objects are root objects.
+	  `category' shows what kind of root objects.
+
+	* gc.c (gc_mark_roots): separate from gc_marks_body().
+
 Tue Oct 15 17:47:59 2013  Tanaka Akira  <akr@f...>
 
 	* process.c: Fix a typo.  MacOS X doesn't have ENOTSUPP.
Index: gc.c
===================================================================
--- gc.c	(revision 43293)
+++ gc.c	(revision 43294)
@@ -3452,7 +3452,9 @@ gc_mark_stacked_objects(rb_objspace_t *o https://github.com/ruby/ruby/blob/trunk/gc.c#L3452
     shrink_stack_chunk_cache(mstack);
 }
 
+#ifndef RGENGC_PRINT_TICK
 #define RGENGC_PRINT_TICK 0
+#endif
 /* the following code is only for internal tuning. */
 
 /* Source code to use RDTSC is quoted and modified from
@@ -3504,7 +3506,7 @@ tick(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L3506
 
 #define MAX_TICKS 0x100
 static tick_t mark_ticks[MAX_TICKS];
-static int mark_ticks_start_line;
+static const char *mark_ticks_categories[MAX_TICKS];
 
 static void
 show_mark_ticks(void)
@@ -3512,106 +3514,130 @@ show_mark_ticks(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L3514
     int i;
     fprintf(stderr, "mark ticks result:\n");
     for (i=0; i<MAX_TICKS; i++) {
-      if (mark_ticks[i] > 0) {
-	  fprintf(stderr, "@%4d\t%8lu\n", i+mark_ticks_start_line, (unsigned long)mark_ticks[i]);
-      }
+	const char *category = mark_ticks_categories[i];
+	if (category) {
+	    fprintf(stderr, "%s\t%8lu\n", category, (unsigned long)mark_ticks[i]);
+	}
+	else {
+	    break;
+	}
     }
 }
 
 #endif /* RGENGC_PRINT_TICK */
 
 static void
-gc_marks_body(rb_objspace_t *objspace, int full_mark)
+gc_mark_roots(rb_objspace_t *objspace, int full_mark, const char **categoryp)
 {
     struct gc_list *list;
     rb_thread_t *th = GET_THREAD();
 
 #if RGENGC_PRINT_TICK
     tick_t start_tick = tick();
-    if (mark_ticks_start_line == 0) {
-	mark_ticks_start_line = __LINE__;
+    int tick_count = 0;
+    const char *prev_category = 0;
+
+    if (mark_ticks_categories[0] == 0) {
 	atexit(show_mark_ticks);
     }
 #endif
 
-#define MARK_CHECKPOINT_PRINT_TICK do { \
-    tick_t t = tick(); \
-    mark_ticks[__LINE__ - mark_ticks_start_line] = t - start_tick; \
-    start_tick = tick(); \
-} while (0)
-
 #if RGENGC_CHECK_MODE > 1
-#define MARK_CHECKPOINT do { \
+#define MARK_CHECKPOINT_DEBUG(category) do { \
     objspace->rgengc.parent_object = INT2FIX(__LINE__); \
 } while (0)
-#elif RGENGC_PRINT_TICK
-#define MARK_CHECKPOINT MARK_CHECKPOINT_PRINT_TICK
-#else
-#define MARK_CHECKPOINT /* do nothing */
+#else /* RGENGC_CHECK_MODE > 1 */
+#define MARK_CHECKPOINT_DEBUG(category)
 #endif
 
-    /* start marking */
-    rgengc_report(1, objspace, "gc_marks_body: start (%s)\n", full_mark ? "full" : "minor");
-
-#if USE_RGENGC
-    objspace->rgengc.parent_object_is_promoted = FALSE;
-    objspace->rgengc.parent_object = Qundef;
-    objspace->rgengc.during_minor_gc = full_mark ? FALSE : TRUE;
-
-    if (objspace->rgengc.during_minor_gc) {
-	objspace->profile.minor_gc_count++;
-	rgengc_rememberset_mark(objspace);
-    }
-    else {
-	objspace->profile.major_gc_count++;
-	rgengc_mark_and_rememberset_clear(objspace);
-    }
+#if RGENGC_PRINT_TICK
+#define MARK_CHECKPOINT_PRINT_TICK(category) do { \
+    if (prev_category) { \
+	tick_t t = tick(); \
+	mark_ticks[tick_count] = t - start_tick; \
+	mark_ticks_categories[tick_count] = prev_category; \
+	tick_count++; \
+    } \
+    prev_category = category; \
+    start_tick = tick(); \
+} while (0)
+#else /* RGENGC_PRINT_TICK */
+#define MARK_CHECKPOINT_PRINT_TICK(category)
 #endif
 
-    MARK_CHECKPOINT;
+#define MARK_CHECKPOINT(category) do { \
+    if (categoryp) *categoryp = category; \
+    MARK_CHECKPOINT_DEBUG(category); \
+    MARK_CHECKPOINT_PRINT_TICK(category); \
+} while (0)
+
+    MARK_CHECKPOINT("vm");
     SET_STACK_END;
     th->vm->self ? rb_gc_mark(th->vm->self) : rb_vm_mark(th->vm);
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("finalizer_table");
     mark_tbl(objspace, finalizer_table);
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("mark_current_machine_context");
     mark_current_machine_context(objspace, th);
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_gc_mark_symbols");
     rb_gc_mark_symbols(full_mark);
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_gc_mark_encodings");
     rb_gc_mark_encodings();
 
     /* mark protected global variables */
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("global_List");
     for (list = global_List; list; list = list->next) {
 	rb_gc_mark_maybe(*list->varptr);
     }
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_mark_end_proc");
     rb_mark_end_proc();
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_gc_mark_global_tbl");
     rb_gc_mark_global_tbl();
 
     /* mark generic instance variables for special constants */
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_mark_generic_ivar_tbl");
     rb_mark_generic_ivar_tbl();
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_gc_mark_parser");
     rb_gc_mark_parser();
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("rb_gc_mark_unlinked_live_method_entries");
     rb_gc_mark_unlinked_live_method_entries(th->vm);
 
     /* marking-loop */
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("gc_mark_stacked_objects");
     gc_mark_stacked_objects(objspace);
 
-    MARK_CHECKPOINT;
+    MARK_CHECKPOINT("finish");
 #undef MARK_CHECKPOINT
+}
+
+static void
+gc_marks_body(rb_objspace_t *objspace, int full_mark)
+{
+    /* start marking */
+    rgengc_report(1, objspace, "gc_marks_body: start (%s)\n", full_mark ? "full" : "minor");
+
+#if USE_RGENGC
+    objspace->rgengc.parent_object_is_promoted = FALSE;
+    objspace->rgengc.parent_object = Qundef;
+    objspace->rgengc.during_minor_gc = full_mark ? FALSE : TRUE;
+
+    if (objspace->rgengc.during_minor_gc) {
+	objspace->profile.minor_gc_count++;
+	rgengc_rememberset_mark(objspace);
+    }
+    else {
+	objspace->profile.major_gc_count++;
+	rgengc_mark_and_rememberset_clear(objspace);
+    }
+#endif
+    gc_mark_roots(objspace, full_mark, 0);
 
     /* cleanup */
     rgengc_report(1, objspace, "gc_marks_body: end (%s)\n", full_mark ? "full" : "minor");
@@ -4701,6 +4727,39 @@ rb_objspace_reachable_objects_from(VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L4727
     }
 }
 
+struct root_objects_data {
+    const char *category;
+    void (*func)(const char *category, VALUE, void *);
+    void *data;
+};
+
+static void
+root_objects_from(VALUE obj, void *ptr)
+{
+    const struct root_objects_data *data = (struct root_objects_data *)ptr;
+    (*data->func)(data->category, obj, data->data);
+}
+
+void
+rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *passing_data)
+{
+    rb_objspace_t *objspace = &rb_objspace;
+    struct root_objects_data data;
+    struct mark_func_data_struct mfd;
+
+    data.func = func;
+    data.data = passing_data;
+    
+    mfd.mark_func = root_objects_from;
+    mfd.data = &data;
+
+    objspace->mark_func_data = &mfd;
+    {
+	gc_mark_roots(objspace, FALSE, &data.category);
+    }
+    objspace->mark_func_data = 0;
+}
+
 /*
   ------------------------ Extended allocator ------------------------
 */
Index: gc.h
===================================================================
--- gc.h	(revision 43293)
+++ gc.h	(revision 43294)
@@ -88,6 +88,7 @@ RUBY_SYMBOL_EXPORT_BEGIN https://github.com/ruby/ruby/blob/trunk/gc.h#L88
 /* exports for objspace module */
 size_t rb_objspace_data_type_memsize(VALUE obj);
 void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
+void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
 int rb_objspace_markable_object_p(VALUE obj);
 int rb_objspace_internal_object_p(VALUE obj);
 

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

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