Hi,

At Fri, 19 Aug 2005 04:36:36 +0900,
Paul Duncan wrote in [ruby-core:05557]:
> Richard Lowe (richlowe / richlowe.net) wrote this patch to add a DTrace
> provider into Ruby.  He's not subscribed to ruby-core, so he asked me to
> forward the patch and his description on to the list.

Tried applying to recent versions, but not sure at all.


Index: Makefile.in =================================================================== RCS file: /cvs/ruby/src/ruby/Makefile.in,v retrieving revision 1.75 diff -U2 -p -r1.75 Makefile.in --- Makefile.in 6 Sep 2005 23:22:34 -0000 1.75 +++ Makefile.in 29 Sep 2005 07:43:07 -0000 @@ -40,4 +40,5 @@ EXTLIBS = LIBS = @LIBS@ $(EXTLIBS) MISSING = @LIBOBJS@ @ALLOCA@ +MISCOBJS = @DTRACE_OBJS@ LDSHARED = @LIBRUBY_LDSHARED@ DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(EXTLDFLAGS) @ARCH_FLAG@ @@ -167,2 +168,5 @@ distclean-local:: ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -o$@ -c ext/extinit.c + +dtrace.$(OBJEXT): dtrace.d $(COREOBJS) + $(DTRACE) $(DTRACE_FLAGS) -o $@ -s dtrace.d $(COREOBJS) Index: common.mk =================================================================== RCS file: /cvs/ruby/src/ruby/common.mk,v retrieving revision 1.20 diff -U2 -p -r1.20 common.mk --- common.mk 3 Aug 2005 15:26:14 -0000 1.20 +++ common.mk 29 Sep 2005 07:36:28 -0000 @@ -13,5 +13,5 @@ EXTOBJS = DLDOBJS = $(DMYEXT) -OBJS = array.$(OBJEXT) \ +COREOBJS = array.$(OBJEXT) \ ascii.$(OBJEXT) \ bignum.$(OBJEXT) \ @@ -59,4 +59,5 @@ OBJS = array.$(OBJEXT) \ version.$(OBJEXT) \ $(MISSING) +OBJS = $(COREOBJS) $(MISCOBJS) SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \ Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.284 diff -U2 -p -r1.284 configure.in --- configure.in 6 Sep 2005 23:22:34 -0000 1.284 +++ configure.in 29 Sep 2005 07:36:28 -0000 @@ -503,4 +503,16 @@ if test "$use_setreuid" = yes; then AC_DEFINE(USE_SETREGID) fi + +AC_CHECK_HEADER(sys/sdt.h) +AC_ARG_ENABLE(dtrace, + [ --enable-dtrace enable DTrace support.], + [enable_dtrace=$enableval]) +if test "$enable_dtrace" = yes -a test "$ac_cv_header_sys_sdt_h" = yes; then + AC_DEFINE(ENABLE_DTRACE) + AC_SUBST(DTRACE_OBJS, ['dtrace.$(OBJEXT)']) + : ${DTRACE_FLAGS="-G -"`expr $ac_cv_sizeof_int \* 8`} + AC_SUBST(DTRACE_FLAGS) +fi + AC_STRUCT_TIMEZONE AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff, Index: dtrace.d =================================================================== RCS file: dtrace.d diff -N dtrace.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dtrace.d 14 Sep 2005 08:40:45 -0000 @@ -0,0 +1,12 @@ +/* -*- Mode: C -*- */ + +provider ruby { + probe function__entry(string, string, string, int); + probe function__return(string, string, string, int); +}; + +#pragma D attributes Evolving/Evolving/Common provider ruby provider +#pragma D attributes Private/Private/Common provider ruby module +#pragma D attributes Private/Private/Common provider ruby function +#pragma D attributes Evolving/Evolving/Common provider ruby name +#pragma D attributes Evolving/Evolving/Common provider ruby args Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.833 diff -U2 -p -r1.833 eval.c --- eval.c 28 Sep 2005 15:58:01 -0000 1.833 +++ eval.c 29 Sep 2005 07:36:28 -0000 @@ -190,4 +190,11 @@ typedef jmp_buf rb_jmpbuf_t; #include <sys/stat.h> +#ifdef ENABLE_DTRACE +# include <sys/sdt.h> +# define USE_DTRACE 1 +#else +# define USE_DTRACE 0 +#endif + VALUE rb_cProc; static VALUE rb_cBinding; @@ -5570,5 +5577,24 @@ formal_assign(VALUE recv, NODE *node, in } -static VALUE +#ifdef ENABLE_DTRACE +# define RB_DTRACE_PROBE_CALL(probe, klass, method, node) do { \ + if (node && node->nd_file) { \ + char *classname = rb_class2name(klass); \ + char *methodname = rb_id2name(method); \ + if (classname && methodname) { \ + DTRACE_PROBE4(ruby, probe, classname, methodname, \ + node->nd_file, nd_line(node)); \ + } \ + } \ + } while (0) +#else +# define RB_DTRACE_PROBE_CALL(probe, klass, method, node) ((void)0) +#endif +#define RB_DTRACE_PROBE_ENTRY(klass, method, node) \ + RB_DTRACE_PROBE_CALL(function__entry, klass, method, node) +#define RB_DTRACE_PROBE_RETURN(klass, method, node) \ + RB_DTRACE_PROBE_CALL(function__return, klass, method, node) + +VALUE rb_call0(VALUE klass, VALUE recv, ID id, ID oid, int argc /* OK */, const VALUE *argv /* OK */, NODE *volatile body, int flags) @@ -5622,9 +5648,12 @@ rb_call0(VALUE klass, VALUE recv, ID id, len, rb_class2name(klass), rb_id2name(id)); } - if (event_hooks) { + if (USE_DTRACE || event_hooks) { int state; - EXEC_EVENT_HOOK(RUBY_EVENT_C_CALL, ruby_current_node, - recv, id, klass); + if (!USE_DTRACE || event_hooks) { + EXEC_EVENT_HOOK(RUBY_EVENT_C_CALL, ruby_current_node, + recv, id, klass); + } + RB_DTRACE_PROBE_ENTRY(klass, id, ruby_current_node); PUSH_TAG(PROT_FUNC); if ((state = EXEC_TAG()) == 0) { @@ -5633,11 +5662,16 @@ rb_call0(VALUE klass, VALUE recv, ID id, POP_TAG(); ruby_current_node = ruby_frame->node; - EXEC_EVENT_HOOK(RUBY_EVENT_C_RETURN, ruby_current_node, - recv, id, klass); + RB_DTRACE_PROBE_RETURN(klass, id, ruby_current_node); + if (!USE_DTRACE || event_hooks) { + EXEC_EVENT_HOOK(RUBY_EVENT_C_RETURN, ruby_current_node, + recv, id, klass); + } if (state) JUMP_TAG(state); } +#if !USE_DTRACE else { result = call_cfunc(body->nd_cfnc, recv, len, argc, argv); } +#endif } break; @@ -5716,4 +5750,5 @@ rb_call0(VALUE klass, VALUE recv, ID id, } + RB_DTRACE_PROBE_ENTRY(klass, id, ruby_frame->prev->node); if (event_hooks) { EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass); @@ -5731,4 +5766,5 @@ rb_call0(VALUE klass, VALUE recv, ID id, ruby_cref = saved_cref; if (safe >= 0) ruby_safe_level = safe; + RB_DTRACE_PROBE_RETURN(klass, id, ruby_frame->prev->node); if (event_hooks) { EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
-- Nobu Nakada