ruby-prof 1.5.0-x64-mingw-ucrt → 1.6.1-x64-mingw-ucrt
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +13 -0
- data/ext/ruby_prof/rp_allocation.c +136 -81
- data/ext/ruby_prof/rp_allocation.h +8 -6
- data/ext/ruby_prof/rp_call_tree.c +8 -1
- data/ext/ruby_prof/rp_measurement.c +10 -3
- data/ext/ruby_prof/rp_method.c +51 -76
- data/ext/ruby_prof/rp_profile.c +62 -77
- data/ext/ruby_prof/rp_profile.h +1 -0
- data/ext/ruby_prof/rp_thread.c +14 -4
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +1 -1
- data/lib/3.1/ruby_prof.so +0 -0
- data/lib/3.2/ruby_prof.so +0 -0
- data/lib/ruby-prof/compatibility.rb +14 -0
- data/lib/ruby-prof/printers/abstract_printer.rb +1 -1
- data/lib/ruby-prof/printers/call_tree_printer.rb +1 -1
- data/lib/ruby-prof/printers/multi_printer.rb +17 -17
- data/lib/ruby-prof/profile.rb +5 -5
- data/lib/ruby-prof/rack.rb +31 -21
- data/lib/ruby-prof/version.rb +1 -1
- data/test/abstract_printer_test.rb +1 -0
- data/test/alias_test.rb +6 -11
- data/test/call_tree_visitor_test.rb +1 -6
- data/test/call_trees_test.rb +2 -2
- data/test/{basic_test.rb → compatibility_test.rb} +8 -2
- data/test/duplicate_names_test.rb +1 -1
- data/test/dynamic_method_test.rb +1 -6
- data/test/enumerable_test.rb +1 -1
- data/test/exceptions_test.rb +2 -2
- data/test/exclude_methods_test.rb +3 -8
- data/test/exclude_threads_test.rb +4 -9
- data/test/fiber_test.rb +4 -9
- data/test/gc_test.rb +2 -1
- data/test/inverse_call_tree_test.rb +33 -34
- data/test/line_number_test.rb +1 -1
- data/test/marshal_test.rb +3 -3
- data/test/measure_allocations_test.rb +8 -17
- data/test/measure_memory_test.rb +3 -12
- data/test/measure_process_time_test.rb +29 -34
- data/test/measure_wall_time_test.rb +176 -181
- data/test/multi_printer_test.rb +0 -5
- data/test/no_method_class_test.rb +1 -1
- data/test/pause_resume_test.rb +12 -16
- data/test/printer_call_stack_test.rb +2 -2
- data/test/printer_call_tree_test.rb +2 -2
- data/test/printer_flat_test.rb +1 -1
- data/test/printer_graph_html_test.rb +2 -2
- data/test/printer_graph_test.rb +2 -2
- data/test/printers_test.rb +14 -20
- data/test/printing_recursive_graph_test.rb +2 -2
- data/test/recursive_test.rb +2 -7
- data/test/singleton_test.rb +1 -1
- data/test/stack_printer_test.rb +5 -8
- data/test/start_stop_test.rb +11 -14
- data/test/thread_test.rb +13 -15
- data/test/unique_call_path_test.rb +4 -4
- data/test/yarv_test.rb +3 -3
- metadata +4 -4
data/ext/ruby_prof/rp_profile.c
CHANGED
@@ -103,17 +103,15 @@ static int excludes_method(st_data_t key, prof_profile_t* profile)
|
|
103
103
|
method_table_lookup(profile->exclude_methods_tbl, key) != NULL);
|
104
104
|
}
|
105
105
|
|
106
|
-
static prof_method_t* create_method(
|
106
|
+
static prof_method_t* create_method(prof_profile_t* profile, st_data_t key, VALUE klass, VALUE msym, VALUE source_file, int source_line)
|
107
107
|
{
|
108
|
-
prof_method_t* result = prof_method_create(profile, klass, msym, source_file, source_line);
|
109
|
-
|
110
|
-
prof_profile_t* profile_t = prof_get_profile(profile);
|
111
|
-
method_table_insert(profile_t->last_thread_data->method_table, result->key, result);
|
108
|
+
prof_method_t* result = prof_method_create(profile->object, klass, msym, source_file, source_line);
|
109
|
+
method_table_insert(profile->last_thread_data->method_table, result->key, result);
|
112
110
|
|
113
111
|
return result;
|
114
112
|
}
|
115
113
|
|
116
|
-
static prof_method_t* check_parent_method(
|
114
|
+
static prof_method_t* check_parent_method(prof_profile_t* profile, thread_data_t* thread_data)
|
117
115
|
{
|
118
116
|
VALUE msym = ID2SYM(rb_intern("_inserted_parent_"));
|
119
117
|
st_data_t key = method_key(cProfile, msym);
|
@@ -128,7 +126,7 @@ static prof_method_t* check_parent_method(VALUE profile, thread_data_t* thread_d
|
|
128
126
|
return result;
|
129
127
|
}
|
130
128
|
|
131
|
-
prof_method_t* check_method(
|
129
|
+
prof_method_t* check_method(prof_profile_t* profile, rb_trace_arg_t* trace_arg, rb_event_flag_t event, thread_data_t* thread_data)
|
132
130
|
{
|
133
131
|
VALUE klass = rb_tracearg_defined_class(trace_arg);
|
134
132
|
|
@@ -142,8 +140,7 @@ prof_method_t* check_method(VALUE profile, rb_trace_arg_t* trace_arg, rb_event_f
|
|
142
140
|
|
143
141
|
st_data_t key = method_key(klass, msym);
|
144
142
|
|
145
|
-
|
146
|
-
if (excludes_method(key, profile_t))
|
143
|
+
if (excludes_method(key, profile))
|
147
144
|
return NULL;
|
148
145
|
|
149
146
|
prof_method_t* result = method_table_lookup(thread_data->method_table, key);
|
@@ -197,17 +194,16 @@ static void prof_trace(prof_profile_t* profile, rb_trace_arg_t* trace_arg, doubl
|
|
197
194
|
|
198
195
|
static void prof_event_hook(VALUE trace_point, void* data)
|
199
196
|
{
|
200
|
-
|
201
|
-
prof_profile_t* profile_t = prof_get_profile(profile);
|
197
|
+
prof_profile_t* profile = (prof_profile_t*)(data);
|
202
198
|
|
203
199
|
rb_trace_arg_t* trace_arg = rb_tracearg_from_tracepoint(trace_point);
|
204
|
-
double measurement = prof_measure(
|
200
|
+
double measurement = prof_measure(profile->measurer, trace_arg);
|
205
201
|
rb_event_flag_t event = rb_tracearg_event_flag(trace_arg);
|
206
202
|
VALUE self = rb_tracearg_self(trace_arg);
|
207
203
|
|
208
204
|
if (trace_file != NULL)
|
209
205
|
{
|
210
|
-
prof_trace(
|
206
|
+
prof_trace(profile, trace_arg, measurement);
|
211
207
|
}
|
212
208
|
|
213
209
|
/* Special case - skip any methods from the mProf
|
@@ -215,7 +211,7 @@ static void prof_event_hook(VALUE trace_point, void* data)
|
|
215
211
|
if (self == mProf)
|
216
212
|
return;
|
217
213
|
|
218
|
-
thread_data_t* thread_data = check_fiber(
|
214
|
+
thread_data_t* thread_data = check_fiber(profile, measurement);
|
219
215
|
|
220
216
|
if (!thread_data->trace)
|
221
217
|
return;
|
@@ -247,7 +243,7 @@ static void prof_event_hook(VALUE trace_point, void* data)
|
|
247
243
|
// This is the first method to be profiled
|
248
244
|
else
|
249
245
|
{
|
250
|
-
frame = prof_frame_push(thread_data->stack, call_tree, measurement, RTEST(
|
246
|
+
frame = prof_frame_push(thread_data->stack, call_tree, measurement, RTEST(profile->paused));
|
251
247
|
}
|
252
248
|
|
253
249
|
thread_data->call_tree = call_tree;
|
@@ -301,7 +297,7 @@ static void prof_event_hook(VALUE trace_point, void* data)
|
|
301
297
|
thread_data->call_tree = call_tree;
|
302
298
|
|
303
299
|
// Push a new frame onto the stack for a new c-call or ruby call (into a method)
|
304
|
-
prof_frame_t* next_frame = prof_frame_push(thread_data->stack, call_tree, measurement, RTEST(
|
300
|
+
prof_frame_t* next_frame = prof_frame_push(thread_data->stack, call_tree, measurement, RTEST(profile->paused));
|
305
301
|
next_frame->source_file = method->source_file;
|
306
302
|
next_frame->source_line = method->source_line;
|
307
303
|
break;
|
@@ -327,7 +323,7 @@ static void prof_event_hook(VALUE trace_point, void* data)
|
|
327
323
|
|
328
324
|
prof_method_t* method = prof_find_method(thread_data->stack, source_file, source_line);
|
329
325
|
if (method)
|
330
|
-
prof_allocate_increment(method, trace_arg);
|
326
|
+
prof_allocate_increment(method->allocations_table, trace_arg);
|
331
327
|
|
332
328
|
break;
|
333
329
|
}
|
@@ -342,12 +338,12 @@ void prof_install_hook(VALUE self)
|
|
342
338
|
RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
|
343
339
|
RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN |
|
344
340
|
RUBY_EVENT_LINE,
|
345
|
-
prof_event_hook,
|
341
|
+
prof_event_hook, profile);
|
346
342
|
rb_ary_push(profile->tracepoints, event_tracepoint);
|
347
343
|
|
348
344
|
if (profile->measurer->track_allocations)
|
349
345
|
{
|
350
|
-
VALUE allocation_tracepoint = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ, prof_event_hook,
|
346
|
+
VALUE allocation_tracepoint = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ, prof_event_hook, profile);
|
351
347
|
rb_ary_push(profile->tracepoints, allocation_tracepoint);
|
352
348
|
}
|
353
349
|
|
@@ -404,9 +400,10 @@ static int prof_profile_mark_methods(st_data_t key, st_data_t value, st_data_t r
|
|
404
400
|
static void prof_profile_mark(void* data)
|
405
401
|
{
|
406
402
|
prof_profile_t* profile = (prof_profile_t*)data;
|
407
|
-
|
408
|
-
|
409
|
-
|
403
|
+
rb_gc_mark_movable(profile->object);
|
404
|
+
rb_gc_mark_movable(profile->tracepoints);
|
405
|
+
rb_gc_mark_movable(profile->running);
|
406
|
+
rb_gc_mark_movable(profile->paused);
|
410
407
|
|
411
408
|
// If GC stress is true (useful for debugging), when threads_table_create is called in the
|
412
409
|
// allocate method Ruby will immediately call this mark method. Thus the threads_tbl will be NULL.
|
@@ -417,6 +414,15 @@ static void prof_profile_mark(void* data)
|
|
417
414
|
rb_st_foreach(profile->exclude_methods_tbl, prof_profile_mark_methods, 0);
|
418
415
|
}
|
419
416
|
|
417
|
+
void prof_profile_compact(void* data)
|
418
|
+
{
|
419
|
+
prof_profile_t* profile = (prof_profile_t*)data;
|
420
|
+
profile->object = rb_gc_location(profile->object);
|
421
|
+
profile->tracepoints = rb_gc_location(profile->tracepoints);
|
422
|
+
profile->running = rb_gc_location(profile->running);
|
423
|
+
profile->paused = rb_gc_location(profile->paused);
|
424
|
+
}
|
425
|
+
|
420
426
|
/* Freeing the profile creates a cascade of freeing. It frees its threads table, which frees
|
421
427
|
each thread and its associated call treee and methods. */
|
422
428
|
static void prof_profile_ruby_gc_free(void* data)
|
@@ -462,6 +468,7 @@ static const rb_data_type_t profile_type =
|
|
462
468
|
.dmark = prof_profile_mark,
|
463
469
|
.dfree = prof_profile_ruby_gc_free,
|
464
470
|
.dsize = prof_profile_size,
|
471
|
+
.dcompact = prof_profile_compact
|
465
472
|
},
|
466
473
|
.data = NULL,
|
467
474
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
@@ -472,6 +479,7 @@ static VALUE prof_allocate(VALUE klass)
|
|
472
479
|
VALUE result;
|
473
480
|
prof_profile_t* profile;
|
474
481
|
result = TypedData_Make_Struct(klass, prof_profile_t, &profile_type, profile);
|
482
|
+
profile->object = result;
|
475
483
|
profile->threads_tbl = threads_table_create();
|
476
484
|
profile->exclude_threads_tbl = NULL;
|
477
485
|
profile->include_threads_tbl = NULL;
|
@@ -510,9 +518,9 @@ prof_stop_threads(prof_profile_t* profile)
|
|
510
518
|
|
511
519
|
/* call-seq:
|
512
520
|
new()
|
513
|
-
new(
|
521
|
+
new(keyword_args)
|
514
522
|
|
515
|
-
Returns a new profiler. Possible
|
523
|
+
Returns a new profiler. Possible keyword arguments include:
|
516
524
|
|
517
525
|
measure_mode: Measure mode. Specifies the profile measure mode.
|
518
526
|
If not specified, defaults to RubyProf::WALL_TIME.
|
@@ -525,78 +533,55 @@ prof_stop_threads(prof_profile_t* profile)
|
|
525
533
|
all other threads. */
|
526
534
|
static VALUE prof_initialize(int argc, VALUE* argv, VALUE self)
|
527
535
|
{
|
536
|
+
VALUE keywords;
|
537
|
+
rb_scan_args_kw(RB_SCAN_ARGS_KEYWORDS, argc, argv, ":", &keywords);
|
538
|
+
|
539
|
+
ID table[] = {rb_intern("measure_mode"),
|
540
|
+
rb_intern("track_allocations"),
|
541
|
+
rb_intern("allow_exceptions"),
|
542
|
+
rb_intern("exclude_common"),
|
543
|
+
rb_intern("exclude_threads"),
|
544
|
+
rb_intern("include_threads") };
|
545
|
+
VALUE values[6];
|
546
|
+
rb_get_kwargs(keywords, table, 0, 6, values);
|
547
|
+
|
548
|
+
VALUE mode = values[0] == Qundef ? INT2NUM(MEASURE_WALL_TIME) : values[0];
|
549
|
+
VALUE track_allocations = values[1] == Qtrue ? Qtrue : Qfalse;
|
550
|
+
VALUE allow_exceptions = values[2] == Qtrue ? Qtrue : Qfalse;
|
551
|
+
VALUE exclude_common = values[3] == Qtrue ? Qtrue : Qfalse;
|
552
|
+
VALUE exclude_threads = values[4];
|
553
|
+
VALUE include_threads = values[5];
|
554
|
+
|
555
|
+
Check_Type(mode, T_FIXNUM);
|
528
556
|
prof_profile_t* profile = prof_get_profile(self);
|
529
|
-
|
530
|
-
|
531
|
-
VALUE exclude_threads = Qnil;
|
532
|
-
VALUE include_threads = Qnil;
|
533
|
-
VALUE exclude_common = Qnil;
|
534
|
-
VALUE allow_exceptions = Qfalse;
|
535
|
-
VALUE track_allocations = Qfalse;
|
536
|
-
|
537
|
-
int i;
|
538
|
-
|
539
|
-
switch (rb_scan_args(argc, argv, "02", &mode_or_options, &exclude_threads))
|
540
|
-
{
|
541
|
-
case 0:
|
542
|
-
break;
|
543
|
-
case 1:
|
544
|
-
if (FIXNUM_P(mode_or_options))
|
545
|
-
{
|
546
|
-
mode = mode_or_options;
|
547
|
-
}
|
548
|
-
else
|
549
|
-
{
|
550
|
-
Check_Type(mode_or_options, T_HASH);
|
551
|
-
mode = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("measure_mode")));
|
552
|
-
track_allocations = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("track_allocations")));
|
553
|
-
allow_exceptions = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("allow_exceptions")));
|
554
|
-
exclude_common = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("exclude_common")));
|
555
|
-
exclude_threads = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("exclude_threads")));
|
556
|
-
include_threads = rb_hash_aref(mode_or_options, ID2SYM(rb_intern("include_threads")));
|
557
|
-
}
|
558
|
-
break;
|
559
|
-
case 2:
|
560
|
-
Check_Type(exclude_threads, T_ARRAY);
|
561
|
-
break;
|
562
|
-
}
|
563
|
-
|
564
|
-
if (mode == Qnil)
|
565
|
-
{
|
566
|
-
mode = INT2NUM(MEASURE_WALL_TIME);
|
567
|
-
}
|
568
|
-
else
|
569
|
-
{
|
570
|
-
Check_Type(mode, T_FIXNUM);
|
571
|
-
}
|
572
|
-
profile->measurer = prof_measurer_create(NUM2INT(mode), track_allocations == Qtrue);
|
573
|
-
profile->allow_exceptions = (allow_exceptions == Qtrue);
|
557
|
+
profile->measurer = prof_measurer_create(NUM2INT(mode), RB_TEST(track_allocations));
|
558
|
+
profile->allow_exceptions = RB_TEST(allow_exceptions);
|
574
559
|
|
575
|
-
if (exclude_threads !=
|
560
|
+
if (exclude_threads != Qundef)
|
576
561
|
{
|
577
562
|
Check_Type(exclude_threads, T_ARRAY);
|
578
563
|
assert(profile->exclude_threads_tbl == NULL);
|
579
564
|
profile->exclude_threads_tbl = threads_table_create();
|
580
|
-
for (i = 0; i < RARRAY_LEN(exclude_threads); i++)
|
565
|
+
for (int i = 0; i < RARRAY_LEN(exclude_threads); i++)
|
581
566
|
{
|
582
567
|
VALUE thread = rb_ary_entry(exclude_threads, i);
|
583
568
|
rb_st_insert(profile->exclude_threads_tbl, thread, Qtrue);
|
584
569
|
}
|
585
570
|
}
|
586
571
|
|
587
|
-
if (include_threads !=
|
572
|
+
if (include_threads != Qundef)
|
588
573
|
{
|
589
574
|
Check_Type(include_threads, T_ARRAY);
|
590
575
|
assert(profile->include_threads_tbl == NULL);
|
591
576
|
profile->include_threads_tbl = threads_table_create();
|
592
|
-
for (i = 0; i < RARRAY_LEN(include_threads); i++)
|
577
|
+
for (int i = 0; i < RARRAY_LEN(include_threads); i++)
|
593
578
|
{
|
594
579
|
VALUE thread = rb_ary_entry(include_threads, i);
|
595
580
|
rb_st_insert(profile->include_threads_tbl, thread, Qtrue);
|
596
581
|
}
|
597
582
|
}
|
598
583
|
|
599
|
-
if (
|
584
|
+
if (RB_TEST(exclude_common))
|
600
585
|
{
|
601
586
|
prof_exclude_common_methods(self);
|
602
587
|
}
|
@@ -820,7 +805,7 @@ static VALUE prof_remove_thread(VALUE self, VALUE thread)
|
|
820
805
|
..
|
821
806
|
end
|
822
807
|
*/
|
823
|
-
static VALUE
|
808
|
+
static VALUE prof_profile_instance(VALUE self)
|
824
809
|
{
|
825
810
|
int result;
|
826
811
|
prof_profile_t* profile = prof_get_profile(self);
|
@@ -856,7 +841,7 @@ static VALUE prof_profile_object(VALUE self)
|
|
856
841
|
*/
|
857
842
|
static VALUE prof_profile_class(int argc, VALUE* argv, VALUE klass)
|
858
843
|
{
|
859
|
-
return
|
844
|
+
return prof_profile_instance(rb_class_new_instance(argc, argv, cProfile));
|
860
845
|
}
|
861
846
|
|
862
847
|
/* call-seq:
|
@@ -927,7 +912,7 @@ void rp_init_profile(void)
|
|
927
912
|
|
928
913
|
rb_define_singleton_method(cProfile, "profile", prof_profile_class, -1);
|
929
914
|
rb_define_method(cProfile, "initialize", prof_initialize, -1);
|
930
|
-
rb_define_method(cProfile, "profile",
|
915
|
+
rb_define_method(cProfile, "profile", prof_profile_instance, 0);
|
931
916
|
rb_define_method(cProfile, "start", prof_start, 0);
|
932
917
|
rb_define_method(cProfile, "stop", prof_stop, 0);
|
933
918
|
rb_define_method(cProfile, "resume", prof_resume, 0);
|
data/ext/ruby_prof/rp_profile.h
CHANGED
data/ext/ruby_prof/rp_thread.c
CHANGED
@@ -58,18 +58,18 @@ void prof_thread_mark(void* data)
|
|
58
58
|
thread_data_t* thread = (thread_data_t*)data;
|
59
59
|
|
60
60
|
if (thread->object != Qnil)
|
61
|
-
|
61
|
+
rb_gc_mark_movable(thread->object);
|
62
62
|
|
63
63
|
rb_gc_mark(thread->fiber);
|
64
64
|
|
65
65
|
if (thread->methods != Qnil)
|
66
|
-
|
66
|
+
rb_gc_mark_movable(thread->methods);
|
67
67
|
|
68
68
|
if (thread->fiber_id != Qnil)
|
69
|
-
|
69
|
+
rb_gc_mark_movable(thread->fiber_id);
|
70
70
|
|
71
71
|
if (thread->thread_id != Qnil)
|
72
|
-
|
72
|
+
rb_gc_mark_movable(thread->thread_id);
|
73
73
|
|
74
74
|
if (thread->call_tree)
|
75
75
|
prof_call_tree_mark(thread->call_tree);
|
@@ -77,6 +77,15 @@ void prof_thread_mark(void* data)
|
|
77
77
|
rb_st_foreach(thread->method_table, mark_methods, 0);
|
78
78
|
}
|
79
79
|
|
80
|
+
void prof_thread_compact(void* data)
|
81
|
+
{
|
82
|
+
thread_data_t* thread = (thread_data_t*)data;
|
83
|
+
thread->object = rb_gc_location(thread->object);
|
84
|
+
thread->methods = rb_gc_location(thread->methods);
|
85
|
+
thread->fiber_id = rb_gc_location(thread->fiber_id);
|
86
|
+
thread->thread_id = rb_gc_location(thread->thread_id);
|
87
|
+
}
|
88
|
+
|
80
89
|
static void prof_thread_free(thread_data_t* thread_data)
|
81
90
|
{
|
82
91
|
/* Has this method object been accessed by Ruby? If
|
@@ -126,6 +135,7 @@ static const rb_data_type_t thread_type =
|
|
126
135
|
.dmark = prof_thread_mark,
|
127
136
|
.dfree = prof_thread_ruby_gc_free,
|
128
137
|
.dsize = prof_thread_size,
|
138
|
+
.dcompact = prof_thread_compact
|
129
139
|
},
|
130
140
|
.data = NULL,
|
131
141
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
@@ -66,7 +66,7 @@
|
|
66
66
|
</PropertyGroup>
|
67
67
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
68
68
|
<TargetExt>.so</TargetExt>
|
69
|
-
<OutDir>$(SolutionDir)
|
69
|
+
<OutDir>$(SolutionDir)\..</OutDir>
|
70
70
|
</PropertyGroup>
|
71
71
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
72
72
|
<ClCompile>
|
data/lib/3.1/ruby_prof.so
CHANGED
Binary file
|
data/lib/3.2/ruby_prof.so
CHANGED
Binary file
|
@@ -96,4 +96,18 @@ module RubyProf
|
|
96
96
|
def self.ensure_not_running!
|
97
97
|
raise(RuntimeError, "RubyProf is already running") if running?
|
98
98
|
end
|
99
|
+
|
100
|
+
class << self
|
101
|
+
extend Gem::Deprecate
|
102
|
+
deprecate :measure_mode, "Profile#measure_mode", 2023, 6
|
103
|
+
deprecate :measure_mode=, "Profile#measure_mode=", 2023, 6
|
104
|
+
deprecate :exclude_threads, "Profile#exclude_threads", 2023, 6
|
105
|
+
deprecate :exclude_threads=, "Profile#initialize", 2023, 6
|
106
|
+
deprecate :start, "Profile#start", 2023, 6
|
107
|
+
deprecate :pause, "Profile#pause", 2023, 6
|
108
|
+
deprecate :stop, "Profile#stop", 2023, 6
|
109
|
+
deprecate :resume, "Profile#resume", 2023, 6
|
110
|
+
deprecate :running?, "Profile#running?", 2023, 6
|
111
|
+
deprecate :profile, "Profile.profile", 2023, 6
|
112
|
+
end
|
99
113
|
end
|
@@ -50,7 +50,7 @@ module RubyProf
|
|
50
50
|
# options - Hash of print options. Note that each printer can
|
51
51
|
# define its own set of options.
|
52
52
|
#
|
53
|
-
# :min_percent - Number 0 to 100 that
|
53
|
+
# :min_percent - Number 0 to 100 that specifies the minimum
|
54
54
|
# %self (the methods self time divided by the
|
55
55
|
# overall total time) that a method must take
|
56
56
|
# for it to be printed out in the report.
|
@@ -27,7 +27,7 @@ module RubyProf
|
|
27
27
|
|
28
28
|
def determine_event_specification_and_value_scale
|
29
29
|
@event_specification = "events: "
|
30
|
-
case
|
30
|
+
case @result.measure_mode
|
31
31
|
when RubyProf::PROCESS_TIME
|
32
32
|
@value_scale = RubyProf::CLOCKS_PER_SEC
|
33
33
|
@event_specification << 'process_time'
|
@@ -6,16 +6,16 @@ module RubyProf
|
|
6
6
|
# profile, a call stack profile and a graph profile.
|
7
7
|
class MultiPrinter
|
8
8
|
def initialize(result, printers = [:flat, :graph_html])
|
9
|
-
@flat_printer = FlatPrinter.new(result)
|
9
|
+
@flat_printer = printers.include?(:flat) ? FlatPrinter.new(result) : nil
|
10
10
|
|
11
|
-
@graph_printer = GraphPrinter.new(result)
|
12
|
-
@graph_html_printer = GraphHtmlPrinter.new(result)
|
11
|
+
@graph_printer = printers.include?(:graph) ? GraphPrinter.new(result) : nil
|
12
|
+
@graph_html_printer = printers.include?(:graph_html) ? GraphHtmlPrinter.new(result) : nil
|
13
13
|
|
14
|
-
@tree_printer = CallTreePrinter.new(result)
|
15
|
-
@call_info_printer = CallInfoPrinter.new(result)
|
14
|
+
@tree_printer = printers.include?(:tree) ? CallTreePrinter.new(result) : nil
|
15
|
+
@call_info_printer = printers.include?(:call_tree) ? CallInfoPrinter.new(result) : nil
|
16
16
|
|
17
|
-
@stack_printer = CallStackPrinter.new(result)
|
18
|
-
@dot_printer = DotPrinter.new(result)
|
17
|
+
@stack_printer = printers.include?(:stack) ? CallStackPrinter.new(result) : nil
|
18
|
+
@dot_printer = printers.include?(:dot) ? DotPrinter.new(result) : nil
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.needs_dir?
|
@@ -28,7 +28,7 @@ module RubyProf
|
|
28
28
|
def print(options)
|
29
29
|
validate_print_params(options)
|
30
30
|
|
31
|
-
@
|
31
|
+
@file_name = options.delete(:profile) || "profile"
|
32
32
|
@directory = options.delete(:path) || File.expand_path(".")
|
33
33
|
|
34
34
|
print_to_flat(options) if @flat_printer
|
@@ -44,36 +44,36 @@ module RubyProf
|
|
44
44
|
|
45
45
|
# the name of the flat profile file
|
46
46
|
def flat_report
|
47
|
-
"#{@directory}/#{@
|
47
|
+
"#{@directory}/#{@file_name}.flat.txt"
|
48
48
|
end
|
49
49
|
|
50
50
|
# the name of the graph profile file
|
51
51
|
def graph_report
|
52
|
-
"#{@directory}/#{@
|
52
|
+
"#{@directory}/#{@file_name}.graph.txt"
|
53
53
|
end
|
54
54
|
|
55
55
|
def graph_html_report
|
56
|
-
"#{@directory}/#{@
|
56
|
+
"#{@directory}/#{@file_name}.graph.html"
|
57
57
|
end
|
58
58
|
|
59
59
|
# the name of the callinfo profile file
|
60
60
|
def call_info_report
|
61
|
-
"#{@directory}/#{@
|
61
|
+
"#{@directory}/#{@file_name}.call_tree.txt"
|
62
62
|
end
|
63
63
|
|
64
64
|
# the name of the callgrind profile file
|
65
65
|
def tree_report
|
66
|
-
"#{@directory}/#{@
|
66
|
+
"#{@directory}/#{@file_name}.callgrind.out.#{$$}"
|
67
67
|
end
|
68
68
|
|
69
69
|
# the name of the call stack profile file
|
70
70
|
def stack_report
|
71
|
-
"#{@directory}/#{@
|
71
|
+
"#{@directory}/#{@file_name}.stack.html"
|
72
72
|
end
|
73
73
|
|
74
74
|
# the name of the call stack profile file
|
75
75
|
def dot_report
|
76
|
-
"#{@directory}/#{@
|
76
|
+
"#{@directory}/#{@file_name}.dot"
|
77
77
|
end
|
78
78
|
|
79
79
|
def print_to_flat(options)
|
@@ -101,12 +101,12 @@ module RubyProf
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def print_to_tree(options)
|
104
|
-
@tree_printer.print(options.merge(:path => @directory, :profile => @
|
104
|
+
@tree_printer.print(options.merge(:path => @directory, :profile => @file_name))
|
105
105
|
end
|
106
106
|
|
107
107
|
def print_to_stack(options)
|
108
108
|
File.open(stack_report, "wb") do |file|
|
109
|
-
@stack_printer.print(file, options.merge(:graph => "#{@
|
109
|
+
@stack_printer.print(file, options.merge(:graph => "#{@file_name}.graph.html"))
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
data/lib/ruby-prof/profile.rb
CHANGED
@@ -23,14 +23,14 @@ module RubyProf
|
|
23
23
|
ExcludeCommonMethods.apply!(self)
|
24
24
|
end
|
25
25
|
|
26
|
-
def exclude_methods!(mod, *
|
27
|
-
[
|
28
|
-
exclude_method!(mod,
|
26
|
+
def exclude_methods!(mod, *method_names)
|
27
|
+
[method_names].flatten.each do |method_name|
|
28
|
+
exclude_method!(mod, method_name)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def exclude_singleton_methods!(mod, *
|
33
|
-
exclude_methods!(mod.singleton_class, *
|
32
|
+
def exclude_singleton_methods!(mod, *method_names)
|
33
|
+
exclude_methods!(mod.singleton_class, *method_names)
|
34
34
|
end
|
35
35
|
|
36
36
|
# call-seq:
|
data/lib/ruby-prof/rack.rb
CHANGED
@@ -6,7 +6,6 @@ module Rack
|
|
6
6
|
def initialize(app, options = {})
|
7
7
|
@app = app
|
8
8
|
@options = options
|
9
|
-
@options[:min_percent] ||= 1
|
10
9
|
|
11
10
|
@tmpdir = options[:path] || Dir.tmpdir
|
12
11
|
FileUtils.mkdir_p(@tmpdir)
|
@@ -26,14 +25,19 @@ module Rack
|
|
26
25
|
if should_profile?(request.path)
|
27
26
|
begin
|
28
27
|
result = nil
|
29
|
-
|
28
|
+
profile = ::RubyProf::Profile.profile(profiling_options) do
|
30
29
|
result = @app.call(env)
|
31
30
|
end
|
32
31
|
|
32
|
+
if @options[:merge_fibers]
|
33
|
+
profile.merge!
|
34
|
+
end
|
35
|
+
|
36
|
+
|
33
37
|
path = request.path.gsub('/', '-')
|
34
38
|
path.slice!(0)
|
35
39
|
|
36
|
-
print(
|
40
|
+
print(profile, path)
|
37
41
|
result
|
38
42
|
end
|
39
43
|
else
|
@@ -54,39 +58,45 @@ module Rack
|
|
54
58
|
end
|
55
59
|
|
56
60
|
def profiling_options
|
57
|
-
|
58
|
-
|
59
|
-
options[:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
if @options[:request_thread_only]
|
66
|
-
options[:include_threads] = [Thread.current]
|
61
|
+
result = {}
|
62
|
+
result[:measure_mode] = @options[:measure_mode] || ::RubyProf::WALL_TIME
|
63
|
+
result[:track_allocations] = @options[:track_allocations] || false
|
64
|
+
result[:exclude_common] = @options[:exclude_common] || false
|
65
|
+
|
66
|
+
if @options[:ignore_existing_threads]
|
67
|
+
result[:exclude_threads] = Thread.list.select {|thread| thread != Thread.current}
|
67
68
|
end
|
68
|
-
|
69
|
-
|
69
|
+
|
70
|
+
if @options[:request_thread_only]
|
71
|
+
result[:include_threads] = [Thread.current]
|
70
72
|
end
|
71
|
-
|
73
|
+
|
74
|
+
result
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_options
|
78
|
+
result = {}
|
79
|
+
result[:min_percent] = @options[:min_percent] || 1
|
80
|
+
result[:sort_method] = @options[:sort_method] || :total_time
|
81
|
+
result
|
72
82
|
end
|
73
83
|
|
74
|
-
def print(
|
84
|
+
def print(profile, path)
|
75
85
|
@printer_klasses.each do |printer_klass, base_name|
|
76
|
-
printer = printer_klass.new(
|
86
|
+
printer = printer_klass.new(profile)
|
77
87
|
|
78
88
|
if base_name.respond_to?(:call)
|
79
89
|
base_name = base_name.call
|
80
90
|
end
|
81
91
|
|
82
92
|
if printer_klass == ::RubyProf::MultiPrinter
|
83
|
-
printer.print(
|
93
|
+
printer.print(print_options.merge(:profile => "#{path}-#{base_name}"))
|
84
94
|
elsif printer_klass == ::RubyProf::CallTreePrinter
|
85
|
-
printer.print(
|
95
|
+
printer.print(print_options.merge(:profile => "#{path}-#{base_name}"))
|
86
96
|
else
|
87
97
|
file_name = ::File.join(@tmpdir, "#{path}-#{base_name}")
|
88
98
|
::File.open(file_name, 'wb') do |file|
|
89
|
-
printer.print(file,
|
99
|
+
printer.print(file, print_options)
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
data/lib/ruby-prof/version.rb
CHANGED