components/ruby/ruby-18/patches/08-ruby-dtrace-1.8.7.patch
changeset 1482 7a1f84fbc2d7
parent 688 9333dc6e30ba
equal deleted inserted replaced
1481:246d38ae4b93 1482:7a1f84fbc2d7
       
     1 diff -rupN ruby-1.8.7-p357.orig/common.mk ruby-1.8.7-p357/common.mk
       
     2 --- ruby-1.8.7-p357.orig/common.mk	2010-11-21 23:22:16.000000000 -0800
       
     3 +++ ruby-1.8.7-p357/common.mk	2012-01-23 14:50:29.502736000 -0800
       
     4 @@ -55,6 +55,7 @@ OBJS	      = array.$(OBJEXT) \
       
     5  		string.$(OBJEXT) \
       
     6  		struct.$(OBJEXT) \
       
     7  		time.$(OBJEXT) \
       
     8 +		tracer.$(OBJEXT) \
       
     9  		util.$(OBJEXT) \
       
    10  		variable.$(OBJEXT) \
       
    11  		version.$(OBJEXT) \
       
    12 @@ -85,9 +86,9 @@ prog: $(PROGRAM) $(WPROGRAM)
       
    13  
       
    14  miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) $(MINIOBJS) $(OBJS) $(DMYEXT)
       
    15  
       
    16 -$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
       
    17 +$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(DTRACE_OBJS) $(SETUP) $(PREP)
       
    18  
       
    19 -$(LIBRUBY_A):	$(OBJS) $(DMYEXT) $(ARCHFILE)
       
    20 +$(LIBRUBY_A):	$(OBJS) $(DMYEXT) $(ARCHFILE) $(DTRACE_OBJS)
       
    21  
       
    22  $(LIBRUBY_SO):	$(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(LIBRUBY_SO_UPDATE)
       
    23  
       
    24 @@ -280,7 +281,7 @@ clear-installed-list:
       
    25  
       
    26  clean: clean-ext clean-local
       
    27  clean-local::
       
    28 -	@$(RM) $(OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
       
    29 +	@$(RM) $(OBJS) $(DTRACE_OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
       
    30  	@$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) $(ARCHFILE) .*.time
       
    31  	@$(RM) y.tab.c y.output
       
    32  clean-ext:
       
    33 diff -rupN ruby-1.8.7-p357.orig/configure.in ruby-1.8.7-p357/configure.in
       
    34 --- ruby-1.8.7-p357.orig/configure.in	2011-02-18 02:37:47.000000000 -0800
       
    35 +++ ruby-1.8.7-p357/configure.in	2012-01-23 14:50:29.513537000 -0800
       
    36 @@ -524,6 +524,11 @@ AC_CHECK_HEADERS(stdlib.h string.h unist
       
    37  		 sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \
       
    38  		 ucontext.h intrinsics.h time.h)
       
    39  
       
    40 +AC_CHECK_HEADER(sys/sdt.h)
       
    41 +if test "$ac_cv_header_sys_sdt_h" == "yes"; then
       
    42 +	AC_DEFINE(HAVE_SDT_H)
       
    43 +fi
       
    44 +
       
    45  dnl Check additional types.
       
    46  AC_CHECK_SIZEOF(rlim_t, 0, [
       
    47    #ifdef HAVE_SYS_TYPES_H
       
    48 @@ -698,6 +703,18 @@ if test "$use_setreuid" = yes; then
       
    49      AC_DEFINE(USE_SETREUID)
       
    50      AC_DEFINE(USE_SETREGID)
       
    51  fi
       
    52 +
       
    53 +AC_ARG_ENABLE(dtrace,
       
    54 +	[  --enable-dtrace         enable DTrace support.],
       
    55 +	[enable_dtrace=$enableval])
       
    56 +if test "$enable_dtrace" == "yes" -a "$ac_cv_header_sys_sdt_h" == "yes"; then
       
    57 +	AC_DEFINE(ENABLE_DTRACE)
       
    58 +	DTRACE_OBJS="dtrace.o"
       
    59 +else
       
    60 +	DTRACE_OBJS=""
       
    61 +fi
       
    62 +AC_SUBST(DTRACE_OBJS)
       
    63 +
       
    64  AC_STRUCT_TIMEZONE
       
    65  AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
       
    66    [AC_TRY_COMPILE([#include <time.h>],
       
    67 @@ -1207,7 +1224,7 @@ if test "$with_dln_a_out" != yes; then
       
    68  	 		       LDFLAGS="$LDFLAGS -Wl,-E"
       
    69  			   fi
       
    70  			else
       
    71 -			   : ${LDSHARED='ld -G'}
       
    72 +			   : ${LDSHARED='$(CC) -G'}
       
    73  			fi
       
    74  			rb_cv_dlopen=yes;;
       
    75  	sunos*) 	: ${LDSHARED='ld -assert nodefinitions'}
       
    76 diff -rupN ruby-1.8.7-p357.orig/dtrace.d ruby-1.8.7-p357/dtrace.d
       
    77 --- ruby-1.8.7-p357.orig/dtrace.d	1969-12-31 16:00:00.000000000 -0800
       
    78 +++ ruby-1.8.7-p357/dtrace.d	2012-01-23 14:50:29.525158000 -0800
       
    79 @@ -0,0 +1,26 @@
       
    80 +/* -*- Mode: C -*- */
       
    81 +
       
    82 +provider ruby {
       
    83 +    probe function__entry(char*, char*, char*, int);
       
    84 +    probe function__return(char*, char*, char*, int);
       
    85 +    probe raise(char*, char*, int);
       
    86 +    probe rescue(char*, int);
       
    87 +    probe line(char*, int);
       
    88 +
       
    89 +    /* gc probes */
       
    90 +    probe gc__begin();
       
    91 +    probe gc__end();
       
    92 +
       
    93 +    /* Some initial memory type probes */
       
    94 +    probe object__create__start(char*, char*, int);
       
    95 +    probe object__create__done(char*, char*, int);
       
    96 +    probe object__free(char*);
       
    97 +
       
    98 +    probe ruby__probe(char*, char*);
       
    99 +};
       
   100 +
       
   101 +#pragma D attributes Evolving/Evolving/Common provider ruby provider
       
   102 +#pragma D attributes Private/Private/Common provider ruby module
       
   103 +#pragma D attributes Private/Private/Common provider ruby function
       
   104 +#pragma D attributes Evolving/Evolving/Common provider ruby name
       
   105 +#pragma D attributes Evolving/Evolving/Common provider ruby args
       
   106 diff -rupN ruby-1.8.7-p357.orig/dtrace.h ruby-1.8.7-p357/dtrace.h
       
   107 --- ruby-1.8.7-p357.orig/dtrace.h	1969-12-31 16:00:00.000000000 -0800
       
   108 +++ ruby-1.8.7-p357/dtrace.h	2012-01-23 14:50:29.531660000 -0800
       
   109 @@ -0,0 +1,85 @@
       
   110 +/*
       
   111 + * Generated by dtrace(1M).
       
   112 + */
       
   113 +
       
   114 +#ifndef	_DTRACE_H
       
   115 +#define	_DTRACE_H
       
   116 +
       
   117 +#ifdef	__cplusplus
       
   118 +extern "C" {
       
   119 +#endif
       
   120 +
       
   121 +#define	RUBY_FUNCTION_ENTRY(arg0, arg1, arg2, arg3) \
       
   122 +	__dtrace_ruby___function__entry(arg0, arg1, arg2, arg3)
       
   123 +#define	RUBY_FUNCTION_ENTRY_ENABLED() \
       
   124 +	__dtraceenabled_ruby___function__entry()
       
   125 +#define	RUBY_FUNCTION_RETURN(arg0, arg1, arg2, arg3) \
       
   126 +	__dtrace_ruby___function__return(arg0, arg1, arg2, arg3)
       
   127 +#define	RUBY_FUNCTION_RETURN_ENABLED() \
       
   128 +	__dtraceenabled_ruby___function__return()
       
   129 +#define	RUBY_GC_BEGIN() \
       
   130 +	__dtrace_ruby___gc__begin()
       
   131 +#define	RUBY_GC_BEGIN_ENABLED() \
       
   132 +	__dtraceenabled_ruby___gc__begin()
       
   133 +#define	RUBY_GC_END() \
       
   134 +	__dtrace_ruby___gc__end()
       
   135 +#define	RUBY_GC_END_ENABLED() \
       
   136 +	__dtraceenabled_ruby___gc__end()
       
   137 +#define	RUBY_LINE(arg0, arg1) \
       
   138 +	__dtrace_ruby___line(arg0, arg1)
       
   139 +#define	RUBY_LINE_ENABLED() \
       
   140 +	__dtraceenabled_ruby___line()
       
   141 +#define	RUBY_OBJECT_CREATE_DONE(arg0, arg1, arg2) \
       
   142 +	__dtrace_ruby___object__create__done(arg0, arg1, arg2)
       
   143 +#define	RUBY_OBJECT_CREATE_DONE_ENABLED() \
       
   144 +	__dtraceenabled_ruby___object__create__done()
       
   145 +#define	RUBY_OBJECT_CREATE_START(arg0, arg1, arg2) \
       
   146 +	__dtrace_ruby___object__create__start(arg0, arg1, arg2)
       
   147 +#define	RUBY_OBJECT_CREATE_START_ENABLED() \
       
   148 +	__dtraceenabled_ruby___object__create__start()
       
   149 +#define	RUBY_OBJECT_FREE(arg0) \
       
   150 +	__dtrace_ruby___object__free(arg0)
       
   151 +#define	RUBY_OBJECT_FREE_ENABLED() \
       
   152 +	__dtraceenabled_ruby___object__free()
       
   153 +#define	RUBY_RAISE(arg0, arg1, arg2) \
       
   154 +	__dtrace_ruby___raise(arg0, arg1, arg2)
       
   155 +#define	RUBY_RAISE_ENABLED() \
       
   156 +	__dtraceenabled_ruby___raise()
       
   157 +#define	RUBY_RESCUE(arg0, arg1) \
       
   158 +	__dtrace_ruby___rescue(arg0, arg1)
       
   159 +#define	RUBY_RESCUE_ENABLED() \
       
   160 +	__dtraceenabled_ruby___rescue()
       
   161 +#define	RUBY_RUBY_PROBE(arg0, arg1) \
       
   162 +	__dtrace_ruby___ruby__probe(arg0, arg1)
       
   163 +#define	RUBY_RUBY_PROBE_ENABLED() \
       
   164 +	__dtraceenabled_ruby___ruby__probe()
       
   165 +
       
   166 +
       
   167 +extern void __dtrace_ruby___function__entry(char *, char *, char *, int);
       
   168 +extern int __dtraceenabled_ruby___function__entry(void);
       
   169 +extern void __dtrace_ruby___function__return(char *, char *, char *, int);
       
   170 +extern int __dtraceenabled_ruby___function__return(void);
       
   171 +extern void __dtrace_ruby___gc__begin(void);
       
   172 +extern int __dtraceenabled_ruby___gc__begin(void);
       
   173 +extern void __dtrace_ruby___gc__end(void);
       
   174 +extern int __dtraceenabled_ruby___gc__end(void);
       
   175 +extern void __dtrace_ruby___line(char *, int);
       
   176 +extern int __dtraceenabled_ruby___line(void);
       
   177 +extern void __dtrace_ruby___object__create__done(char *, char *, int);
       
   178 +extern int __dtraceenabled_ruby___object__create__done(void);
       
   179 +extern void __dtrace_ruby___object__create__start(char *, char *, int);
       
   180 +extern int __dtraceenabled_ruby___object__create__start(void);
       
   181 +extern void __dtrace_ruby___object__free(char *);
       
   182 +extern int __dtraceenabled_ruby___object__free(void);
       
   183 +extern void __dtrace_ruby___raise(char *, char *, int);
       
   184 +extern int __dtraceenabled_ruby___raise(void);
       
   185 +extern void __dtrace_ruby___rescue(char *, int);
       
   186 +extern int __dtraceenabled_ruby___rescue(void);
       
   187 +extern void __dtrace_ruby___ruby__probe(char *, char *);
       
   188 +extern int __dtraceenabled_ruby___ruby__probe(void);
       
   189 +
       
   190 +#ifdef	__cplusplus
       
   191 +}
       
   192 +#endif
       
   193 +
       
   194 +#endif	/* _DTRACE_H */
       
   195 diff -rupN ruby-1.8.7-p357.orig/eval.c ruby-1.8.7-p357/eval.c
       
   196 --- ruby-1.8.7-p357.orig/eval.c	2011-05-22 21:49:40.000000000 -0700
       
   197 +++ ruby-1.8.7-p357/eval.c	2012-01-23 14:50:29.548765000 -0800
       
   198 @@ -226,6 +226,10 @@ int _setjmp(), _longjmp();
       
   199  
       
   200  #include <sys/stat.h>
       
   201  
       
   202 +#ifdef ENABLE_DTRACE
       
   203 +#include "dtrace.h"
       
   204 +#endif
       
   205 +
       
   206  VALUE rb_cProc;
       
   207  VALUE rb_cBinding;
       
   208  static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE));
       
   209 @@ -3059,12 +3063,22 @@ rb_eval(self, n)
       
   210  
       
   211        case NODE_IF:
       
   212  	if (RTEST(rb_eval(self, node->nd_cond))) {
       
   213 +	    #ifdef ENABLE_DTRACE
       
   214 +	    if (RUBY_LINE_ENABLED())
       
   215 +		if (ruby_current_node && ruby_current_node->nd_file)
       
   216 +		    RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   217 +	    #endif
       
   218  	    EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
       
   219  			    ruby_frame->last_func,
       
   220  			    ruby_frame->last_class);
       
   221  	    node = node->nd_body;
       
   222  	}
       
   223  	else {
       
   224 +	    #ifdef ENABLE_DTRACE
       
   225 +	    if (RUBY_LINE_ENABLED())
       
   226 +		if (ruby_current_node && ruby_current_node->nd_file)
       
   227 +		    RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   228 +	    #endif
       
   229  	    EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
       
   230  			    ruby_frame->last_func,
       
   231  			    ruby_frame->last_class);
       
   232 @@ -3079,6 +3093,11 @@ rb_eval(self, n)
       
   233  	    if (nd_type(node) != NODE_WHEN) goto again;
       
   234  	    tag = node->nd_head;
       
   235  	    while (tag) {
       
   236 +		#ifdef ENABLE_DTRACE
       
   237 +		if (RUBY_LINE_ENABLED())
       
   238 +		    if (ruby_current_node && ruby_current_node->nd_file)
       
   239 +			RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   240 +		#endif
       
   241  		EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
       
   242  				ruby_frame->last_func,
       
   243  				ruby_frame->last_class);
       
   244 @@ -3120,6 +3139,11 @@ rb_eval(self, n)
       
   245  		}
       
   246  		tag = node->nd_head;
       
   247  		while (tag) {
       
   248 +		    #ifdef ENABLE_DTRACE
       
   249 +		    if (RUBY_LINE_ENABLED())
       
   250 +		        if (ruby_current_node && ruby_current_node->nd_file)
       
   251 +			    RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   252 +		    #endif
       
   253  		    EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
       
   254  				    ruby_frame->last_func,
       
   255  				    ruby_frame->last_class);
       
   256 @@ -3340,6 +3364,11 @@ rb_eval(self, n)
       
   257  		rescuing = -1;
       
   258  		while (resq) {
       
   259  		    ruby_current_node = resq;
       
   260 +		    #ifdef ENABLE_DTRACE
       
   261 +		    if (RUBY_RESCUE_ENABLED())
       
   262 +		        if (ruby_current_node && ruby_current_node->nd_file)
       
   263 +			RUBY_RESCUE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   264 +		    #endif
       
   265  		    if (handle_rescue(self, resq)) {
       
   266  			state = 0;
       
   267  			rescuing = 1;
       
   268 @@ -4160,6 +4189,11 @@ rb_eval(self, n)
       
   269  	break;
       
   270  
       
   271        case NODE_NEWLINE:
       
   272 +	#ifdef ENABLE_DTRACE
       
   273 +	if (RUBY_LINE_ENABLED())
       
   274 +	    if (ruby_current_node && ruby_current_node->nd_file)
       
   275 +		RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   276 +	#endif
       
   277  	EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self, 
       
   278  			ruby_frame->last_func,
       
   279  			ruby_frame->last_class);
       
   280 @@ -4638,6 +4672,10 @@ rb_longjmp(tag, mesg)
       
   281  
       
   282      rb_trap_restore_mask();
       
   283      if (tag != TAG_FATAL) {
       
   284 +	#ifdef ENABLE_DTRACE
       
   285 +	if (RUBY_RAISE_ENABLED())
       
   286 +	    RUBY_RAISE(rb_obj_classname(ruby_errinfo), ruby_sourcefile, ruby_sourceline);
       
   287 +	#endif
       
   288  	EXEC_EVENT_HOOK(RUBY_EVENT_RAISE, ruby_current_node,
       
   289  			ruby_frame->self,
       
   290  			ruby_frame->last_func,
       
   291 @@ -5909,6 +5947,13 @@ rb_call0(klass, recv, id, oid, argc, arg
       
   292  		rb_bug("bad argc (%d) specified for `%s(%s)'",
       
   293  		       len, rb_class2name(klass), rb_id2name(id));
       
   294  	    }
       
   295 +    	    #ifdef ENABLE_DTRACE
       
   296 +	    if (RUBY_FUNCTION_ENTRY_ENABLED()) {
       
   297 +	    	    char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   298 +		    if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   299 +			RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   300 +	    }
       
   301 +	    #endif
       
   302  	    if (event_hooks) {
       
   303  		int state;
       
   304  
       
   305 @@ -5927,6 +5972,13 @@ rb_call0(klass, recv, id, oid, argc, arg
       
   306  	    else {
       
   307  		result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
       
   308  	    }
       
   309 +	    #ifdef ENABLE_DTRACE
       
   310 +    	    if (RUBY_FUNCTION_RETURN_ENABLED()) {
       
   311 +	        char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   312 +	        if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   313 +	            RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));			
       
   314 +	    }
       
   315 +	    #endif
       
   316  	}
       
   317  	break;
       
   318  
       
   319 @@ -5954,12 +6006,26 @@ rb_call0(klass, recv, id, oid, argc, arg
       
   320  
       
   321        case NODE_BMETHOD:
       
   322  	ruby_frame->flags |= FRAME_DMETH;
       
   323 +	#ifdef ENABLE_DTRACE
       
   324 +	if (RUBY_FUNCTION_ENTRY_ENABLED()) {
       
   325 +		char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   326 +		if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   327 +	            RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   328 +	 }
       
   329 +	#endif
       
   330  	if (event_hooks) {
       
   331  	    struct BLOCK *data;
       
   332  	    Data_Get_Struct(body->nd_cval, struct BLOCK, data);
       
   333  	    EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
       
   334  	}
       
   335  	result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
       
   336 +	#ifdef ENABLE_DTRACE
       
   337 +	 if (RUBY_FUNCTION_RETURN_ENABLED()) {
       
   338 +	    char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   339 +	    if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   340 +	        RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   341 +	}
       
   342 +	#endif
       
   343  	if (event_hooks) {
       
   344  	    EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
       
   345  	}
       
   346 @@ -6073,6 +6139,13 @@ rb_call0(klass, recv, id, oid, argc, arg
       
   347  		    }
       
   348  		    ruby_frame->argc = i;
       
   349  		}
       
   350 +		#ifdef ENABLE_DTRACE
       
   351 +		if (RUBY_FUNCTION_ENTRY_ENABLED()) {
       
   352 +			char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   353 +			if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   354 +		            RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   355 +		 }
       
   356 +		#endif
       
   357  		if (event_hooks) {
       
   358  		    EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);
       
   359  		}
       
   360 @@ -6083,6 +6156,13 @@ rb_call0(klass, recv, id, oid, argc, arg
       
   361  		state = 0;
       
   362  	    }
       
   363  	    POP_TAG();
       
   364 +	    #ifdef ENABLE_DTRACE
       
   365 +	     if (RUBY_FUNCTION_RETURN_ENABLED()) {
       
   366 +		char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
       
   367 +		if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
       
   368 +	 	    RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
       
   369 +	    }
       
   370 +	    #endif
       
   371  	    if (event_hooks) {
       
   372  		EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
       
   373  	    }
       
   374 diff -rupN ruby-1.8.7-p357.orig/gc.c ruby-1.8.7-p357/gc.c
       
   375 --- ruby-1.8.7-p357.orig/gc.c	2009-12-24 00:28:08.000000000 -0800
       
   376 +++ ruby-1.8.7-p357/gc.c	2012-01-23 14:50:29.562277000 -0800
       
   377 @@ -30,6 +30,11 @@
       
   378  #include <sys/resource.h>
       
   379  #endif
       
   380  
       
   381 +#ifdef ENABLE_DTRACE
       
   382 +#include <sys/sdt.h>
       
   383 +#include "dtrace.h"
       
   384 +#endif
       
   385 +
       
   386  #if defined _WIN32 || defined __CYGWIN__
       
   387  #include <windows.h>
       
   388  #endif
       
   389 @@ -1264,6 +1269,11 @@ obj_free(obj)
       
   390  	break;
       
   391      }
       
   392  
       
   393 +   #ifdef ENABLE_DTRACE
       
   394 +   if (RUBY_OBJECT_FREE_ENABLED())
       
   395 +      RUBY_OBJECT_FREE(rb_class2name(CLASS_OF(obj)));
       
   396 +   #endif
       
   397 +
       
   398      if (FL_TEST(obj, FL_EXIVAR)) {
       
   399  	rb_free_generic_ivar((VALUE)obj);
       
   400      }
       
   401 @@ -1430,6 +1440,12 @@ garbage_collect()
       
   402  {
       
   403      struct gc_list *list;
       
   404      struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug??  */
       
   405 +
       
   406 +    #ifdef ENABLE_DTRACE
       
   407 +    if (RUBY_GC_BEGIN_ENABLED())
       
   408 +       RUBY_GC_BEGIN();
       
   409 +    #endif
       
   410 +
       
   411      jmp_buf save_regs_gc_mark;
       
   412      SET_STACK_END;
       
   413  
       
   414 @@ -1522,6 +1538,11 @@ garbage_collect()
       
   415      } while (!MARK_STACK_EMPTY);
       
   416  
       
   417      gc_sweep();
       
   418 +
       
   419 +    #ifdef ENABLE_DTRACE
       
   420 +    if (RUBY_GC_END_ENABLED())
       
   421 +	RUBY_GC_END();
       
   422 +    #endif
       
   423  }
       
   424  
       
   425  void
       
   426 diff -rupN ruby-1.8.7-p357.orig/inits.c ruby-1.8.7-p357/inits.c
       
   427 --- ruby-1.8.7-p357.orig/inits.c	2011-12-28 04:47:15.000000000 -0800
       
   428 +++ ruby-1.8.7-p357/inits.c	2012-01-23 14:50:29.571286000 -0800
       
   429 @@ -48,6 +48,7 @@ void Init_Time _((void));
       
   430  void Init_var_tables _((void));
       
   431  void Init_version _((void));
       
   432  void Init_st _((void));
       
   433 +void Init_Tracer _((void));
       
   434  
       
   435  void
       
   436  rb_call_inits()
       
   437 @@ -87,4 +88,5 @@ rb_call_inits()
       
   438      Init_Enumerator();
       
   439      Init_marshal();
       
   440      Init_version();
       
   441 +    Init_Tracer();
       
   442  }
       
   443 diff -rupN ruby-1.8.7-p357.orig/Makefile.in ruby-1.8.7-p357/Makefile.in
       
   444 --- ruby-1.8.7-p357.orig/Makefile.in	2012-01-23 14:35:56.408791000 -0800
       
   445 +++ ruby-1.8.7-p357/Makefile.in	2012-01-23 14:50:29.579192000 -0800
       
   446 @@ -88,6 +88,7 @@ ASFLAGS       = @ASFLAGS@
       
   447  
       
   448  OBJEXT        = @OBJEXT@
       
   449  MANTYPE	      = @MANTYPE@
       
   450 +DTRACE_OBJS   = @DTRACE_OBJS@
       
   451  
       
   452  INSTALLED_LIST= .installed.list
       
   453  #### End of variables
       
   454 @@ -103,11 +104,11 @@ all:
       
   455  
       
   456  miniruby$(EXEEXT):
       
   457  		@$(RM) $@
       
   458 -		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
       
   459 +		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(DTRACE_OBJS) $(LIBS) $(OUTFLAG)$@
       
   460  
       
   461  $(PROGRAM):
       
   462  		@$(RM) $@
       
   463 -		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@
       
   464 +		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(DTRACE_OBJS) gc.o eval.o tracer.o $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@
       
   465  
       
   466  # We must `rm' the library each time this rule is invoked because "updating" a
       
   467  # MAB library on Apple/NeXT (see --enable-fat-binary in configure) is not
       
   468 @@ -119,7 +120,7 @@ $(LIBRUBY_A):
       
   469  
       
   470  $(LIBRUBY_SO):
       
   471  		@-$(PRE_LIBRUBY_UPDATE)
       
   472 -		$(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(SOLIBS) $(OUTFLAG)$@
       
   473 +		$(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(DTRACE_OBJS) $(SOLIBS) $(OUTFLAG)$@
       
   474  		@-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link if File.exist? link; \
       
   475  						  File.symlink "$(LIBRUBY_SO)", link}' \
       
   476  				$(LIBRUBY_ALIASES) || true
       
   477 @@ -194,6 +195,9 @@ distclean-local::
       
   478  ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
       
   479  	$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c
       
   480  
       
   481 +dtrace.@OBJEXT@: dtrace.d $(OBJS) $(MAINOBJ)
       
   482 +	/usr/sbin/dtrace -G -o $@ -s dtrace.d $(OBJS)
       
   483 +
       
   484  update-rubyspec: 
       
   485  	if [ -d $(srcdir)/rubyspec ]; then \
       
   486  	  cd $(srcdir)/rubyspec/mspec; \
       
   487 diff -rupN ruby-1.8.7-p357.orig/object.c ruby-1.8.7-p357/object.c
       
   488 --- ruby-1.8.7-p357.orig/object.c	2009-12-13 19:53:19.000000000 -0800
       
   489 +++ ruby-1.8.7-p357/object.c	2012-01-23 14:50:29.588706000 -0800
       
   490 @@ -20,6 +20,12 @@
       
   491  #include <ctype.h>
       
   492  #include <math.h>
       
   493  
       
   494 +#ifdef ENABLE_DTRACE
       
   495 +#include "dtrace.h"
       
   496 +#include "node.h"
       
   497 +NODE* ruby_current_node;
       
   498 +#endif
       
   499 +
       
   500  VALUE rb_mKernel;
       
   501  VALUE rb_cObject;
       
   502  VALUE rb_cModule;
       
   503 @@ -1603,7 +1609,25 @@ rb_obj_alloc(klass)
       
   504      if (FL_TEST(klass, FL_SINGLETON)) {
       
   505  	rb_raise(rb_eTypeError, "can't create instance of virtual class");
       
   506      }
       
   507 +
       
   508 +    #ifdef ENABLE_DTRACE
       
   509 +    if (RUBY_OBJECT_CREATE_START_ENABLED()) {
       
   510 +	char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file;
       
   511 +	int   line = ruby_current_node == NULL ? 0  : nd_line(ruby_current_node);
       
   512 +	RUBY_OBJECT_CREATE_START(rb_class2name(klass), file, line);
       
   513 +    }
       
   514 +    #endif
       
   515 +
       
   516      obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0);
       
   517 +
       
   518 +    #ifdef ENABLE_DTRACE
       
   519 +    if (RUBY_OBJECT_CREATE_DONE_ENABLED()) {
       
   520 +	char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file;
       
   521 +	int   line = ruby_current_node == NULL ? 0  : nd_line(ruby_current_node);
       
   522 +	RUBY_OBJECT_CREATE_DONE(rb_class2name(klass), file, line);
       
   523 +    }
       
   524 +    #endif
       
   525 +
       
   526      if (rb_obj_class(obj) != rb_class_real(klass)) {
       
   527  	rb_raise(rb_eTypeError, "wrong instance allocation");
       
   528      }
       
   529 diff -rupN ruby-1.8.7-p357.orig/tracer.c ruby-1.8.7-p357/tracer.c
       
   530 --- ruby-1.8.7-p357.orig/tracer.c	1969-12-31 16:00:00.000000000 -0800
       
   531 +++ ruby-1.8.7-p357/tracer.c	2012-01-23 14:50:29.606242000 -0800
       
   532 @@ -0,0 +1,64 @@
       
   533 +#include "ruby.h"
       
   534 +
       
   535 +#ifdef ENABLE_DTRACE
       
   536 +#include "dtrace.h"
       
   537 +#endif
       
   538 +
       
   539 +VALUE rb_mDtrace;
       
   540 +
       
   541 +static VALUE
       
   542 +ruby_dtrace_fire(argc, argv, klass)
       
   543 +  int argc;
       
   544 +  VALUE *argv;
       
   545 +  VALUE klass;
       
   546 +{
       
   547 +	int args;
       
   548 +	VALUE name, data, ret;
       
   549 +	char *probe_data;
       
   550 +	char *probe_name;
       
   551 +	char *start_probe;
       
   552 +	char *end_probe;
       
   553 +	
       
   554 +	#ifdef ENABLE_DTRACE
       
   555 +
       
   556 +	args = rb_scan_args(argc, argv, "11", &name, &data);
       
   557 +	probe_data = args == 2 ? StringValuePtr(data) : "";
       
   558 +	probe_name = StringValuePtr(name);
       
   559 +
       
   560 +    	if (rb_block_given_p()) {
       
   561 +		start_probe = malloc(strlen(probe_name) + 7);
       
   562 +		end_probe   = malloc(strlen(probe_name) + 5);
       
   563 +		
       
   564 +		sprintf(start_probe, "%s-start", probe_name);
       
   565 +		sprintf(end_probe, "%s-end", probe_name);
       
   566 +		
       
   567 +		/* Build -start and -end strings for probe names */
       
   568 +		if (RUBY_RUBY_PROBE_ENABLED())
       
   569 +			RUBY_RUBY_PROBE(start_probe, probe_data);
       
   570 +	#endif
       
   571 +	
       
   572 +		ret = rb_yield(Qnil);
       
   573 +	
       
   574 +	#if ENABLE_DTRACE
       
   575 +
       
   576 +		if (RUBY_RUBY_PROBE_ENABLED())
       
   577 +			RUBY_RUBY_PROBE(end_probe, probe_data);
       
   578 +		
       
   579 +		free(start_probe);
       
   580 +		free(end_probe);
       
   581 +    	} else {
       
   582 +		if (RUBY_RUBY_PROBE_ENABLED())
       
   583 +			RUBY_RUBY_PROBE(probe_name, probe_data);
       
   584 +		ret = Qnil;
       
   585 +	}
       
   586 +	#endif
       
   587 +    	return ret;
       
   588 +}
       
   589 +
       
   590 +
       
   591 +void Init_Tracer()
       
   592 +{
       
   593 +	rb_mDtrace = rb_define_module("DTracer");
       
   594 +	rb_define_module_function(rb_mDtrace, "fire", ruby_dtrace_fire, -1);
       
   595 +}
       
   596 +