dumping ground for random patches and texts
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Cc: Eric Wong <e@80x24.org>
Subject: [PATCH 2/2] gc.c: make gc_enter+gc_exit pairs dtrace probes, too
Date: Sun, 16 Dec 2018 12:06:30 +0000	[thread overview]
Message-ID: <20181216120630.17237-2-e@80x24.org> (raw)
In-Reply-To: <20181216120630.17237-1-e@80x24.org>

I would like to use these with systemtap to gather
min/max/avg/variance data for gc_*_continue functions

[ruby-core:90399] [Feature #14813]
---
 gc.c                   | 53 ++++++++++++++++++++++++--------
 probes.d               | 70 ++++++++++++++++++++++++++++++++++++++++++
 test/dtrace/test_gc.rb | 10 ++++++
 3 files changed, 121 insertions(+), 12 deletions(-)

diff --git a/gc.c b/gc.c
index 528dabaca9..617088a58c 100644
--- a/gc.c
+++ b/gc.c
@@ -3008,6 +3008,37 @@ rb_gc_call_finalizer_at_exit(void)
     rb_objspace_call_finalizer(&rb_objspace);
 }
 
+enum gc_event {
+    gc_ev_SWEEP_CONTINUE = 0,
+    gc_ev_MARKS_CONTINUE,
+    gc_ev_START,
+    gc_ev_REST,
+    gc_ev_RB_OBJSPACE_CALL_FINALIZER
+};
+
+static const char * const
+gc_event_str[] = {
+    "sweep_continue",
+    "marks_continue",
+    "gc_start",
+    "gc_rest",
+    "rb_objspace_call_finalizer"
+};
+
+#define RUBY_DTRACE_GC_HOOK(name) do { \
+    if (RUBY_DTRACE_GC_##name##_ENABLED()) RUBY_DTRACE_GC_##name(); \
+} while (0)
+
+#define GC_ENTER(objspace, event) do { \
+    RUBY_DTRACE_GC_HOOK(event##_BEGIN); \
+    gc_enter(objspace, gc_event_str[gc_ev_##event]); \
+} while (0)
+
+#define GC_EXIT(objspace, event) do { \
+    RUBY_DTRACE_GC_HOOK(event##_END); \
+    gc_exit(objspace, gc_event_str[gc_ev_##event]); \
+} while (0)
+
 static void
 rb_objspace_call_finalizer(rb_objspace_t *objspace)
 {
@@ -3044,7 +3075,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
     dont_gc = 1;
 
     /* running data/file finalizers are part of garbage collection */
-    gc_enter(objspace, "rb_objspace_call_finalizer");
+    GC_ENTER(objspace, RB_OBJSPACE_CALL_FINALIZER);
 
     /* run data/file object's finalizers */
     for (i = 0; i < heap_allocated_pages; i++) {
@@ -3079,7 +3110,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
 	}
     }
 
-    gc_exit(objspace, "rb_objspace_call_finalizer");
+    GC_EXIT(objspace, RB_OBJSPACE_CALL_FINALIZER);
 
     if (heap_pages_deferred_final) {
 	finalize_list(objspace, heap_pages_deferred_final);
@@ -3859,14 +3890,14 @@ gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap)
     GC_ASSERT(dont_gc == FALSE);
     if (!GC_ENABLE_LAZY_SWEEP) return;
 
-    gc_enter(objspace, "sweep_continue");
+    GC_ENTER(objspace, SWEEP_CONTINUE);
 #if USE_RGENGC
     if (objspace->rgengc.need_major_gc == GPR_FLAG_NONE && heap_increment(objspace, heap)) {
 	gc_report(3, objspace, "gc_sweep_continue: success heap_increment().\n");
     }
 #endif
     gc_sweep_step(objspace, heap);
-    gc_exit(objspace, "sweep_continue");
+    GC_EXIT(objspace, SWEEP_CONTINUE);
 }
 
 static void
@@ -5807,7 +5838,7 @@ gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap)
     GC_ASSERT(dont_gc == FALSE);
 #if GC_ENABLE_INCREMENTAL_MARK
 
-    gc_enter(objspace, "marks_continue");
+    GC_ENTER(objspace, MARKS_CONTINUE);
 
     PUSH_MARK_FUNC_DATA(NULL);
     {
@@ -5837,7 +5868,7 @@ gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap)
     }
     POP_MARK_FUNC_DATA();
 
-    gc_exit(objspace, "marks_continue");
+    GC_EXIT(objspace, MARKS_CONTINUE);
 #endif
 }
 
@@ -6572,7 +6603,7 @@ gc_start(rb_objspace_t *objspace, int reason)
     gc_verify_internal_consistency(Qnil);
 #endif
 
-    gc_enter(objspace, "gc_start");
+    GC_ENTER(objspace, START);
 
     if (ruby_gc_stressful) {
 	int flag = FIXNUM_P(ruby_gc_stress_mode) ? FIX2INT(ruby_gc_stress_mode) : 0;
@@ -6659,7 +6690,7 @@ gc_start(rb_objspace_t *objspace, int reason)
     }
     gc_prof_timer_stop(objspace);
 
-    gc_exit(objspace, "gc_start");
+    GC_EXIT(objspace, START);
     return TRUE;
 }
 
@@ -6670,7 +6701,7 @@ gc_rest(rb_objspace_t *objspace)
     int sweeping = is_lazy_sweeping(heap_eden);
 
     if (marking || sweeping) {
-	gc_enter(objspace, "gc_rest");
+	GC_ENTER(objspace, REST);
 
 	if (RGENGC_CHECK_MODE >= 2) gc_verify_internal_consistency(Qnil);
 
@@ -6682,7 +6713,7 @@ gc_rest(rb_objspace_t *objspace)
 	if (is_lazy_sweeping(heap_eden)) {
 	    gc_sweep_rest(objspace);
 	}
-	gc_exit(objspace, "gc_rest");
+	GC_EXIT(objspace, REST);
     }
 }
 
@@ -9071,8 +9102,6 @@ gc_prof_timer_stop(rb_objspace_t *objspace)
     }
 }
 
-#define RUBY_DTRACE_GC_HOOK(name) \
-    do {if (RUBY_DTRACE_GC_##name##_ENABLED()) RUBY_DTRACE_GC_##name();} while (0)
 static inline void
 gc_prof_mark_timer_start(rb_objspace_t *objspace)
 {
diff --git a/probes.d b/probes.d
index 57a3d762bd..0bb3d68a38 100644
--- a/probes.d
+++ b/probes.d
@@ -215,6 +215,76 @@ provider ruby {
   */
   probe gc__sweep__end();
 
+  /*
+     ruby:::gc-sweep-continue-begin();
+
+     Fired at the beginning of a lazy sweep step
+  */
+  probe gc__sweep__continue__begin();
+
+  /*
+     ruby:::gc-sweep-continue-end();
+
+     Fired at the end of a lazy sweep step
+  */
+  probe gc__sweep__continue__end();
+
+  /*
+     ruby:::gc-marks-continue-begin();
+
+     Fired at the beginning of an incremental mark step
+  */
+  probe gc__marks__continue__begin();
+
+  /*
+     ruby:::gc-marks-continue-end();
+
+     Fired at the end of an incremental mark step
+  */
+  probe gc__marks__continue__end();
+
+  /*
+     ruby:::gc-start-begin();
+
+     Fired when GC begins preparation for incremental marking
+  */
+  probe gc__start__begin();
+
+  /*
+     ruby:::gc-start-end();
+
+     Fired when GC finishes preparation for incremental marking
+  */
+  probe gc__start__end();
+
+  /*
+     ruby:::gc-rest-begin();
+
+     Fired when GC starts to finish all incremental marking and lazy sweeping
+  */
+  probe gc__rest__begin();
+
+  /*
+     ruby:::gc-rest-begin();
+
+     Fired when GC finishes all incremental marking and lazy sweeping as a batch
+  */
+  probe gc__rest__end();
+
+  /*
+     ruby:::gc-rb-objspace-call-finalizer-begin();
+
+     Fired when finalizers begin running
+  */
+  probe gc__rb__objspace__call__finalizer__begin();
+
+  /*
+     ruby:::gc-rb-objspace-call-finalizer-end();
+
+     Fired when finalizers finish running
+  */
+  probe gc__rb__objspace__call__finalizer__end();
+
   /*
      ruby:::method-cache-clear(class, filename, lineno);
 
diff --git a/test/dtrace/test_gc.rb b/test/dtrace/test_gc.rb
index 77de7998dd..e9ef42719f 100644
--- a/test/dtrace/test_gc.rb
+++ b/test/dtrace/test_gc.rb
@@ -8,6 +8,16 @@ class TestGC < TestCase
       gc-mark-end
       gc-sweep-begin
       gc-sweep-end
+      gc-sweep-continue-begin
+      gc-sweep-continue-end
+      gc-marks-continue-begin
+      gc-marks-continue-end
+      gc-start-begin
+      gc-start-end
+      gc-rest-begin
+      gc-rest-end
+      gc-rb-objspace-call-finalizer-begin
+      gc-rb-objspace-call-finalizer-end
     }.each do |probe_name|
       define_method(:"test_#{probe_name.gsub(/-/, '_')}") do
 	probe = "ruby$target:::#{probe_name} { printf(\"#{probe_name}\\n\"); }"
-- 
EW


      reply	other threads:[~2018-12-16 12:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-16 12:06 [PATCH 1/2] insns.def (duparray, duphash): add dtrace hooks Eric Wong
2018-12-16 12:06 ` Eric Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181216120630.17237-2-e@80x24.org \
    --to=e@80x24.org \
    --cc=spew@80x24.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).