--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ruby/ruby-18/patches/08-ruby-dtrace-1.8.7.patch Wed Nov 06 14:12:13 2013 -0800
@@ -0,0 +1,596 @@
+diff -rupN ruby-1.8.7-p357.orig/common.mk ruby-1.8.7-p357/common.mk
+--- ruby-1.8.7-p357.orig/common.mk 2010-11-21 23:22:16.000000000 -0800
++++ ruby-1.8.7-p357/common.mk 2012-01-23 14:50:29.502736000 -0800
+@@ -55,6 +55,7 @@ OBJS = array.$(OBJEXT) \
+ string.$(OBJEXT) \
+ struct.$(OBJEXT) \
+ time.$(OBJEXT) \
++ tracer.$(OBJEXT) \
+ util.$(OBJEXT) \
+ variable.$(OBJEXT) \
+ version.$(OBJEXT) \
+@@ -85,9 +86,9 @@ prog: $(PROGRAM) $(WPROGRAM)
+
+ miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) $(MINIOBJS) $(OBJS) $(DMYEXT)
+
+-$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
++$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(DTRACE_OBJS) $(SETUP) $(PREP)
+
+-$(LIBRUBY_A): $(OBJS) $(DMYEXT) $(ARCHFILE)
++$(LIBRUBY_A): $(OBJS) $(DMYEXT) $(ARCHFILE) $(DTRACE_OBJS)
+
+ $(LIBRUBY_SO): $(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(LIBRUBY_SO_UPDATE)
+
+@@ -280,7 +281,7 @@ clear-installed-list:
+
+ clean: clean-ext clean-local
+ clean-local::
+- @$(RM) $(OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
++ @$(RM) $(OBJS) $(DTRACE_OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
+ @$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) $(ARCHFILE) .*.time
+ @$(RM) y.tab.c y.output
+ clean-ext:
+diff -rupN ruby-1.8.7-p357.orig/configure.in ruby-1.8.7-p357/configure.in
+--- ruby-1.8.7-p357.orig/configure.in 2011-02-18 02:37:47.000000000 -0800
++++ ruby-1.8.7-p357/configure.in 2012-01-23 14:50:29.513537000 -0800
+@@ -524,6 +524,11 @@ AC_CHECK_HEADERS(stdlib.h string.h unist
+ sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \
+ ucontext.h intrinsics.h time.h)
+
++AC_CHECK_HEADER(sys/sdt.h)
++if test "$ac_cv_header_sys_sdt_h" == "yes"; then
++ AC_DEFINE(HAVE_SDT_H)
++fi
++
+ dnl Check additional types.
+ AC_CHECK_SIZEOF(rlim_t, 0, [
+ #ifdef HAVE_SYS_TYPES_H
+@@ -698,6 +703,18 @@ if test "$use_setreuid" = yes; then
+ AC_DEFINE(USE_SETREUID)
+ AC_DEFINE(USE_SETREGID)
+ fi
++
++AC_ARG_ENABLE(dtrace,
++ [ --enable-dtrace enable DTrace support.],
++ [enable_dtrace=$enableval])
++if test "$enable_dtrace" == "yes" -a "$ac_cv_header_sys_sdt_h" == "yes"; then
++ AC_DEFINE(ENABLE_DTRACE)
++ DTRACE_OBJS="dtrace.o"
++else
++ DTRACE_OBJS=""
++fi
++AC_SUBST(DTRACE_OBJS)
++
+ AC_STRUCT_TIMEZONE
+ AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
+ [AC_TRY_COMPILE([#include <time.h>],
+@@ -1207,7 +1224,7 @@ if test "$with_dln_a_out" != yes; then
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ fi
+ else
+- : ${LDSHARED='ld -G'}
++ : ${LDSHARED='$(CC) -G'}
+ fi
+ rb_cv_dlopen=yes;;
+ sunos*) : ${LDSHARED='ld -assert nodefinitions'}
+diff -rupN ruby-1.8.7-p357.orig/dtrace.d ruby-1.8.7-p357/dtrace.d
+--- ruby-1.8.7-p357.orig/dtrace.d 1969-12-31 16:00:00.000000000 -0800
++++ ruby-1.8.7-p357/dtrace.d 2012-01-23 14:50:29.525158000 -0800
+@@ -0,0 +1,26 @@
++/* -*- Mode: C -*- */
++
++provider ruby {
++ probe function__entry(char*, char*, char*, int);
++ probe function__return(char*, char*, char*, int);
++ probe raise(char*, char*, int);
++ probe rescue(char*, int);
++ probe line(char*, int);
++
++ /* gc probes */
++ probe gc__begin();
++ probe gc__end();
++
++ /* Some initial memory type probes */
++ probe object__create__start(char*, char*, int);
++ probe object__create__done(char*, char*, int);
++ probe object__free(char*);
++
++ probe ruby__probe(char*, char*);
++};
++
++#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
+diff -rupN ruby-1.8.7-p357.orig/dtrace.h ruby-1.8.7-p357/dtrace.h
+--- ruby-1.8.7-p357.orig/dtrace.h 1969-12-31 16:00:00.000000000 -0800
++++ ruby-1.8.7-p357/dtrace.h 2012-01-23 14:50:29.531660000 -0800
+@@ -0,0 +1,85 @@
++/*
++ * Generated by dtrace(1M).
++ */
++
++#ifndef _DTRACE_H
++#define _DTRACE_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define RUBY_FUNCTION_ENTRY(arg0, arg1, arg2, arg3) \
++ __dtrace_ruby___function__entry(arg0, arg1, arg2, arg3)
++#define RUBY_FUNCTION_ENTRY_ENABLED() \
++ __dtraceenabled_ruby___function__entry()
++#define RUBY_FUNCTION_RETURN(arg0, arg1, arg2, arg3) \
++ __dtrace_ruby___function__return(arg0, arg1, arg2, arg3)
++#define RUBY_FUNCTION_RETURN_ENABLED() \
++ __dtraceenabled_ruby___function__return()
++#define RUBY_GC_BEGIN() \
++ __dtrace_ruby___gc__begin()
++#define RUBY_GC_BEGIN_ENABLED() \
++ __dtraceenabled_ruby___gc__begin()
++#define RUBY_GC_END() \
++ __dtrace_ruby___gc__end()
++#define RUBY_GC_END_ENABLED() \
++ __dtraceenabled_ruby___gc__end()
++#define RUBY_LINE(arg0, arg1) \
++ __dtrace_ruby___line(arg0, arg1)
++#define RUBY_LINE_ENABLED() \
++ __dtraceenabled_ruby___line()
++#define RUBY_OBJECT_CREATE_DONE(arg0, arg1, arg2) \
++ __dtrace_ruby___object__create__done(arg0, arg1, arg2)
++#define RUBY_OBJECT_CREATE_DONE_ENABLED() \
++ __dtraceenabled_ruby___object__create__done()
++#define RUBY_OBJECT_CREATE_START(arg0, arg1, arg2) \
++ __dtrace_ruby___object__create__start(arg0, arg1, arg2)
++#define RUBY_OBJECT_CREATE_START_ENABLED() \
++ __dtraceenabled_ruby___object__create__start()
++#define RUBY_OBJECT_FREE(arg0) \
++ __dtrace_ruby___object__free(arg0)
++#define RUBY_OBJECT_FREE_ENABLED() \
++ __dtraceenabled_ruby___object__free()
++#define RUBY_RAISE(arg0, arg1, arg2) \
++ __dtrace_ruby___raise(arg0, arg1, arg2)
++#define RUBY_RAISE_ENABLED() \
++ __dtraceenabled_ruby___raise()
++#define RUBY_RESCUE(arg0, arg1) \
++ __dtrace_ruby___rescue(arg0, arg1)
++#define RUBY_RESCUE_ENABLED() \
++ __dtraceenabled_ruby___rescue()
++#define RUBY_RUBY_PROBE(arg0, arg1) \
++ __dtrace_ruby___ruby__probe(arg0, arg1)
++#define RUBY_RUBY_PROBE_ENABLED() \
++ __dtraceenabled_ruby___ruby__probe()
++
++
++extern void __dtrace_ruby___function__entry(char *, char *, char *, int);
++extern int __dtraceenabled_ruby___function__entry(void);
++extern void __dtrace_ruby___function__return(char *, char *, char *, int);
++extern int __dtraceenabled_ruby___function__return(void);
++extern void __dtrace_ruby___gc__begin(void);
++extern int __dtraceenabled_ruby___gc__begin(void);
++extern void __dtrace_ruby___gc__end(void);
++extern int __dtraceenabled_ruby___gc__end(void);
++extern void __dtrace_ruby___line(char *, int);
++extern int __dtraceenabled_ruby___line(void);
++extern void __dtrace_ruby___object__create__done(char *, char *, int);
++extern int __dtraceenabled_ruby___object__create__done(void);
++extern void __dtrace_ruby___object__create__start(char *, char *, int);
++extern int __dtraceenabled_ruby___object__create__start(void);
++extern void __dtrace_ruby___object__free(char *);
++extern int __dtraceenabled_ruby___object__free(void);
++extern void __dtrace_ruby___raise(char *, char *, int);
++extern int __dtraceenabled_ruby___raise(void);
++extern void __dtrace_ruby___rescue(char *, int);
++extern int __dtraceenabled_ruby___rescue(void);
++extern void __dtrace_ruby___ruby__probe(char *, char *);
++extern int __dtraceenabled_ruby___ruby__probe(void);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _DTRACE_H */
+diff -rupN ruby-1.8.7-p357.orig/eval.c ruby-1.8.7-p357/eval.c
+--- ruby-1.8.7-p357.orig/eval.c 2011-05-22 21:49:40.000000000 -0700
++++ ruby-1.8.7-p357/eval.c 2012-01-23 14:50:29.548765000 -0800
+@@ -226,6 +226,10 @@ int _setjmp(), _longjmp();
+
+ #include <sys/stat.h>
+
++#ifdef ENABLE_DTRACE
++#include "dtrace.h"
++#endif
++
+ VALUE rb_cProc;
+ VALUE rb_cBinding;
+ static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE));
+@@ -3059,12 +3063,22 @@ rb_eval(self, n)
+
+ case NODE_IF:
+ if (RTEST(rb_eval(self, node->nd_cond))) {
++ #ifdef ENABLE_DTRACE
++ if (RUBY_LINE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
+ ruby_frame->last_func,
+ ruby_frame->last_class);
+ node = node->nd_body;
+ }
+ else {
++ #ifdef ENABLE_DTRACE
++ if (RUBY_LINE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
+ ruby_frame->last_func,
+ ruby_frame->last_class);
+@@ -3079,6 +3093,11 @@ rb_eval(self, n)
+ if (nd_type(node) != NODE_WHEN) goto again;
+ tag = node->nd_head;
+ while (tag) {
++ #ifdef ENABLE_DTRACE
++ if (RUBY_LINE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
+ ruby_frame->last_func,
+ ruby_frame->last_class);
+@@ -3120,6 +3139,11 @@ rb_eval(self, n)
+ }
+ tag = node->nd_head;
+ while (tag) {
++ #ifdef ENABLE_DTRACE
++ if (RUBY_LINE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
+ ruby_frame->last_func,
+ ruby_frame->last_class);
+@@ -3340,6 +3364,11 @@ rb_eval(self, n)
+ rescuing = -1;
+ while (resq) {
+ ruby_current_node = resq;
++ #ifdef ENABLE_DTRACE
++ if (RUBY_RESCUE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_RESCUE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ if (handle_rescue(self, resq)) {
+ state = 0;
+ rescuing = 1;
+@@ -4160,6 +4189,11 @@ rb_eval(self, n)
+ break;
+
+ case NODE_NEWLINE:
++ #ifdef ENABLE_DTRACE
++ if (RUBY_LINE_ENABLED())
++ if (ruby_current_node && ruby_current_node->nd_file)
++ RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node));
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
+ ruby_frame->last_func,
+ ruby_frame->last_class);
+@@ -4638,6 +4672,10 @@ rb_longjmp(tag, mesg)
+
+ rb_trap_restore_mask();
+ if (tag != TAG_FATAL) {
++ #ifdef ENABLE_DTRACE
++ if (RUBY_RAISE_ENABLED())
++ RUBY_RAISE(rb_obj_classname(ruby_errinfo), ruby_sourcefile, ruby_sourceline);
++ #endif
+ EXEC_EVENT_HOOK(RUBY_EVENT_RAISE, ruby_current_node,
+ ruby_frame->self,
+ ruby_frame->last_func,
+@@ -5909,6 +5947,13 @@ rb_call0(klass, recv, id, oid, argc, arg
+ rb_bug("bad argc (%d) specified for `%s(%s)'",
+ len, rb_class2name(klass), rb_id2name(id));
+ }
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_ENTRY_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ if (event_hooks) {
+ int state;
+
+@@ -5927,6 +5972,13 @@ rb_call0(klass, recv, id, oid, argc, arg
+ else {
+ result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
+ }
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_RETURN_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ }
+ break;
+
+@@ -5954,12 +6006,26 @@ rb_call0(klass, recv, id, oid, argc, arg
+
+ case NODE_BMETHOD:
+ ruby_frame->flags |= FRAME_DMETH;
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_ENTRY_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ if (event_hooks) {
+ struct BLOCK *data;
+ Data_Get_Struct(body->nd_cval, struct BLOCK, data);
+ EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
+ }
+ result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_RETURN_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ if (event_hooks) {
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
+ }
+@@ -6073,6 +6139,13 @@ rb_call0(klass, recv, id, oid, argc, arg
+ }
+ ruby_frame->argc = i;
+ }
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_ENTRY_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ if (event_hooks) {
+ EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);
+ }
+@@ -6083,6 +6156,13 @@ rb_call0(klass, recv, id, oid, argc, arg
+ state = 0;
+ }
+ POP_TAG();
++ #ifdef ENABLE_DTRACE
++ if (RUBY_FUNCTION_RETURN_ENABLED()) {
++ char *classname = rb_class2name(klass), *methodname = rb_id2name(id);
++ if (ruby_current_node && ruby_current_node->nd_file && classname && methodname)
++ RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node));
++ }
++ #endif
+ if (event_hooks) {
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
+ }
+diff -rupN ruby-1.8.7-p357.orig/gc.c ruby-1.8.7-p357/gc.c
+--- ruby-1.8.7-p357.orig/gc.c 2009-12-24 00:28:08.000000000 -0800
++++ ruby-1.8.7-p357/gc.c 2012-01-23 14:50:29.562277000 -0800
+@@ -30,6 +30,11 @@
+ #include <sys/resource.h>
+ #endif
+
++#ifdef ENABLE_DTRACE
++#include <sys/sdt.h>
++#include "dtrace.h"
++#endif
++
+ #if defined _WIN32 || defined __CYGWIN__
+ #include <windows.h>
+ #endif
+@@ -1264,6 +1269,11 @@ obj_free(obj)
+ break;
+ }
+
++ #ifdef ENABLE_DTRACE
++ if (RUBY_OBJECT_FREE_ENABLED())
++ RUBY_OBJECT_FREE(rb_class2name(CLASS_OF(obj)));
++ #endif
++
+ if (FL_TEST(obj, FL_EXIVAR)) {
+ rb_free_generic_ivar((VALUE)obj);
+ }
+@@ -1430,6 +1440,12 @@ garbage_collect()
+ {
+ struct gc_list *list;
+ struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
++
++ #ifdef ENABLE_DTRACE
++ if (RUBY_GC_BEGIN_ENABLED())
++ RUBY_GC_BEGIN();
++ #endif
++
+ jmp_buf save_regs_gc_mark;
+ SET_STACK_END;
+
+@@ -1522,6 +1538,11 @@ garbage_collect()
+ } while (!MARK_STACK_EMPTY);
+
+ gc_sweep();
++
++ #ifdef ENABLE_DTRACE
++ if (RUBY_GC_END_ENABLED())
++ RUBY_GC_END();
++ #endif
+ }
+
+ void
+diff -rupN ruby-1.8.7-p357.orig/inits.c ruby-1.8.7-p357/inits.c
+--- ruby-1.8.7-p357.orig/inits.c 2011-12-28 04:47:15.000000000 -0800
++++ ruby-1.8.7-p357/inits.c 2012-01-23 14:50:29.571286000 -0800
+@@ -48,6 +48,7 @@ void Init_Time _((void));
+ void Init_var_tables _((void));
+ void Init_version _((void));
+ void Init_st _((void));
++void Init_Tracer _((void));
+
+ void
+ rb_call_inits()
+@@ -87,4 +88,5 @@ rb_call_inits()
+ Init_Enumerator();
+ Init_marshal();
+ Init_version();
++ Init_Tracer();
+ }
+diff -rupN ruby-1.8.7-p357.orig/Makefile.in ruby-1.8.7-p357/Makefile.in
+--- ruby-1.8.7-p357.orig/Makefile.in 2012-01-23 14:35:56.408791000 -0800
++++ ruby-1.8.7-p357/Makefile.in 2012-01-23 14:50:29.579192000 -0800
+@@ -88,6 +88,7 @@ ASFLAGS = @ASFLAGS@
+
+ OBJEXT = @OBJEXT@
+ MANTYPE = @MANTYPE@
++DTRACE_OBJS = @DTRACE_OBJS@
+
+ INSTALLED_LIST= .installed.list
+ #### End of variables
+@@ -103,11 +104,11 @@ all:
+
+ miniruby$(EXEEXT):
+ @$(RM) $@
+- $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
++ $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(DTRACE_OBJS) $(LIBS) $(OUTFLAG)$@
+
+ $(PROGRAM):
+ @$(RM) $@
+- $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@
++ $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(DTRACE_OBJS) gc.o eval.o tracer.o $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@
+
+ # We must `rm' the library each time this rule is invoked because "updating" a
+ # MAB library on Apple/NeXT (see --enable-fat-binary in configure) is not
+@@ -119,7 +120,7 @@ $(LIBRUBY_A):
+
+ $(LIBRUBY_SO):
+ @-$(PRE_LIBRUBY_UPDATE)
+- $(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(SOLIBS) $(OUTFLAG)$@
++ $(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(DTRACE_OBJS) $(SOLIBS) $(OUTFLAG)$@
+ @-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link if File.exist? link; \
+ File.symlink "$(LIBRUBY_SO)", link}' \
+ $(LIBRUBY_ALIASES) || true
+@@ -194,6 +195,9 @@ distclean-local::
+ ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
+ $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c
+
++dtrace.@OBJEXT@: dtrace.d $(OBJS) $(MAINOBJ)
++ /usr/sbin/dtrace -G -o $@ -s dtrace.d $(OBJS)
++
+ update-rubyspec:
+ if [ -d $(srcdir)/rubyspec ]; then \
+ cd $(srcdir)/rubyspec/mspec; \
+diff -rupN ruby-1.8.7-p357.orig/object.c ruby-1.8.7-p357/object.c
+--- ruby-1.8.7-p357.orig/object.c 2009-12-13 19:53:19.000000000 -0800
++++ ruby-1.8.7-p357/object.c 2012-01-23 14:50:29.588706000 -0800
+@@ -20,6 +20,12 @@
+ #include <ctype.h>
+ #include <math.h>
+
++#ifdef ENABLE_DTRACE
++#include "dtrace.h"
++#include "node.h"
++NODE* ruby_current_node;
++#endif
++
+ VALUE rb_mKernel;
+ VALUE rb_cObject;
+ VALUE rb_cModule;
+@@ -1603,7 +1609,25 @@ rb_obj_alloc(klass)
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ rb_raise(rb_eTypeError, "can't create instance of virtual class");
+ }
++
++ #ifdef ENABLE_DTRACE
++ if (RUBY_OBJECT_CREATE_START_ENABLED()) {
++ char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file;
++ int line = ruby_current_node == NULL ? 0 : nd_line(ruby_current_node);
++ RUBY_OBJECT_CREATE_START(rb_class2name(klass), file, line);
++ }
++ #endif
++
+ obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0);
++
++ #ifdef ENABLE_DTRACE
++ if (RUBY_OBJECT_CREATE_DONE_ENABLED()) {
++ char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file;
++ int line = ruby_current_node == NULL ? 0 : nd_line(ruby_current_node);
++ RUBY_OBJECT_CREATE_DONE(rb_class2name(klass), file, line);
++ }
++ #endif
++
+ if (rb_obj_class(obj) != rb_class_real(klass)) {
+ rb_raise(rb_eTypeError, "wrong instance allocation");
+ }
+diff -rupN ruby-1.8.7-p357.orig/tracer.c ruby-1.8.7-p357/tracer.c
+--- ruby-1.8.7-p357.orig/tracer.c 1969-12-31 16:00:00.000000000 -0800
++++ ruby-1.8.7-p357/tracer.c 2012-01-23 14:50:29.606242000 -0800
+@@ -0,0 +1,64 @@
++#include "ruby.h"
++
++#ifdef ENABLE_DTRACE
++#include "dtrace.h"
++#endif
++
++VALUE rb_mDtrace;
++
++static VALUE
++ruby_dtrace_fire(argc, argv, klass)
++ int argc;
++ VALUE *argv;
++ VALUE klass;
++{
++ int args;
++ VALUE name, data, ret;
++ char *probe_data;
++ char *probe_name;
++ char *start_probe;
++ char *end_probe;
++
++ #ifdef ENABLE_DTRACE
++
++ args = rb_scan_args(argc, argv, "11", &name, &data);
++ probe_data = args == 2 ? StringValuePtr(data) : "";
++ probe_name = StringValuePtr(name);
++
++ if (rb_block_given_p()) {
++ start_probe = malloc(strlen(probe_name) + 7);
++ end_probe = malloc(strlen(probe_name) + 5);
++
++ sprintf(start_probe, "%s-start", probe_name);
++ sprintf(end_probe, "%s-end", probe_name);
++
++ /* Build -start and -end strings for probe names */
++ if (RUBY_RUBY_PROBE_ENABLED())
++ RUBY_RUBY_PROBE(start_probe, probe_data);
++ #endif
++
++ ret = rb_yield(Qnil);
++
++ #if ENABLE_DTRACE
++
++ if (RUBY_RUBY_PROBE_ENABLED())
++ RUBY_RUBY_PROBE(end_probe, probe_data);
++
++ free(start_probe);
++ free(end_probe);
++ } else {
++ if (RUBY_RUBY_PROBE_ENABLED())
++ RUBY_RUBY_PROBE(probe_name, probe_data);
++ ret = Qnil;
++ }
++ #endif
++ return ret;
++}
++
++
++void Init_Tracer()
++{
++ rb_mDtrace = rb_define_module("DTracer");
++ rb_define_module_function(rb_mDtrace, "fire", ruby_dtrace_fire, -1);
++}
++