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
prev parent 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).