public
Description: Rubinius, the Ruby VM
Homepage: http://rubini.us
Clone URL: git://github.com/evanphx/rubinius.git
Added DTrace probes for function-entry/return and gc-begin/end.

Probes are disabled by default, see shotgun/vars.mk to enable them in your build 
on a DTrace compatible machine.
Probe signatures are compatible with Joyent's Ruby probes, with the exception of 
the provider name (Rubinius).
Example dtrace scripts and documentation forthcoming.
crafterm (author)
Sun Jan 27 16:40:54 -0800 2008
commit  46513843cedfe47bd5710aa3756230aa15a1570a
tree    c5164b2b9eaa5a03b6838052acc1b95774345b8f
parent  b9e5fc471bdb331ee7d84e04a4baccef3baf89d4
...
35
36
37
38
39
40
41
...
35
36
37
 
38
39
40
0
@@ -35,7 +35,6 @@ runtime/platform.conf
0
 *.swp
0
 *.dylib
0
 *.so
0
-*.d
0
 *~
0
 \#*
0
 .\#*
...
10
11
12
 
 
 
 
 
 
13
14
15
...
109
110
111
112
 
113
114
115
...
117
118
119
 
 
 
120
121
122
...
10
11
12
13
14
15
16
17
18
19
20
21
...
115
116
117
 
118
119
120
121
...
123
124
125
126
127
128
129
130
131
0
@@ -10,6 +10,12 @@ else
0
   BINSUFFIX?=
0
 endif
0
 
0
+ifdef DTRACE
0
+  DTRACE_H=dtrace.h
0
+else
0
+  DTRACE_H=
0
+endif
0
+
0
 CFLAGS += -I.. $(CPPFLAGS) -Iexternal_libs/libbstring -Iexternal_libs/libcchash -Iexternal_libs/libmpa -Iexternal_libs/libmquark -Iexternal_libs/libev
0
 
0
 ALIBS=external_libs/libtommath/libtommath.a external_libs/onig/.libs/libonig.a external_libs/libzip/lib/.libs/libzip.a external_libs/libltdl/.libs/libltdl.a external_libs/libev/.libs/libev.a external_libs/libbstring/libbstring.a external_libs/libcchash/libcchash.a external_libs/libmpa/libptr_array.a external_libs/libmquark/libmquark.a
0
@@ -109,7 +115,7 @@ external_libs/libmpa/libptr_array.a:
0
 external_libs/libmquark/libmquark.a:
0
   cd external_libs/libmquark; $(MAKE)
0
 
0
-$(RBLIB): config.h $(ALIBS) external_libs/lightning/config.h 
0
+$(RBLIB): config.h $(DTRACE_H) $(ALIBS) external_libs/lightning/config.h 
0
   cd lib; $(MAKE) library; 
0
 
0
 .PHONY: $(RBLIB)
0
@@ -117,6 +123,9 @@ $(RBLIB): config.h $(ALIBS) external_libs/lightning/config.h
0
 # Don't try to build main until librubinius exists
0
 main.c: $(RBLIB)
0
 
0
+dtrace.h: rubinius.d
0
+  /usr/sbin/dtrace -h -s rubinius.d -o dtrace.h
0
+
0
 rubinius.bin: $(RBLIB) main.o
0
   $(COMP) -o rubinius.bin main.o $(RBLIB) $(BIN_RPATH)
0
 
...
162
163
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
166
167
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
0
@@ -162,6 +162,28 @@ void cpu_add_roots(STATE, cpu c, ptr_array roots) {
0
   #undef ar
0
 }
0
 
0
+int cpu_ip2line(STATE, OBJECT meth, int ip) {
0
+  OBJECT lines, tup;
0
+  int l, total, start, nd, op;
0
+  
0
+  if(meth->obj_type != CMethodType) return 0;
0
+
0
+  lines = cmethod_get_lines(meth);
0
+  total = NUM_FIELDS(lines);
0
+  for(l = 0; l < total; l++) {
0
+    tup = tuple_at(state, lines, l);
0
+    start = FIXNUM_TO_INT(tuple_at(state, tup, 0));
0
+    nd = FIXNUM_TO_INT(tuple_at(state, tup, 1));
0
+    op = FIXNUM_TO_INT(tuple_at(state, tup, 2));
0
+
0
+    if(ip >= start && ip <= nd) {
0
+      return op;
0
+    }
0
+  }
0
+
0
+  return 0;
0
+}
0
+
0
 void cpu_update_roots(STATE, cpu c, ptr_array roots, int start) {
0
   xpointer tmp;
0
   int i, len;
...
201
202
203
 
 
204
205
206
...
201
202
203
204
205
206
207
208
0
@@ -201,6 +201,8 @@ OBJECT cpu_marshal_to_file(STATE, OBJECT obj, char *path, int version);
0
 void cpu_bootstrap(STATE);
0
 void cpu_add_roots(STATE, cpu c, ptr_array roots);
0
 void cpu_update_roots(STATE, cpu c, ptr_array roots, int start);
0
+int cpu_ip2line(STATE, OBJECT meth, int ip);
0
+
0
 
0
 /* Method cache functions */
0
 void cpu_clear_cache(STATE, cpu c);
...
16
17
18
 
 
 
 
 
 
 
19
20
21
...
553
554
555
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
557
558
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
560
561
...
647
648
649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
651
652
...
710
711
712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
714
715
...
856
857
858
859
 
860
 
861
862
863
...
933
934
935
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
937
938
...
1281
1282
1283
 
 
 
 
 
 
1284
1285
1286
...
1311
1312
1313
 
 
 
 
 
 
1314
1315
1316
...
16
17
18
19
20
21
22
23
24
25
26
27
28
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
...
928
929
930
 
931
932
933
934
935
936
...
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
...
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
...
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
0
@@ -16,6 +16,13 @@
0
 #include "shotgun/lib/fixnum.h"
0
 #include "shotgun/lib/primitive_util.h"
0
 
0
+#if CONFIG_ENABLE_DTRACE
0
+#include "dtrace.h"
0
+#define ENABLE_DTRACE 1
0
+#else
0
+#define ENABLE_DTRACE 0
0
+#endif
0
+
0
 #define RISA(obj,cls) (REFERENCE_P(obj) && ISA(obj,BASIC_CLASS(cls)))
0
 
0
 #define next_int _int = *ip_ptr++;
0
@@ -553,9 +560,39 @@ static inline int cpu_try_primitive(STATE, cpu c, OBJECT mo, OBJECT recv, int ar
0
   req = FIXNUM_TO_INT(cmethod_get_required(mo));
0
   
0
   if(args == req || req < 0) {
0
+#if ENABLE_DTRACE
0
+  if (RUBINIUS_FUNCTION_ENTRY_ENABLED()) {
0
+    const char * module_name = mod == Qnil ? "<unknown>" : rbs_symbol_to_cstring(state, module_get_name(mod));
0
+    const char * method_name = rbs_symbol_to_cstring(state, sym);
0
+
0
+    cpu_flush_ip(c);
0
+
0
+    struct fast_context *fc = FASTCTX(c->active_context);
0
+    int line_number = cpu_ip2line(state, fc->method, fc->ip);
0
+    const char * filename = rbs_symbol_to_cstring(state, cmethod_get_file(fc->method));
0
+
0
+    RUBINIUS_FUNCTION_ENTRY(module_name, method_name, filename, line_number);
0
+  }
0
+#endif
0
+    
0
     stack_push(recv);
0
     if(cpu_perform_primitive(state, c, prim, mo, args, sym, mod, block)) {
0
       /* Worked! */
0
+      
0
+#if ENABLE_DTRACE
0
+  if (RUBINIUS_FUNCTION_RETURN_ENABLED()) {
0
+    const char * module_name = mod == Qnil ? "<unknown>" : rbs_symbol_to_cstring(state, module_get_name(mod));
0
+    const char * method_name = rbs_symbol_to_cstring(state, sym);
0
+
0
+    cpu_flush_ip(c);
0
+
0
+    struct fast_context *fc = FASTCTX(c->active_context);
0
+    int line_number = cpu_ip2line(state, fc->method, fc->ip);
0
+    const char * filename = rbs_symbol_to_cstring(state, cmethod_get_file(fc->method));
0
+
0
+    RUBINIUS_FUNCTION_RETURN(module_name, method_name, filename, line_number);
0
+  }
0
+#endif
0
       return TRUE;
0
     }
0
     /* Didn't work, need to remove the recv we put on before. */
0
@@ -647,6 +684,23 @@ void nmc_activate(STATE, cpu c, OBJECT nmc, OBJECT val, int reraise);
0
 inline int cpu_simple_return(STATE, cpu c, OBJECT val) {
0
   OBJECT destination, home;
0
 
0
+#if ENABLE_DTRACE
0
+  if (RUBINIUS_FUNCTION_RETURN_ENABLED()) {
0
+    OBJECT module = cpu_current_module(state, c);
0
+    
0
+    const char * module_name = (module == Qnil) ? "<unknown>" : rbs_symbol_to_cstring(state, module_get_name(module));
0
+    const char * method_name = rbs_symbol_to_cstring(state, cmethod_get_name(cpu_current_method(state, c)));
0
+    
0
+    cpu_flush_ip(c);
0
+    
0
+    struct fast_context *fc = FASTCTX(c->active_context);
0
+    int line_number = cpu_ip2line(state, fc->method, fc->ip);
0
+    const char * filename = rbs_symbol_to_cstring(state, cmethod_get_file(fc->method));
0
+
0
+    RUBINIUS_FUNCTION_RETURN(module_name, method_name, filename, line_number);
0
+  }
0
+#endif
0
+
0
   destination = cpu_current_sender(c);
0
   
0
   // printf("Rtrnng frm %p (%d)\n", c->active_context, FASTCTX(c->active_context)->size);
0
@@ -710,6 +764,24 @@ inline int cpu_return_to_sender(STATE, cpu c, OBJECT val, int consider_block, in
0
   
0
   is_block = blokctx_s_block_context_p(state, c->active_context);
0
   destination = cpu_current_sender(c);
0
+  
0
+#if ENABLE_DTRACE
0
+  if (RUBINIUS_FUNCTION_RETURN_ENABLED() && !is_block) {
0
+    OBJECT module = cpu_current_module(state, c);
0
+
0
+    const char * module_name = (module == Qnil) ? "<unknown>" : rbs_symbol_to_cstring(state, module_get_name(module));
0
+    const char * method_name = rbs_symbol_to_cstring(state, cmethod_get_name(cpu_current_method(state, c)));
0
+
0
+    cpu_flush_ip(c);
0
+    
0
+    struct fast_context *fc = FASTCTX(c->active_context);
0
+    int line_number = cpu_ip2line(state, fc->method, fc->ip);
0
+    const char * filename = rbs_symbol_to_cstring(state, cmethod_get_file(fc->method));
0
+
0
+    RUBINIUS_FUNCTION_RETURN(module_name, method_name, filename, line_number);
0
+  }
0
+#endif
0
+  
0
     
0
   if(destination == Qnil) {
0
     object_memory_retire_context(state->om, c->active_context);
0
@@ -856,8 +928,9 @@ static inline void cpu_return_to_block_creator(STATE, cpu c) {
0
 inline void cpu_goto_method(STATE, cpu c, OBJECT recv, OBJECT meth,
0
                                      int count, OBJECT name, OBJECT block) {
0
   OBJECT ctx;
0
-  
0
+
0
   if(cpu_try_primitive(state, c, meth, recv, count, name, Qnil, block)) { return; }
0
+
0
   ctx = cpu_create_context(state, c, recv, meth, name, 
0
         _real_class(state, recv), (unsigned long int)count, block);
0
   cpu_activate_context(state, c, ctx, ctx, 0);
0
@@ -933,6 +1006,22 @@ static inline void _cpu_build_and_activate(STATE, cpu c, OBJECT mo,
0
       missing ? "METHOD MISSING" : ""
0
       );
0
   }
0
+  
0
+#if ENABLE_DTRACE
0
+  if (RUBINIUS_FUNCTION_ENTRY_ENABLED()) {
0
+    const char * module_name = rbs_symbol_to_cstring(state, module_get_name(mod));
0
+    const char * method_name = rbs_symbol_to_cstring(state, sym);
0
+
0
+    cpu_flush_ip(c);
0
+
0
+    struct fast_context *fc = FASTCTX(c->active_context);
0
+    int line_number = cpu_ip2line(state, fc->method, fc->ip);
0
+    const char * filename = rbs_symbol_to_cstring(state, cmethod_get_file(fc->method));
0
+
0
+    RUBINIUS_FUNCTION_ENTRY(module_name, method_name, filename, line_number);
0
+  }
0
+#endif
0
+
0
   ctx = cpu_create_context(state, c, recv, mo, sym, mod, (unsigned long int)args, block);
0
   /* If it was missing, setup some extra data in the MethodContext for
0
      the method_missing method to check out, to see why it was missing. */
0
@@ -1281,6 +1370,12 @@ next_op:
0
 #endif
0
 check_interrupts:
0
     if(state->om->collect_now) {
0
+
0
+#if ENABLE_DTRACE
0
+      if (RUBINIUS_GC_BEGIN_ENABLED()) {
0
+        RUBINIUS_GC_BEGIN();
0
+      }
0
+#endif      
0
       int cm = state->om->collect_now;
0
       
0
       /* Collect the first generation. */
0
@@ -1311,6 +1406,12 @@ check_interrupts:
0
       }
0
       
0
       state->om->collect_now = 0;
0
+
0
+#if ENABLE_DTRACE
0
+      if (RUBINIUS_GC_END_ENABLED()) {
0
+        RUBINIUS_GC_END();
0
+      }
0
+#endif      
0
     }
0
     
0
     if(state->check_events) {
...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
102
103
104
105
 
106
107
108
...
33
34
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
37
38
...
82
83
84
 
85
86
87
88
0
@@ -33,26 +33,6 @@ static int _recursive_reporting = 0;
0
 
0
 #define SYM2STR(st, sym) string_byte_address(st, rbs_symbol_to_string(st, sym))
0
 
0
-static int _ip2line(STATE, OBJECT meth, int ip) {
0
-  OBJECT lines, tup;
0
-  int l, total, start, nd, op;
0
-
0
-  lines = cmethod_get_lines(meth);
0
-  total = NUM_FIELDS(lines);
0
-  for(l = 0; l < total; l++) {
0
-    tup = tuple_at(state, lines, l);
0
-    start = FIXNUM_TO_INT(tuple_at(state, tup, 0));
0
-    nd = FIXNUM_TO_INT(tuple_at(state, tup, 1));
0
-    op = FIXNUM_TO_INT(tuple_at(state, tup, 2));
0
-
0
-    if(ip >= start && ip <= nd) {
0
-      return op;
0
-    }
0
-  }
0
-
0
-  return 0;
0
-}
0
-
0
 void machine_print_callstack_limited(machine m, int maxlev) {
0
   OBJECT context, tmp;
0
   const char *modname, *methname, *filename;
0
@@ -102,7 +82,7 @@ void machine_print_callstack_limited(machine m, int maxlev) {
0
       (void*)context, modname, methname,
0
       fc->ip,
0
       filename,
0
-      _ip2line(m->s, fc->method, fc->ip)
0
+      cpu_ip2line(m->s, fc->method, fc->ip)
0
     );
0
     context = fc->sender;
0
   }
...
73
74
75
 
 
 
 
 
76
77
 
78
79
80
...
73
74
75
76
77
78
79
80
81
82
83
84
85
86
0
@@ -73,8 +73,14 @@ echo "#define CONFIG_EXTPATH \"$EXTPATH\""
0
 echo "#define CONFIG_BUILDREV \"$BUILDREV\""
0
 echo "#define CONFIG_ENGINE \"$ENGINE\""
0
 echo "#define CONFIG_CC \"$CC\""
0
+
0
+if test "$DTRACE" = "1"; then
0
+  echo "#define CONFIG_ENABLE_DTRACE 1"
0
+fi
0
+
0
 ) > config.h
0
 
0
+
0
 if config/run is64bit; then
0
   echo "#define CONFIG_WORDSIZE 64" >> config.h
0
   echo "#define CONFIG_ENABLE_DT 0" >> config.h
...
6
7
8
 
 
...
6
7
8
9
10
0
@@ -6,3 +6,5 @@ RUBY_PATCHLEVEL=111
0
 
0
 LIBVER=0.8
0
 VERSION=${LIBVER}.0
0
+
0
+DTRACE=0

Comments