ruby-prof 0.11.3 → 0.12.1
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 +14 -14
- data/bin/ruby-prof +275 -266
- 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 +48 -7
- data/ext/ruby_prof/rp_stack.h +3 -3
- data/ext/ruby_prof/rp_thread.c +26 -17
- data/ext/ruby_prof/rp_thread.h +3 -3
- data/ext/ruby_prof/ruby_prof.c +7 -86
- 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 +110 -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/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 +6 -1
- 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 +1 -1
- 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 -3
- data/lib/ruby-prof/printers/graph_printer.rb +15 -15
- 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 +0 -1
- data/test/printers_test.rb +7 -18
- data/test/recursive_test.rb +4 -48
- data/test/test_helper.rb +30 -10
- data/test/test_suite.rb +1 -2
- metadata +23 -5
- 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"
|
@@ -43,7 +43,7 @@ prof_stack_free(prof_stack_t *stack)
|
|
43
43
|
}
|
44
44
|
|
45
45
|
prof_frame_t *
|
46
|
-
prof_stack_push(prof_stack_t *stack)
|
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 @@ prof_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,12 +76,51 @@ prof_stack_push(prof_stack_t *stack)
|
|
74
76
|
}
|
75
77
|
|
76
78
|
prof_frame_t *
|
77
|
-
prof_stack_pop(prof_stack_t *stack)
|
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 *
|
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__
|
@@ -44,8 +44,8 @@ typedef struct
|
|
44
44
|
|
45
45
|
prof_stack_t * prof_stack_create();
|
46
46
|
void prof_stack_free(prof_stack_t *stack);
|
47
|
-
prof_frame_t * prof_stack_push(prof_stack_t *stack);
|
48
|
-
prof_frame_t * prof_stack_pop(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
49
|
prof_frame_t * prof_stack_peek(prof_stack_t *stack);
|
50
50
|
|
51
51
|
#endif //__RP_STACK__
|
data/ext/ruby_prof/rp_thread.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"
|
@@ -12,7 +12,6 @@ thread_data_create()
|
|
12
12
|
thread_data_t* result = ALLOC(thread_data_t);
|
13
13
|
result->stack = prof_stack_create();
|
14
14
|
result->method_table = method_table_create();
|
15
|
-
result->top = NULL;
|
16
15
|
result->object = Qnil;
|
17
16
|
result->methods = Qnil;
|
18
17
|
return result;
|
@@ -42,7 +41,6 @@ static void
|
|
42
41
|
thread_data_free(thread_data_t* thread_data)
|
43
42
|
{
|
44
43
|
thread_data_ruby_gc_free(thread_data);
|
45
|
-
thread_data->top = NULL;
|
46
44
|
method_table_free(thread_data->method_table);
|
47
45
|
prof_stack_free(thread_data->stack);
|
48
46
|
|
@@ -68,7 +66,9 @@ prof_thread_mark(thread_data_t *thread)
|
|
68
66
|
if (thread->methods != Qnil)
|
69
67
|
rb_gc_mark(thread->methods);
|
70
68
|
|
71
|
-
|
69
|
+
if (thread->thread_id != Qnil)
|
70
|
+
rb_gc_mark(thread->thread_id);
|
71
|
+
|
72
72
|
st_foreach(thread->method_table, mark_methods, 0);
|
73
73
|
}
|
74
74
|
|
@@ -179,6 +179,28 @@ switch_thread(void* prof, VALUE thread_id)
|
|
179
179
|
return thread_data;
|
180
180
|
}
|
181
181
|
|
182
|
+
int pause_thread(st_data_t key, st_data_t value, st_data_t data)
|
183
|
+
{
|
184
|
+
thread_data_t* thread_data = (thread_data_t *) value;
|
185
|
+
prof_profile_t* profile = (prof_profile_t*)data;
|
186
|
+
|
187
|
+
prof_frame_t* frame = prof_stack_peek(thread_data->stack);
|
188
|
+
prof_frame_pause(frame, profile->measurement_at_pause_resume);
|
189
|
+
|
190
|
+
return ST_CONTINUE;
|
191
|
+
}
|
192
|
+
|
193
|
+
int unpause_thread(st_data_t key, st_data_t value, st_data_t data)
|
194
|
+
{
|
195
|
+
thread_data_t* thread_data = (thread_data_t *) value;
|
196
|
+
prof_profile_t* profile = (prof_profile_t*)data;
|
197
|
+
|
198
|
+
prof_frame_t* frame = prof_stack_peek(thread_data->stack);
|
199
|
+
prof_frame_unpause(frame, profile->measurement_at_pause_resume);
|
200
|
+
|
201
|
+
return ST_CONTINUE;
|
202
|
+
}
|
203
|
+
|
182
204
|
static int
|
183
205
|
collect_methods(st_data_t key, st_data_t value, st_data_t result)
|
184
206
|
{
|
@@ -220,18 +242,6 @@ prof_thread_methods(VALUE self)
|
|
220
242
|
return thread->methods;
|
221
243
|
}
|
222
244
|
|
223
|
-
/* call-seq:
|
224
|
-
method -> MethodInfo
|
225
|
-
|
226
|
-
Returns the top level method for this thread (ie, the starting
|
227
|
-
method). */
|
228
|
-
static VALUE
|
229
|
-
prof_thread_top_method(VALUE self)
|
230
|
-
{
|
231
|
-
thread_data_t* thread = prof_get_thread(self);
|
232
|
-
return prof_method_wrap(thread->top);
|
233
|
-
}
|
234
|
-
|
235
245
|
void rp_init_thread()
|
236
246
|
{
|
237
247
|
cRpThread = rb_define_class_under(mProf, "Thread", rb_cObject);
|
@@ -239,5 +249,4 @@ void rp_init_thread()
|
|
239
249
|
|
240
250
|
rb_define_method(cRpThread, "id", prof_thread_id, 0);
|
241
251
|
rb_define_method(cRpThread, "methods", prof_thread_methods, 0);
|
242
|
-
rb_define_method(cRpThread, "top_method", prof_thread_top_method, 0);
|
243
252
|
}
|