ruby-prof 0.11.3 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|