ruby-prof 0.11.2-x86-mingw32 → 0.12.1-x86-mingw32
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.
- data/CHANGES +27 -0
- data/README.rdoc +15 -15
- data/Rakefile +5 -0
- data/bin/ruby-prof +274 -265
- data/ext/ruby_prof/rp_call_info.c +33 -24
- data/ext/ruby_prof/rp_call_info.h +2 -1
- data/ext/ruby_prof/rp_measure.c +1 -1
- data/ext/ruby_prof/rp_measure.h +1 -1
- data/ext/ruby_prof/rp_measure_allocations.c +1 -1
- data/ext/ruby_prof/rp_measure_cpu_time.c +1 -1
- data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
- data/ext/ruby_prof/rp_measure_gc_time.c +1 -1
- data/ext/ruby_prof/rp_measure_memory.c +1 -1
- data/ext/ruby_prof/rp_measure_process_time.c +2 -2
- data/ext/ruby_prof/rp_measure_wall_time.c +2 -2
- data/ext/ruby_prof/rp_method.c +11 -24
- data/ext/ruby_prof/rp_method.h +2 -3
- data/ext/ruby_prof/rp_stack.c +55 -14
- data/ext/ruby_prof/rp_stack.h +10 -10
- data/ext/ruby_prof/rp_thread.c +30 -21
- data/ext/ruby_prof/rp_thread.h +3 -3
- data/ext/ruby_prof/ruby_prof.c +9 -88
- data/ext/ruby_prof/ruby_prof.h +1 -1
- data/ext/ruby_prof/vc/ruby_prof.sln +12 -6
- data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +2 -0
- data/ext/ruby_prof/vc/{ruby_prof.vcxproj → ruby_prof_19.vcxproj} +4 -1
- data/ext/ruby_prof/vc/ruby_prof_20.vcxproj +112 -0
- data/ext/ruby_prof/version.h +4 -4
- data/lib/1.8/ruby_prof.so +0 -0
- data/lib/1.9/ruby_prof.so +0 -0
- data/lib/2.0/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +1 -0
- data/lib/ruby-prof/call_info.rb +1 -1
- data/lib/ruby-prof/call_info_visitor.rb +4 -2
- data/lib/ruby-prof/compatibility.rb +13 -3
- data/lib/ruby-prof/method_info.rb +1 -1
- data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
- data/lib/ruby-prof/printers/call_stack_printer.rb +3 -3
- data/lib/ruby-prof/printers/dot_printer.rb +2 -2
- data/lib/ruby-prof/printers/flat_printer.rb +4 -4
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +2 -2
- data/lib/ruby-prof/printers/graph_html_printer.rb +3 -4
- data/lib/ruby-prof/printers/graph_printer.rb +15 -15
- data/lib/ruby-prof/profile.rb +1 -1
- data/lib/ruby-prof/rack.rb +0 -5
- data/lib/ruby-prof/thread.rb +22 -0
- data/ruby-prof.gemspec +2 -1
- data/test/basic_test.rb +77 -45
- data/test/call_info_test.rb +78 -0
- data/test/call_info_visitor_test.rb +1 -1
- data/test/dynamic_method_test.rb +14 -8
- data/test/measure_cpu_time_test.rb +23 -12
- data/test/measure_process_time_test.rb +21 -170
- data/test/measure_wall_time_test.rb +59 -13
- data/test/method_elimination_test.rb +30 -19
- data/test/pause_resume_test.rb +129 -22
- data/test/prime.rb +1 -2
- data/test/printers_test.rb +8 -17
- data/test/recursive_test.rb +6 -50
- data/test/test_helper.rb +30 -10
- data/test/test_suite.rb +1 -2
- metadata +23 -7
- data/test/bug_test.rb +0 -6
- data/test/gc_test.rb +0 -35
- data/test/pause_test.rb +0 -57
- data/test/prime_test.rb +0 -13
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "ruby_prof.h"
|
@@ -10,7 +10,6 @@ VALUE cCallInfo;
|
|
10
10
|
|
11
11
|
// Forward declarations
|
12
12
|
st_table * call_info_table_create();
|
13
|
-
void call_info_table_free(st_table *table);
|
14
13
|
|
15
14
|
|
16
15
|
/* ======= prof_call_info_t ========*/
|
@@ -31,9 +30,8 @@ prof_call_info_create(prof_method_t* method, prof_call_info_t* parent)
|
|
31
30
|
result->line = 0;
|
32
31
|
return result;
|
33
32
|
}
|
34
|
-
|
35
33
|
static void
|
36
|
-
|
34
|
+
prof_call_info_ruby_gc_free(prof_call_info_t *call_info)
|
37
35
|
{
|
38
36
|
/* Has this thread object been accessed by Ruby? If
|
39
37
|
yes clean it up so to avoid a segmentation fault. */
|
@@ -44,8 +42,13 @@ prof_call_info_free(prof_call_info_t *call_info)
|
|
44
42
|
RDATA(call_info->object)->dmark = NULL;
|
45
43
|
}
|
46
44
|
call_info->object = Qnil;
|
45
|
+
}
|
47
46
|
|
48
|
-
|
47
|
+
static void
|
48
|
+
prof_call_info_free(prof_call_info_t *call_info)
|
49
|
+
{
|
50
|
+
prof_call_info_ruby_gc_free(call_info);
|
51
|
+
xfree(call_info->call_infos);
|
49
52
|
xfree(call_info);
|
50
53
|
}
|
51
54
|
|
@@ -53,10 +56,13 @@ static void
|
|
53
56
|
prof_call_info_mark(prof_call_info_t *call_info)
|
54
57
|
{
|
55
58
|
if (call_info->object)
|
56
|
-
rb_gc_mark(call_info->
|
59
|
+
rb_gc_mark(call_info->object);
|
57
60
|
|
58
61
|
if (call_info->children)
|
59
62
|
rb_gc_mark(call_info->children);
|
63
|
+
|
64
|
+
/* We don't mark the call info child table since that will be done
|
65
|
+
via the appropriate method */
|
60
66
|
}
|
61
67
|
|
62
68
|
VALUE
|
@@ -64,7 +70,7 @@ prof_call_info_wrap(prof_call_info_t *call_info)
|
|
64
70
|
{
|
65
71
|
if (call_info->object == Qnil)
|
66
72
|
{
|
67
|
-
call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark,
|
73
|
+
call_info->object = Data_Wrap_Struct(cCallInfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
|
68
74
|
}
|
69
75
|
return call_info->object;
|
70
76
|
}
|
@@ -89,20 +95,6 @@ call_info_table_create()
|
|
89
95
|
return st_init_table(&type_method_hash);
|
90
96
|
}
|
91
97
|
|
92
|
-
/*static int
|
93
|
-
call_info_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
|
94
|
-
{
|
95
|
-
prof_call_info_free((prof_call_info_t*)value);
|
96
|
-
return ST_CONTINUE;
|
97
|
-
}*/
|
98
|
-
|
99
|
-
void
|
100
|
-
call_info_table_free(st_table *table)
|
101
|
-
{
|
102
|
-
//st_foreach(table, call_info_table_free_iterator, 0);
|
103
|
-
st_free_table(table);
|
104
|
-
}
|
105
|
-
|
106
98
|
size_t
|
107
99
|
call_info_table_insert(st_table *table, const prof_method_key_t *key, prof_call_info_t *val)
|
108
100
|
{
|
@@ -337,11 +329,29 @@ prof_call_infos_create()
|
|
337
329
|
return result;
|
338
330
|
}
|
339
331
|
|
332
|
+
void
|
333
|
+
prof_call_infos_mark(prof_call_infos_t *call_infos)
|
334
|
+
{
|
335
|
+
prof_call_info_t **call_info;
|
336
|
+
|
337
|
+
if (call_infos->object)
|
338
|
+
rb_gc_mark(call_infos->object);
|
339
|
+
|
340
|
+
for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
|
341
|
+
{
|
342
|
+
prof_call_info_mark(*call_info);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
340
346
|
void
|
341
347
|
prof_call_infos_free(prof_call_infos_t *call_infos)
|
342
348
|
{
|
343
|
-
|
344
|
-
|
349
|
+
prof_call_info_t **call_info;
|
350
|
+
|
351
|
+
for(call_info=call_infos->start; call_info<call_infos->ptr; call_info++)
|
352
|
+
{
|
353
|
+
prof_call_info_free(*call_info);
|
354
|
+
}
|
345
355
|
}
|
346
356
|
|
347
357
|
void
|
@@ -375,7 +385,6 @@ prof_call_infos_wrap(prof_call_infos_t *call_infos)
|
|
375
385
|
return call_infos->object;
|
376
386
|
}
|
377
387
|
|
378
|
-
|
379
388
|
void rp_init_call_info()
|
380
389
|
{
|
381
390
|
/* CallInfo */
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#ifndef __RP_CALL_INFO_H__
|
@@ -37,6 +37,7 @@ typedef struct prof_call_infos_t
|
|
37
37
|
|
38
38
|
void rp_init_call_info(void);
|
39
39
|
prof_call_infos_t* prof_call_infos_create();
|
40
|
+
void prof_call_infos_mark(prof_call_infos_t *call_infos);
|
40
41
|
void prof_call_infos_free(prof_call_infos_t *call_infos);
|
41
42
|
void prof_add_call_info(prof_call_infos_t *call_infos, prof_call_info_t *call_info);
|
42
43
|
VALUE prof_call_infos_wrap(prof_call_infos_t *call_infos);
|
data/ext/ruby_prof/rp_measure.c
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "ruby_prof.h"
|
data/ext/ruby_prof/rp_measure.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#ifndef __RP_MEASUREMENT_H__
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
/* :nodoc: */
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "ruby_prof.h"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
/* :nodoc: */
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
/* :nodoc: */
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
/* :nodoc: */
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "ruby_prof.h"
|
@@ -12,7 +12,7 @@ measure_process_time()
|
|
12
12
|
#if defined(__linux__)
|
13
13
|
struct timespec clock;
|
14
14
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID , &clock);
|
15
|
-
return
|
15
|
+
return clock.tv_sec + (clock.tv_nsec/1000000000.0);
|
16
16
|
#elif defined(_win32)
|
17
17
|
FILETIME createTime;
|
18
18
|
FILETIME exitTime;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
/* :nodoc: */
|
@@ -11,7 +11,7 @@ measure_wall_time()
|
|
11
11
|
{
|
12
12
|
struct timeval tv;
|
13
13
|
gettimeofday(&tv, NULL);
|
14
|
-
return
|
14
|
+
return tv.tv_sec + (tv.tv_usec/1000000.0);
|
15
15
|
}
|
16
16
|
|
17
17
|
prof_measurer_t* prof_measurer_wall_time()
|
data/ext/ruby_prof/rp_method.c
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "ruby_prof.h"
|
@@ -98,10 +98,12 @@ method_name(ID mid)
|
|
98
98
|
{
|
99
99
|
VALUE result;
|
100
100
|
|
101
|
-
if (mid ==
|
102
|
-
result = rb_str_new2("allocate");
|
103
|
-
else if (mid == 0)
|
101
|
+
if (mid == 0)
|
104
102
|
result = rb_str_new2("[No method]");
|
103
|
+
#ifdef ID_ALLOCATOR
|
104
|
+
else if (mid == ID_ALLOCATOR)
|
105
|
+
result = rb_str_new2("allocate");
|
106
|
+
#endif
|
105
107
|
else
|
106
108
|
result = rb_String(ID2SYM(mid));
|
107
109
|
|
@@ -139,7 +141,6 @@ prof_method_create(VALUE klass, ID mid, const char* source_file, int line)
|
|
139
141
|
prof_method_t *result = ALLOC(prof_method_t);
|
140
142
|
result->object = Qnil;
|
141
143
|
result->call_infos = prof_call_infos_create();
|
142
|
-
result->call_infos2 = Qnil;
|
143
144
|
|
144
145
|
result->key = ALLOC(prof_method_key_t);
|
145
146
|
method_key(result->key, klass, mid);
|
@@ -188,6 +189,7 @@ prof_method_free(prof_method_t* method)
|
|
188
189
|
{
|
189
190
|
prof_method_ruby_gc_free(method);
|
190
191
|
prof_call_infos_free(method->call_infos);
|
192
|
+
xfree(method->call_infos);
|
191
193
|
|
192
194
|
xfree(method->key);
|
193
195
|
method->key = NULL;
|
@@ -195,28 +197,13 @@ prof_method_free(prof_method_t* method)
|
|
195
197
|
xfree(method);
|
196
198
|
}
|
197
199
|
|
198
|
-
/*static int
|
199
|
-
mark_call_infos(st_data_t key, st_data_t value, st_data_t result)
|
200
|
-
{
|
201
|
-
prof_call_info_t *call_info = (prof_call_info_t *) value;
|
202
|
-
prof_call_info_mark(call_info);
|
203
|
-
return ST_CONTINUE;
|
204
|
-
}
|
205
|
-
*/
|
206
|
-
|
207
200
|
void
|
208
201
|
prof_method_mark(prof_method_t *method)
|
209
202
|
{
|
210
203
|
if (method->object)
|
211
204
|
rb_gc_mark(method->object);
|
212
205
|
|
213
|
-
|
214
|
-
rb_gc_mark(method->call_infos2);
|
215
|
-
|
216
|
-
if (method->call_infos->object)
|
217
|
-
rb_gc_mark(method->call_infos->object);
|
218
|
-
|
219
|
-
//st_foreach(method->call_info_table, mark_call_infos, NULL);
|
206
|
+
prof_call_infos_mark(method->call_infos);
|
220
207
|
}
|
221
208
|
|
222
209
|
VALUE
|
@@ -409,11 +396,11 @@ static VALUE
|
|
409
396
|
prof_method_call_infos(VALUE self)
|
410
397
|
{
|
411
398
|
prof_method_t *method = get_prof_method(self);
|
412
|
-
if (method->
|
399
|
+
if (method->call_infos->object == Qnil)
|
413
400
|
{
|
414
|
-
method->
|
401
|
+
method->call_infos->object = prof_call_infos_wrap(method->call_infos);
|
415
402
|
}
|
416
|
-
return method->
|
403
|
+
return method->call_infos->object;
|
417
404
|
}
|
418
405
|
|
419
406
|
void rp_init_method_info()
|
data/ext/ruby_prof/rp_method.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#ifndef __RP_METHOD_INFO__
|
@@ -31,9 +31,8 @@ typedef struct
|
|
31
31
|
prof_method_key_t *key; /* Method key */
|
32
32
|
const char *source_file; /* The method's source file */
|
33
33
|
int line; /* The method's line number. */
|
34
|
-
struct prof_call_infos_t *call_infos;
|
34
|
+
struct prof_call_infos_t *call_infos; /* Call info objects for this method */
|
35
35
|
VALUE object; /* Cached ruby object */
|
36
|
-
VALUE call_infos2; /* Cached array of RubyProf::CallInfo */
|
37
36
|
} prof_method_t;
|
38
37
|
|
39
38
|
void rp_init_method_info(void);
|
data/ext/ruby_prof/rp_stack.c
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#include "rp_stack.h"
|
@@ -6,16 +6,16 @@
|
|
6
6
|
#define INITIAL_STACK_SIZE 8
|
7
7
|
|
8
8
|
void
|
9
|
-
|
9
|
+
prof_frame_pause(prof_frame_t *frame, double current_measurement)
|
10
10
|
{
|
11
|
-
if (frame &&
|
11
|
+
if (frame && prof_frame_is_unpaused(frame))
|
12
12
|
frame->pause_time = current_measurement;
|
13
13
|
}
|
14
14
|
|
15
15
|
void
|
16
|
-
|
16
|
+
prof_frame_unpause(prof_frame_t *frame, double current_measurement)
|
17
17
|
{
|
18
|
-
if (frame &&
|
18
|
+
if (frame && prof_frame_is_paused(frame)) {
|
19
19
|
frame->dead_time += (current_measurement - frame->pause_time);
|
20
20
|
frame->pause_time = -1;
|
21
21
|
}
|
@@ -25,7 +25,7 @@ frame_unpause(prof_frame_t *frame, double current_measurement)
|
|
25
25
|
/* Creates a stack of prof_frame_t to keep track
|
26
26
|
of timings for active methods. */
|
27
27
|
prof_stack_t *
|
28
|
-
|
28
|
+
prof_stack_create()
|
29
29
|
{
|
30
30
|
prof_stack_t *stack = ALLOC(prof_stack_t);
|
31
31
|
stack->start = ALLOC_N(prof_frame_t, INITIAL_STACK_SIZE);
|
@@ -36,14 +36,14 @@ stack_create()
|
|
36
36
|
}
|
37
37
|
|
38
38
|
void
|
39
|
-
|
39
|
+
prof_stack_free(prof_stack_t *stack)
|
40
40
|
{
|
41
41
|
xfree(stack->start);
|
42
42
|
xfree(stack);
|
43
43
|
}
|
44
44
|
|
45
45
|
prof_frame_t *
|
46
|
-
|
46
|
+
prof_stack_push(prof_stack_t *stack, double measurement)
|
47
47
|
{
|
48
48
|
prof_frame_t* result = NULL;
|
49
49
|
|
@@ -64,7 +64,9 @@ stack_push(prof_stack_t *stack)
|
|
64
64
|
result->child_time = 0;
|
65
65
|
result->switch_time = 0;
|
66
66
|
result->wait_time = 0;
|
67
|
+
result->dead_time = 0;
|
67
68
|
result->depth = (int)(stack->ptr - stack->start); // shortening of 64 bit into 32
|
69
|
+
result->start_time = measurement;
|
68
70
|
|
69
71
|
// Increment the stack ptr for next time
|
70
72
|
stack->ptr++;
|
@@ -74,16 +76,55 @@ stack_push(prof_stack_t *stack)
|
|
74
76
|
}
|
75
77
|
|
76
78
|
prof_frame_t *
|
77
|
-
|
79
|
+
prof_stack_pop(prof_stack_t *stack, double measurement)
|
78
80
|
{
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
prof_frame_t *frame = NULL;
|
82
|
+
prof_frame_t* parent_frame = NULL;
|
83
|
+
prof_call_info_t *call_info;
|
84
|
+
|
85
|
+
double total_time;
|
86
|
+
double self_time;
|
87
|
+
#ifdef _MSC_VER
|
88
|
+
BOOL frame_paused;
|
89
|
+
#else
|
90
|
+
_Bool frame_paused;
|
91
|
+
#endif
|
92
|
+
|
93
|
+
/* Frame can be null. This can happen if RubProf.start is called from
|
94
|
+
a method that exits. And it can happen if an exception is raised
|
95
|
+
in code that is being profiled and the stack unwinds (RubyProf is
|
96
|
+
not notified of that by the ruby runtime. */
|
97
|
+
if (stack->ptr == stack->start)
|
98
|
+
return NULL;
|
99
|
+
|
100
|
+
frame = --stack->ptr;
|
101
|
+
|
102
|
+
/* Calculate the total time this method took */
|
103
|
+
prof_frame_unpause(frame, measurement);
|
104
|
+
total_time = measurement - frame->start_time - frame->dead_time;
|
105
|
+
self_time = total_time - frame->child_time - frame->wait_time;
|
106
|
+
|
107
|
+
/* Update information about the current method */
|
108
|
+
call_info = frame->call_info;
|
109
|
+
call_info->called++;
|
110
|
+
call_info->total_time += total_time;
|
111
|
+
call_info->self_time += self_time;
|
112
|
+
call_info->wait_time += frame->wait_time;
|
113
|
+
|
114
|
+
parent_frame = prof_stack_peek(stack);
|
115
|
+
if (parent_frame)
|
116
|
+
{
|
117
|
+
parent_frame->child_time += total_time;
|
118
|
+
parent_frame->dead_time += frame->dead_time;
|
119
|
+
|
120
|
+
call_info->line = parent_frame->line;
|
121
|
+
}
|
122
|
+
|
123
|
+
return frame;
|
83
124
|
}
|
84
125
|
|
85
126
|
prof_frame_t *
|
86
|
-
|
127
|
+
prof_stack_peek(prof_stack_t *stack)
|
87
128
|
{
|
88
129
|
if (stack->ptr == stack->start)
|
89
130
|
return NULL;
|
data/ext/ruby_prof/rp_stack.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Copyright (C) 2005-
|
1
|
+
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
2
|
Please see the LICENSE file for copyright and distribution information */
|
3
3
|
|
4
4
|
#ifndef __RP_STACK__
|
@@ -28,10 +28,10 @@ typedef struct
|
|
28
28
|
unsigned int line;
|
29
29
|
} prof_frame_t;
|
30
30
|
|
31
|
-
#define
|
32
|
-
#define
|
33
|
-
void
|
34
|
-
void
|
31
|
+
#define prof_frame_is_paused(f) (f->pause_time >= 0)
|
32
|
+
#define prof_frame_is_unpaused(f) (f->pause_time < 0)
|
33
|
+
void prof_frame_pause(prof_frame_t*, double current_measurement);
|
34
|
+
void prof_frame_unpause(prof_frame_t*, double current_measurement);
|
35
35
|
|
36
36
|
|
37
37
|
/* Current stack of active methods.*/
|
@@ -42,10 +42,10 @@ typedef struct
|
|
42
42
|
prof_frame_t *ptr;
|
43
43
|
} prof_stack_t;
|
44
44
|
|
45
|
-
prof_stack_t *
|
46
|
-
void
|
47
|
-
prof_frame_t *
|
48
|
-
prof_frame_t *
|
49
|
-
prof_frame_t *
|
45
|
+
prof_stack_t * prof_stack_create();
|
46
|
+
void prof_stack_free(prof_stack_t *stack);
|
47
|
+
prof_frame_t * prof_stack_push(prof_stack_t *stack, double measurement);
|
48
|
+
prof_frame_t * prof_stack_pop(prof_stack_t *stack, double measurement);
|
49
|
+
prof_frame_t * prof_stack_peek(prof_stack_t *stack);
|
50
50
|
|
51
51
|
#endif //__RP_STACK__
|