XRay 1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -35,17 +35,16 @@ module XRay
35
35
  # evaling a block .
36
36
  #
37
37
  # The first argument passed will be passed to the D script as arg0 for
38
- # the ruby-probe probe. This is conventionally a probe base name. The
39
- # probes which fire before and after the block runs will have
40
- # "-start" and "-end" appended, respectively.
38
+ # the ruby-probe probe. The first argument is conventionally a
39
+ # probe base name. The probes which fire before and after the block
40
+ # runs will have "-start" and "-end" appended to the probe base name,
41
+ # respectively.
41
42
  #
42
43
  # The second argument is optional and can be used to pass additional
43
44
  # data into the D script as arg1.
44
45
  #
45
46
  # Example:
46
47
  #
47
- # XRay::DTrace::Tracer.fire('service-start', "order processing")
48
- #
49
48
  # XRay::DTrace::Tracer.firing('db-query', "select * from dual;") do
50
49
  # ActiveRecord::Base.execute("select * from dual;")
51
50
  #
@@ -65,7 +64,7 @@ module XRay
65
64
  result
66
65
  end
67
66
 
68
- # Returns true if ruby-probe probes are enables
67
+ # Returns true if ruby-probe probes are enabled.
69
68
  # (application-level probes for Ruby).
70
69
  def enabled?
71
70
  DTracer.enabled?
@@ -74,8 +73,6 @@ module XRay
74
73
 
75
74
  elsif Object.const_defined?(:Tracer) && Tracer.methods.include?(:fire) ### Joyent Tracer ##
76
75
 
77
- raise "got here"
78
-
79
76
  def fire(name, data = nil) #:nodoc: all
80
77
 
81
78
  ::Tracer.fire(name, data)
@@ -0,0 +1,511 @@
1
+ Index: Makefile.in
2
+ ===================================================================
3
+ --- Makefile.in (revision 16089)
4
+ +++ Makefile.in (working copy)
5
+ @@ -86,6 +86,8 @@
6
+ OBJEXT = @OBJEXT@
7
+ MANTYPE = @MANTYPE@
8
+
9
+ +DTRACE_HEADER = @DTRACE_HEADER@
10
+ +
11
+ INSTALLED_LIST= .installed.list
12
+ #### End of variables
13
+
14
+ @@ -171,8 +173,11 @@
15
+ $(AS) $(ASFLAGS) -o $@ $<
16
+
17
+ clean-local::
18
+ - @$(RM) ext/extinit.c ext/extinit.$(OBJEXT)
19
+ + @$(RM) ext/extinit.c ext/extinit.$(OBJEXT) $(DTRACE_HEADER)
20
+
21
+ +dtrace.h: dtrace.d
22
+ + /usr/sbin/dtrace -h -s dtrace.d
23
+ +
24
+ distclean-local::
25
+ @$(RM) ext/config.cache $(RBCONFIG)
26
+
27
+ Index: configure.in
28
+ ===================================================================
29
+ --- configure.in (revision 16089)
30
+ +++ configure.in (working copy)
31
+ @@ -488,6 +488,11 @@
32
+ sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \
33
+ ucontext.h intrinsics.h)
34
+
35
+ +AC_CHECK_HEADER(sys/sdt.h)
36
+ +if test "$ac_cv_header_sys_sdt_h" == "yes"; then
37
+ + AC_DEFINE(HAVE_SDT_H)
38
+ +fi
39
+ +
40
+ dnl Check additional types.
41
+ AC_CHECK_SIZEOF(rlim_t, 0, [
42
+ #ifdef HAVE_SYS_TYPES_H
43
+ @@ -547,6 +552,18 @@
44
+ AC_DEFINE(USE_SETREUID)
45
+ AC_DEFINE(USE_SETREGID)
46
+ fi
47
+ +
48
+ +AC_ARG_ENABLE(dtrace,
49
+ + [ --enable-dtrace enable DTrace support.],
50
+ + [enable_dtrace=$enableval])
51
+ +if test "$enable_dtrace" == "yes" -a "$ac_cv_header_sys_sdt_h" == "yes"; then
52
+ + AC_DEFINE(ENABLE_DTRACE)
53
+ + DTRACE_HEADER="dtrace.h"
54
+ +else
55
+ + DTRACE_HEADER=""
56
+ +fi
57
+ +AC_SUBST(DTRACE_HEADER)
58
+ +
59
+ AC_STRUCT_TIMEZONE
60
+ AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
61
+ [AC_TRY_COMPILE([#include <time.h>],
62
+ Index: inits.c
63
+ ===================================================================
64
+ --- inits.c (revision 16089)
65
+ +++ inits.c (working copy)
66
+ @@ -45,6 +45,7 @@
67
+ void Init_Time _((void));
68
+ void Init_var_tables _((void));
69
+ void Init_version _((void));
70
+ +void Init_Tracer _((void));
71
+
72
+ void
73
+ rb_call_inits()
74
+ @@ -81,4 +82,5 @@
75
+ Init_GC();
76
+ Init_marshal();
77
+ Init_version();
78
+ + Init_Tracer();
79
+ }
80
+ Index: object.c
81
+ ===================================================================
82
+ --- object.c (revision 16089)
83
+ +++ object.c (working copy)
84
+ @@ -19,7 +19,35 @@
85
+ #include <errno.h>
86
+ #include <ctype.h>
87
+ #include <math.h>
88
+ +#ifdef ENABLE_DTRACE
89
+ +#include "dtrace.h"
90
+ +#include "node.h"
91
+ +#endif
92
+
93
+ +#ifdef ENABLE_DTRACE
94
+ +
95
+ +#define FIRE_OBJECT_CREATE_START_PROBE(ruby_current_node, klass) \
96
+ + if (RUBY_OBJECT_CREATE_START_ENABLED()) { \
97
+ + char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file; \
98
+ + int line = ruby_current_node == NULL ? 0 : nd_line(ruby_current_node); \
99
+ + RUBY_OBJECT_CREATE_START(rb_class2name(klass), file, line); \
100
+ + }
101
+ +
102
+ +#define FIRE_OBJECT_CREATE_DONE_PROBE(ruby_current_node, klass) \
103
+ + if (RUBY_OBJECT_CREATE_DONE_ENABLED()) { \
104
+ + char *file = ruby_current_node == NULL ? "" : ruby_current_node->nd_file; \
105
+ + int line = ruby_current_node == NULL ? 0 : nd_line(ruby_current_node); \
106
+ + RUBY_OBJECT_CREATE_DONE(rb_class2name(klass), file, line); \
107
+ + }
108
+ +
109
+ +#else
110
+ +
111
+ +#define FIRE_OBJECT_CREATE_START_PROBE(ruby_current_node, klass) /* NOOP */
112
+ +#define FIRE_OBJECT_CREATE_DONE_PROBE(ruby_current_node, klass) /* NOOP */
113
+ +
114
+ +#endif
115
+ +
116
+ +
117
+ VALUE rb_mKernel;
118
+ VALUE rb_cObject;
119
+ VALUE rb_cModule;
120
+ @@ -1553,7 +1581,9 @@
121
+ if (FL_TEST(klass, FL_SINGLETON)) {
122
+ rb_raise(rb_eTypeError, "can't create instance of virtual class");
123
+ }
124
+ + FIRE_OBJECT_CREATE_START_PROBE(ruby_current_node, klass);
125
+ obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0);
126
+ + FIRE_OBJECT_CREATE_DONE_PROBE(ruby_current_node, klass);
127
+ if (rb_obj_class(obj) != rb_class_real(klass)) {
128
+ rb_raise(rb_eTypeError, "wrong instance allocation");
129
+ }
130
+ Index: tracer.c
131
+ ===================================================================
132
+ --- tracer.c (revision 0)
133
+ +++ tracer.c (revision 0)
134
+ @@ -0,0 +1,62 @@
135
+ +#include "ruby.h"
136
+ +
137
+ +#ifdef ENABLE_DTRACE
138
+ +#include "dtrace.h"
139
+ +#endif
140
+ +
141
+ +VALUE rb_mDtrace;
142
+ +
143
+ +static VALUE
144
+ +ruby_dtrace_fire(argc, argv, klass)
145
+ + int argc;
146
+ + VALUE *argv;
147
+ + VALUE klass;
148
+ +{
149
+ + int args;
150
+ + VALUE name, data, ret;
151
+ + char *probe_data;
152
+ + char *probe_name;
153
+ + char *start_probe;
154
+ + char *end_probe;
155
+ +
156
+ +#ifdef ENABLE_DTRACE
157
+ +
158
+ + args = rb_scan_args(argc, argv, "11", &name, &data);
159
+ + probe_data = args == 2 ? StringValuePtr(data) : "";
160
+ + probe_name = StringValuePtr(name);
161
+ +
162
+ + if (rb_block_given_p()) {
163
+ + start_probe = malloc(strlen(probe_name) + 7);
164
+ + end_probe = malloc(strlen(probe_name) + 5);
165
+ +
166
+ + sprintf(start_probe, "%s-start", probe_name);
167
+ + sprintf(end_probe, "%s-end", probe_name);
168
+ +
169
+ + /* Build -start and -end strings for probe names */
170
+ + if (RUBY_RUBY_PROBE_ENABLED())
171
+ + RUBY_RUBY_PROBE(start_probe, probe_data);
172
+ +#endif
173
+ +
174
+ + ret = rb_yield(Qnil);
175
+ +
176
+ +#if ENABLE_DTRACE
177
+ + if (RUBY_RUBY_PROBE_ENABLED())
178
+ + RUBY_RUBY_PROBE(end_probe, probe_data);
179
+ +
180
+ + free(start_probe);
181
+ + free(end_probe);
182
+ + } else {
183
+ + if (RUBY_RUBY_PROBE_ENABLED())
184
+ + RUBY_RUBY_PROBE(probe_name, probe_data);
185
+ + ret = Qnil;
186
+ + }
187
+ +#endif
188
+ + return ret;
189
+ +}
190
+ +
191
+ +
192
+ +void Init_Tracer()
193
+ +{
194
+ + rb_mDtrace = rb_define_module("Tracer");
195
+ + rb_define_module_function(rb_mDtrace, "fire", ruby_dtrace_fire, -1);
196
+ +}
197
+ Index: dtrace.d
198
+ ===================================================================
199
+ --- dtrace.d (revision 0)
200
+ +++ dtrace.d (revision 0)
201
+ @@ -0,0 +1,26 @@
202
+ +/* -*- Mode: C -*- */
203
+ +
204
+ +provider ruby {
205
+ + probe function__entry(char*, char*, char*, int);
206
+ + probe function__return(char*, char*, char*, int);
207
+ + probe raise(char*, char*, int);
208
+ + probe rescue(char*, int);
209
+ + probe line(char*, int);
210
+ +
211
+ + /* gc probes */
212
+ + probe gc__begin();
213
+ + probe gc__end();
214
+ +
215
+ + /* Some initial memory type probes */
216
+ + probe object__create__start(char*, char*, int);
217
+ + probe object__create__done(char*, char*, int);
218
+ + probe object__free(char*);
219
+ +
220
+ + probe ruby__probe(char*, char*);
221
+ +};
222
+ +
223
+ +#pragma D attributes Evolving/Evolving/Common provider ruby provider
224
+ +#pragma D attributes Private/Private/Common provider ruby module
225
+ +#pragma D attributes Private/Private/Common provider ruby function
226
+ +#pragma D attributes Evolving/Evolving/Common provider ruby name
227
+ +#pragma D attributes Evolving/Evolving/Common provider ruby args
228
+
229
+ Index: common.mk
230
+ ===================================================================
231
+ --- common.mk (revision 16089)
232
+ +++ common.mk (working copy)
233
+ @@ -49,6 +49,7 @@
234
+ string.$(OBJEXT) \
235
+ struct.$(OBJEXT) \
236
+ time.$(OBJEXT) \
237
+ + tracer.$(OBJEXT) \
238
+ util.$(OBJEXT) \
239
+ variable.$(OBJEXT) \
240
+ version.$(OBJEXT) \
241
+ @@ -262,7 +263,7 @@
242
+
243
+ clean: clean-ext clean-local
244
+ clean-local::
245
+ - @$(RM) $(OBJS) $(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)
246
+ + @$(RM) $(OBJS) $(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES) $(DTRACE_HEADER)
247
+ @$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) $(ARCHFILE) .*.time
248
+ clean-ext:
249
+ @-$(MINIRUBY) $(srcdir)/ext/extmk.rb $(EXTMK_ARGS) clean
250
+ @@ -363,7 +364,7 @@
251
+ error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}ruby.h config.h \
252
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
253
+ {$(VPATH)}env.h {$(VPATH)}st.h
254
+ -eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}ruby.h config.h \
255
+ +eval.$(OBJEXT): $(DTRACE_HEADER) {$(VPATH)}eval.c {$(VPATH)}ruby.h config.h \
256
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
257
+ {$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \
258
+ {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h
259
+ @@ -371,7 +372,7 @@
260
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
261
+ {$(VPATH)}rubyio.h {$(VPATH)}rubysig.h {$(VPATH)}util.h \
262
+ {$(VPATH)}dln.h
263
+ -gc.$(OBJEXT): {$(VPATH)}gc.c {$(VPATH)}ruby.h config.h \
264
+ +gc.$(OBJEXT): $(DTRACE_HEADER) {$(VPATH)}gc.c {$(VPATH)}ruby.h config.h \
265
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
266
+ {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}node.h \
267
+ {$(VPATH)}env.h {$(VPATH)}re.h {$(VPATH)}regex.h
268
+ @@ -394,7 +395,7 @@
269
+ numeric.$(OBJEXT): {$(VPATH)}numeric.c {$(VPATH)}ruby.h config.h \
270
+ {$(VPATH)}env.h {$(VPATH)}defines.h {$(VPATH)}intern.h \
271
+ {$(VPATH)}missing.h
272
+ -object.$(OBJEXT): {$(VPATH)}object.c {$(VPATH)}ruby.h config.h \
273
+ +object.$(OBJEXT): $(DTRACE_HEADER) {$(VPATH)}object.c {$(VPATH)}ruby.h config.h \
274
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
275
+ {$(VPATH)}st.h {$(VPATH)}util.h
276
+ pack.$(OBJEXT): {$(VPATH)}pack.c {$(VPATH)}ruby.h config.h \
277
+ Index: eval.c
278
+ ===================================================================
279
+ --- eval.c (revision 16089)
280
+ +++ eval.c (working copy)
281
+ @@ -217,6 +217,9 @@
282
+ #endif
283
+
284
+ #include <sys/stat.h>
285
+ +#ifdef ENABLE_DTRACE
286
+ +#include "dtrace.h"
287
+ +#endif
288
+
289
+ VALUE rb_cProc;
290
+ VALUE rb_cBinding;
291
+ @@ -1138,6 +1141,53 @@
292
+ } \
293
+ } while (0)
294
+
295
+ +#ifdef ENABLE_DTRACE
296
+ +
297
+ +#define FIRE_LINE_PROBE(ruby_current_node) \
298
+ + if (RUBY_LINE_ENABLED()) { \
299
+ + if (ruby_current_node && ruby_current_node->nd_file) { \
300
+ + RUBY_LINE(ruby_current_node->nd_file, nd_line(ruby_current_node)); \
301
+ + } \
302
+ + }
303
+ +
304
+ +#define FIRE_RESCUE_PROBE(ruby_current_node) \
305
+ + if (RUBY_RESCUE_ENABLED()) { \
306
+ + if (ruby_current_node && ruby_current_node->nd_file) { \
307
+ + RUBY_RESCUE(ruby_current_node->nd_file, nd_line(ruby_current_node)); \
308
+ + } \
309
+ + }
310
+ +
311
+ +#define FIRE_RAISE_PROBE(ruby_errinfo, ruby_sourcefile, ruby_sourceline) \
312
+ + if (RUBY_RAISE_ENABLED()) { \
313
+ + RUBY_RAISE(rb_obj_classname(ruby_errinfo), ruby_sourcefile, ruby_sourceline); \
314
+ + }
315
+ +
316
+ +#define FIRE_FUNCTION_ENTRY(ruby_current_node, klass, id) \
317
+ + if (RUBY_FUNCTION_ENTRY_ENABLED()) { \
318
+ + char *classname = rb_class2name(klass), *methodname = rb_id2name(id); \
319
+ + if (ruby_current_node && ruby_current_node->nd_file && classname && methodname) { \
320
+ + RUBY_FUNCTION_ENTRY(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node)); \
321
+ + } \
322
+ + }
323
+ +
324
+ +#define FIRE_FUNCTION_RETURN(ruby_current_node, klass, id) \
325
+ + if (RUBY_FUNCTION_RETURN_ENABLED()) { \
326
+ + char *classname = rb_class2name(klass), *methodname = rb_id2name(id); \
327
+ + if (ruby_current_node && ruby_current_node->nd_file && classname && methodname) { \
328
+ + RUBY_FUNCTION_RETURN(classname, methodname, ruby_current_node->nd_file, nd_line(ruby_current_node)); \
329
+ + } \
330
+ + }
331
+ +
332
+ +#else
333
+ +
334
+ +#define FIRE_LINE_PROBE(ruby_current_node) /* NOOP */
335
+ +#define FIRE_RESCUE_PROBE(ruby_current_node) /* NOOP */
336
+ +#define FIRE_RAISE_PROBE(ruby_errinfo, ruby_sourcefile, ruby_sourceline) /* NOOP */
337
+ +#define FIRE_FUNCTION_ENTRY(ruby_current_node, klass, id) /* NOOP */
338
+ +#define FIRE_FUNCTION_RETURN(ruby_current_node, klass, id) /* NOOP */
339
+ +
340
+ +#endif
341
+ +
342
+ static VALUE trace_func = 0;
343
+ static int tracing = 0;
344
+ static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE));
345
+ @@ -3028,6 +3078,7 @@
346
+ RETURN(Qfalse);
347
+
348
+ case NODE_IF:
349
+ + FIRE_LINE_PROBE(ruby_current_node);
350
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
351
+ ruby_frame->last_func,
352
+ ruby_frame->last_class);
353
+ @@ -3046,6 +3097,7 @@
354
+ if (nd_type(node) != NODE_WHEN) goto again;
355
+ tag = node->nd_head;
356
+ while (tag) {
357
+ + FIRE_LINE_PROBE(ruby_current_node);
358
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
359
+ ruby_frame->last_func,
360
+ ruby_frame->last_class);
361
+ @@ -3087,6 +3139,7 @@
362
+ }
363
+ tag = node->nd_head;
364
+ while (tag) {
365
+ + FIRE_LINE_PROBE(ruby_current_node);
366
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
367
+ ruby_frame->last_func,
368
+ ruby_frame->last_class);
369
+ @@ -3307,6 +3360,7 @@
370
+ rescuing = -1;
371
+ while (resq) {
372
+ ruby_current_node = resq;
373
+ + FIRE_RESCUE_PROBE(ruby_current_node);
374
+ if (handle_rescue(self, resq)) {
375
+ state = 0;
376
+ rescuing = 1;
377
+ @@ -4124,6 +4178,7 @@
378
+ break;
379
+
380
+ case NODE_NEWLINE:
381
+ + FIRE_LINE_PROBE(ruby_current_node);
382
+ EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
383
+ ruby_frame->last_func,
384
+ ruby_frame->last_class);
385
+ @@ -4598,6 +4653,7 @@
386
+
387
+ rb_trap_restore_mask();
388
+ if (tag != TAG_FATAL) {
389
+ + FIRE_RAISE_PROBE(ruby_errinfo, ruby_sourcefile, ruby_sourceline);
390
+ EXEC_EVENT_HOOK(RUBY_EVENT_RAISE, ruby_current_node,
391
+ ruby_frame->self,
392
+ ruby_frame->last_func,
393
+ @@ -5828,6 +5884,7 @@
394
+ rb_bug("bad argc (%d) specified for `%s(%s)'",
395
+ len, rb_class2name(klass), rb_id2name(id));
396
+ }
397
+ + FIRE_FUNCTION_ENTRY(ruby_current_node, klass, id);
398
+ if (event_hooks) {
399
+ int state;
400
+
401
+ @@ -5846,6 +5903,7 @@
402
+ else {
403
+ result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
404
+ }
405
+ + FIRE_FUNCTION_RETURN(ruby_current_node, klass, id);
406
+ }
407
+ break;
408
+
409
+ @@ -5873,12 +5931,14 @@
410
+
411
+ case NODE_BMETHOD:
412
+ ruby_frame->flags |= FRAME_DMETH;
413
+ + FIRE_FUNCTION_ENTRY(ruby_current_node, klass, id);
414
+ if (event_hooks) {
415
+ struct BLOCK *data;
416
+ Data_Get_Struct(body->nd_cval, struct BLOCK, data);
417
+ EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
418
+ }
419
+ result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
420
+ + FIRE_FUNCTION_RETURN(ruby_current_node, klass, id);
421
+ if (event_hooks) {
422
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
423
+ }
424
+ @@ -5992,6 +6052,7 @@
425
+ }
426
+ ruby_frame->argc = i;
427
+ }
428
+ + FIRE_FUNCTION_ENTRY(ruby_current_node, klass, id);
429
+ if (event_hooks) {
430
+ EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);
431
+ }
432
+ @@ -6002,6 +6063,7 @@
433
+ state = 0;
434
+ }
435
+ POP_TAG();
436
+ + FIRE_FUNCTION_RETURN(ruby_current_node, klass, id);
437
+ if (event_hooks) {
438
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
439
+ }
440
+ Index: gc.c
441
+ ===================================================================
442
+ --- gc.c (revision 16089)
443
+ +++ gc.c (working copy)
444
+ @@ -30,6 +30,11 @@
445
+ #include <sys/resource.h>
446
+ #endif
447
+
448
+ +#ifdef ENABLE_DTRACE
449
+ +#include <sys/sdt.h>
450
+ +#include "dtrace.h"
451
+ +#endif
452
+ +
453
+ #if defined _WIN32 || defined __CYGWIN__
454
+ #include <windows.h>
455
+ #endif
456
+ @@ -68,6 +73,31 @@
457
+ #endif
458
+ #endif
459
+
460
+ +#ifdef ENABLE_DTRACE
461
+ +
462
+ +#define FIRE_OBJECT_FREE_PROBE(obj) \
463
+ + if (RUBY_OBJECT_FREE_ENABLED()) { \
464
+ + RUBY_OBJECT_FREE(rb_class2name(CLASS_OF(obj))); \
465
+ + } \
466
+ +
467
+ +#define FIRE_GC_BEGIN_PROBE() \
468
+ + if (RUBY_GC_BEGIN_ENABLED()) { \
469
+ + RUBY_GC_BEGIN(); \
470
+ + }
471
+ +
472
+ +#define FIRE_GC_END_PROBE() \
473
+ + if (RUBY_GC_END_ENABLED()) { \
474
+ + RUBY_GC_END(); \
475
+ + }
476
+ +
477
+ +#else
478
+ +
479
+ +#define FIRE_OBJECT_FREE_PROBE(obj) /* NOOP */
480
+ +#define FIRE_GC_BEGIN_PROBE() /* NOOP */
481
+ +#define FIRE_GC_END_PROBE() /* NOOP */
482
+ +
483
+ +#endif
484
+ +
485
+ static unsigned long malloc_increase = 0;
486
+ static unsigned long malloc_limit = GC_MALLOC_LIMIT;
487
+ static void run_final();
488
+ @@ -1159,6 +1189,7 @@
489
+ break;
490
+ }
491
+
492
+ + FIRE_OBJECT_FREE_PROBE(obj);
493
+ if (FL_TEST(obj, FL_EXIVAR)) {
494
+ rb_free_generic_ivar((VALUE)obj);
495
+ }
496
+ @@ -1322,6 +1353,7 @@
497
+ {
498
+ struct gc_list *list;
499
+ struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
500
+ + FIRE_GC_BEGIN_PROBE();
501
+ jmp_buf save_regs_gc_mark;
502
+ SET_STACK_END;
503
+
504
+ @@ -1414,6 +1446,7 @@
505
+ } while (!MARK_STACK_EMPTY);
506
+
507
+ gc_sweep();
508
+ + FIRE_GC_END_PROBE();
509
+ }
510
+
511
+ void