ruby-prof 0.13.1 → 1.4.2

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.
Files changed (209) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +579 -371
  3. data/LICENSE +24 -23
  4. data/README.rdoc +5 -433
  5. data/Rakefile +98 -110
  6. data/bin/ruby-prof +328 -329
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +16 -59
  9. data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
  10. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  11. data/ext/ruby_prof/rp_allocation.c +287 -0
  12. data/ext/ruby_prof/rp_allocation.h +31 -0
  13. data/ext/ruby_prof/rp_call_tree.c +369 -0
  14. data/ext/ruby_prof/rp_call_tree.h +43 -0
  15. data/ext/ruby_prof/rp_call_trees.c +288 -0
  16. data/ext/ruby_prof/rp_call_trees.h +28 -0
  17. data/ext/ruby_prof/rp_measure_allocations.c +50 -65
  18. data/ext/ruby_prof/rp_measure_memory.c +42 -73
  19. data/ext/ruby_prof/rp_measure_process_time.c +65 -71
  20. data/ext/ruby_prof/rp_measure_wall_time.c +64 -42
  21. data/ext/ruby_prof/rp_measurement.c +237 -0
  22. data/ext/ruby_prof/rp_measurement.h +50 -0
  23. data/ext/ruby_prof/rp_method.c +491 -420
  24. data/ext/ruby_prof/rp_method.h +62 -57
  25. data/ext/ruby_prof/rp_profile.c +908 -0
  26. data/ext/ruby_prof/rp_profile.h +35 -0
  27. data/ext/ruby_prof/rp_stack.c +212 -128
  28. data/ext/ruby_prof/rp_stack.h +53 -51
  29. data/ext/ruby_prof/rp_thread.c +362 -268
  30. data/ext/ruby_prof/rp_thread.h +39 -27
  31. data/ext/ruby_prof/ruby_prof.c +52 -695
  32. data/ext/ruby_prof/ruby_prof.h +26 -55
  33. data/ext/ruby_prof/vc/ruby_prof.sln +28 -21
  34. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +56 -8
  35. data/lib/ruby-prof.rb +52 -67
  36. data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
  37. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  38. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  39. data/lib/ruby-prof/call_tree.rb +57 -0
  40. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  41. data/lib/ruby-prof/compatibility.rb +99 -169
  42. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  43. data/lib/ruby-prof/measurement.rb +17 -0
  44. data/lib/ruby-prof/method_info.rb +78 -131
  45. data/lib/ruby-prof/printers/abstract_printer.rb +137 -85
  46. data/lib/ruby-prof/printers/call_info_printer.rb +53 -41
  47. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -773
  48. data/lib/ruby-prof/printers/call_tree_printer.rb +151 -92
  49. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  50. data/lib/ruby-prof/printers/flat_printer.rb +53 -69
  51. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -255
  52. data/lib/ruby-prof/printers/graph_printer.rb +113 -116
  53. data/lib/ruby-prof/printers/multi_printer.rb +127 -56
  54. data/lib/ruby-prof/profile.rb +37 -77
  55. data/lib/ruby-prof/rack.rb +62 -15
  56. data/lib/ruby-prof/task.rb +147 -147
  57. data/lib/ruby-prof/thread.rb +10 -12
  58. data/lib/ruby-prof/version.rb +3 -0
  59. data/lib/unprof.rb +10 -10
  60. data/ruby-prof.gemspec +65 -61
  61. data/test/abstract_printer_test.rb +26 -0
  62. data/test/alias_test.rb +126 -0
  63. data/test/basic_test.rb +43 -128
  64. data/test/call_tree_visitor_test.rb +32 -0
  65. data/test/call_trees_test.rb +66 -0
  66. data/test/duplicate_names_test.rb +32 -32
  67. data/test/dynamic_method_test.rb +53 -74
  68. data/test/enumerable_test.rb +21 -16
  69. data/test/exceptions_test.rb +24 -16
  70. data/test/exclude_methods_test.rb +151 -0
  71. data/test/exclude_threads_test.rb +53 -54
  72. data/test/fiber_test.rb +129 -65
  73. data/test/gc_test.rb +90 -0
  74. data/test/inverse_call_tree_test.rb +175 -0
  75. data/test/line_number_test.rb +158 -71
  76. data/test/marshal_test.rb +113 -0
  77. data/test/measure_allocations.rb +30 -0
  78. data/test/measure_allocations_test.rb +375 -25
  79. data/test/measure_allocations_trace_test.rb +375 -0
  80. data/test/measure_memory_trace_test.rb +1101 -0
  81. data/test/measure_process_time_test.rb +785 -62
  82. data/test/measure_times.rb +56 -0
  83. data/test/measure_wall_time_test.rb +434 -254
  84. data/test/multi_printer_test.rb +71 -82
  85. data/test/no_method_class_test.rb +15 -15
  86. data/test/pause_resume_test.rb +175 -166
  87. data/test/prime.rb +54 -54
  88. data/test/prime_script.rb +6 -0
  89. data/test/printer_call_stack_test.rb +27 -0
  90. data/test/printer_call_tree_test.rb +30 -0
  91. data/test/printer_flat_test.rb +99 -0
  92. data/test/printer_graph_html_test.rb +59 -0
  93. data/test/printer_graph_test.rb +40 -0
  94. data/test/printers_test.rb +141 -257
  95. data/test/printing_recursive_graph_test.rb +81 -0
  96. data/test/profile_test.rb +16 -0
  97. data/test/rack_test.rb +93 -0
  98. data/test/recursive_test.rb +206 -215
  99. data/test/singleton_test.rb +38 -38
  100. data/test/stack_printer_test.rb +64 -78
  101. data/test/start_stop_test.rb +109 -112
  102. data/test/test_helper.rb +13 -115
  103. data/test/thread_test.rb +144 -178
  104. data/test/unique_call_path_test.rb +120 -224
  105. data/test/yarv_test.rb +56 -0
  106. metadata +77 -133
  107. data/doc/LICENSE.html +0 -155
  108. data/doc/README_rdoc.html +0 -648
  109. data/doc/Rack.html +0 -167
  110. data/doc/Rack/RubyProf.html +0 -319
  111. data/doc/RubyProf.html +0 -1000
  112. data/doc/RubyProf/AbstractPrinter.html +0 -580
  113. data/doc/RubyProf/AggregateCallInfo.html +0 -570
  114. data/doc/RubyProf/CallInfo.html +0 -512
  115. data/doc/RubyProf/CallInfoPrinter.html +0 -190
  116. data/doc/RubyProf/CallInfoVisitor.html +0 -332
  117. data/doc/RubyProf/CallStackPrinter.html +0 -1600
  118. data/doc/RubyProf/CallTreePrinter.html +0 -413
  119. data/doc/RubyProf/Cmd.html +0 -669
  120. data/doc/RubyProf/DotPrinter.html +0 -312
  121. data/doc/RubyProf/FlatPrinter.html +0 -229
  122. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -267
  123. data/doc/RubyProf/GraphHtmlPrinter.html +0 -630
  124. data/doc/RubyProf/GraphPrinter.html +0 -209
  125. data/doc/RubyProf/MethodInfo.html +0 -713
  126. data/doc/RubyProf/MultiPrinter.html +0 -407
  127. data/doc/RubyProf/Profile.html +0 -821
  128. data/doc/RubyProf/ProfileTask.html +0 -532
  129. data/doc/RubyProf/Test.html +0 -578
  130. data/doc/RubyProf/Thread.html +0 -262
  131. data/doc/created.rid +0 -32
  132. data/doc/examples/flat_txt.html +0 -191
  133. data/doc/examples/graph_txt.html +0 -305
  134. data/doc/images/add.png +0 -0
  135. data/doc/images/brick.png +0 -0
  136. data/doc/images/brick_link.png +0 -0
  137. data/doc/images/bug.png +0 -0
  138. data/doc/images/bullet_black.png +0 -0
  139. data/doc/images/bullet_toggle_minus.png +0 -0
  140. data/doc/images/bullet_toggle_plus.png +0 -0
  141. data/doc/images/date.png +0 -0
  142. data/doc/images/delete.png +0 -0
  143. data/doc/images/find.png +0 -0
  144. data/doc/images/loadingAnimation.gif +0 -0
  145. data/doc/images/macFFBgHack.png +0 -0
  146. data/doc/images/package.png +0 -0
  147. data/doc/images/page_green.png +0 -0
  148. data/doc/images/page_white_text.png +0 -0
  149. data/doc/images/page_white_width.png +0 -0
  150. data/doc/images/plugin.png +0 -0
  151. data/doc/images/ruby.png +0 -0
  152. data/doc/images/tag_blue.png +0 -0
  153. data/doc/images/tag_green.png +0 -0
  154. data/doc/images/transparent.png +0 -0
  155. data/doc/images/wrench.png +0 -0
  156. data/doc/images/wrench_orange.png +0 -0
  157. data/doc/images/zoom.png +0 -0
  158. data/doc/index.html +0 -647
  159. data/doc/js/darkfish.js +0 -155
  160. data/doc/js/jquery.js +0 -18
  161. data/doc/js/navigation.js +0 -142
  162. data/doc/js/search.js +0 -94
  163. data/doc/js/search_index.js +0 -1
  164. data/doc/js/searcher.js +0 -228
  165. data/doc/rdoc.css +0 -543
  166. data/doc/table_of_contents.html +0 -462
  167. data/examples/empty.png +0 -0
  168. data/examples/flat.txt +0 -55
  169. data/examples/graph.dot +0 -106
  170. data/examples/graph.html +0 -823
  171. data/examples/graph.png +0 -0
  172. data/examples/graph.txt +0 -170
  173. data/examples/minus.png +0 -0
  174. data/examples/multi.flat.txt +0 -23
  175. data/examples/multi.graph.html +0 -906
  176. data/examples/multi.grind.dat +0 -194
  177. data/examples/multi.stack.html +0 -573
  178. data/examples/plus.png +0 -0
  179. data/examples/stack.html +0 -573
  180. data/ext/ruby_prof/rp_call_info.c +0 -407
  181. data/ext/ruby_prof/rp_call_info.h +0 -48
  182. data/ext/ruby_prof/rp_measure.c +0 -48
  183. data/ext/ruby_prof/rp_measure.h +0 -45
  184. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -112
  185. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -65
  186. data/ext/ruby_prof/rp_measure_gc_time.c +0 -57
  187. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
  188. data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
  189. data/ext/ruby_prof/version.h +0 -7
  190. data/lib/ruby-prof/aggregate_call_info.rb +0 -72
  191. data/lib/ruby-prof/call_info.rb +0 -89
  192. data/lib/ruby-prof/call_info_visitor.rb +0 -44
  193. data/lib/ruby-prof/images/empty.png +0 -0
  194. data/lib/ruby-prof/images/minus.png +0 -0
  195. data/lib/ruby-prof/images/plus.png +0 -0
  196. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -57
  197. data/lib/ruby-prof/test.rb +0 -150
  198. data/test/aggregate_test.rb +0 -136
  199. data/test/call_info_test.rb +0 -78
  200. data/test/call_info_visitor_test.rb +0 -31
  201. data/test/exec_test.rb +0 -14
  202. data/test/measure_cpu_time_test.rb +0 -220
  203. data/test/measure_gc_runs_test.rb +0 -32
  204. data/test/measure_gc_time_test.rb +0 -36
  205. data/test/measure_memory_test.rb +0 -31
  206. data/test/method_elimination_test.rb +0 -84
  207. data/test/module_test.rb +0 -45
  208. data/test/stack_test.rb +0 -138
  209. data/test/test_suite.rb +0 -37
@@ -0,0 +1,35 @@
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #ifndef __RP_PROFILE_H__
5
+ #define __RP_PROFILE_H__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_measurement.h"
9
+ #include "rp_thread.h"
10
+
11
+ extern VALUE cProfile;
12
+
13
+ typedef struct prof_profile_t
14
+ {
15
+ VALUE running;
16
+ VALUE paused;
17
+
18
+ prof_measurer_t* measurer;
19
+
20
+ VALUE tracepoints;
21
+
22
+ st_table* threads_tbl;
23
+ st_table* exclude_threads_tbl;
24
+ st_table* include_threads_tbl;
25
+ st_table* exclude_methods_tbl;
26
+ thread_data_t* last_thread_data;
27
+ double measurement_at_pause_resume;
28
+ bool allow_exceptions;
29
+ } prof_profile_t;
30
+
31
+ void rp_init_profile(void);
32
+ prof_profile_t* prof_get_profile(VALUE self);
33
+
34
+
35
+ #endif //__RP_PROFILE_H__
@@ -1,128 +1,212 @@
1
- /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
- Please see the LICENSE file for copyright and distribution information */
3
-
4
- #include "rp_stack.h"
5
-
6
- #define INITIAL_STACK_SIZE 8
7
-
8
- void
9
- prof_frame_pause(prof_frame_t *frame, double current_measurement)
10
- {
11
- if (frame && prof_frame_is_unpaused(frame))
12
- frame->pause_time = current_measurement;
13
- }
14
-
15
- void
16
- prof_frame_unpause(prof_frame_t *frame, double current_measurement)
17
- {
18
- if (frame && prof_frame_is_paused(frame)) {
19
- frame->dead_time += (current_measurement - frame->pause_time);
20
- frame->pause_time = -1;
21
- }
22
- }
23
-
24
-
25
- /* Creates a stack of prof_frame_t to keep track
26
- of timings for active methods. */
27
- prof_stack_t *
28
- prof_stack_create()
29
- {
30
- prof_stack_t *stack = ALLOC(prof_stack_t);
31
- stack->start = ALLOC_N(prof_frame_t, INITIAL_STACK_SIZE);
32
- stack->ptr = stack->start;
33
- stack->end = stack->start + INITIAL_STACK_SIZE;
34
-
35
- return stack;
36
- }
37
-
38
- void
39
- prof_stack_free(prof_stack_t *stack)
40
- {
41
- xfree(stack->start);
42
- xfree(stack);
43
- }
44
-
45
- prof_frame_t *
46
- prof_stack_push(prof_stack_t *stack, double measurement)
47
- {
48
- prof_frame_t* result = NULL;
49
-
50
- /* Is there space on the stack? If not, double
51
- its size. */
52
- if (stack->ptr == stack->end )
53
- {
54
- size_t len = stack->ptr - stack->start;
55
- size_t new_capacity = (stack->end - stack->start) * 2;
56
- REALLOC_N(stack->start, prof_frame_t, new_capacity);
57
- /* Memory just got moved, reset pointers */
58
- stack->ptr = stack->start + len;
59
- stack->end = stack->start + new_capacity;
60
- }
61
-
62
- // Setup returned stack pointer to be valid
63
- result = stack->ptr;
64
- result->child_time = 0;
65
- result->switch_time = 0;
66
- result->wait_time = 0;
67
- result->dead_time = 0;
68
- result->depth = (int)(stack->ptr - stack->start); // shortening of 64 bit into 32
69
- result->start_time = measurement;
70
-
71
- // Increment the stack ptr for next time
72
- stack->ptr++;
73
-
74
- // Return the result
75
- return result;
76
- }
77
-
78
- prof_frame_t *
79
- prof_stack_pop(prof_stack_t *stack, double measurement)
80
- {
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
-
88
- /* Frame can be null. This can happen if RubProf.start is called from
89
- a method that exits. And it can happen if an exception is raised
90
- in code that is being profiled and the stack unwinds (RubyProf is
91
- not notified of that by the ruby runtime. */
92
- if (stack->ptr == stack->start)
93
- return NULL;
94
-
95
- frame = --stack->ptr;
96
-
97
- /* Calculate the total time this method took */
98
- prof_frame_unpause(frame, measurement);
99
- total_time = measurement - frame->start_time - frame->dead_time;
100
- self_time = total_time - frame->child_time - frame->wait_time;
101
-
102
- /* Update information about the current method */
103
- call_info = frame->call_info;
104
- call_info->called++;
105
- call_info->total_time += total_time;
106
- call_info->self_time += self_time;
107
- call_info->wait_time += frame->wait_time;
108
-
109
- parent_frame = prof_stack_peek(stack);
110
- if (parent_frame)
111
- {
112
- parent_frame->child_time += total_time;
113
- parent_frame->dead_time += frame->dead_time;
114
-
115
- call_info->line = parent_frame->line;
116
- }
117
-
118
- return frame;
119
- }
120
-
121
- prof_frame_t *
122
- prof_stack_peek(prof_stack_t *stack)
123
- {
124
- if (stack->ptr == stack->start)
125
- return NULL;
126
- else
127
- return stack->ptr - 1;
128
- }
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #include "rp_stack.h"
5
+
6
+ #define INITIAL_STACK_SIZE 16
7
+
8
+ // Creates a stack of prof_frame_t to keep track of timings for active methods.
9
+ prof_stack_t* prof_stack_create()
10
+ {
11
+ prof_stack_t* stack = ALLOC(prof_stack_t);
12
+ stack->start = ZALLOC_N(prof_frame_t, INITIAL_STACK_SIZE);
13
+ stack->ptr = stack->start;
14
+ stack->end = stack->start + INITIAL_STACK_SIZE;
15
+
16
+ return stack;
17
+ }
18
+
19
+ void prof_stack_free(prof_stack_t* stack)
20
+ {
21
+ xfree(stack->start);
22
+ xfree(stack);
23
+ }
24
+
25
+ prof_frame_t* prof_stack_parent(prof_stack_t* stack)
26
+ {
27
+ if (stack->ptr == stack->start || stack->ptr - 1 == stack->start)
28
+ return NULL;
29
+ else
30
+ return stack->ptr - 2;
31
+ }
32
+
33
+ prof_frame_t* prof_stack_last(prof_stack_t* stack)
34
+ {
35
+ if (stack->ptr == stack->start)
36
+ return NULL;
37
+ else
38
+ return stack->ptr - 1;
39
+ }
40
+
41
+ void prof_stack_verify_size(prof_stack_t* stack)
42
+ {
43
+ // Is there space on the stack? If not, double its size.
44
+ if (stack->ptr == stack->end)
45
+ {
46
+ size_t len = stack->ptr - stack->start;
47
+ size_t new_capacity = (stack->end - stack->start) * 2;
48
+ REALLOC_N(stack->start, prof_frame_t, new_capacity);
49
+
50
+ /* Memory just got moved, reset pointers */
51
+ stack->ptr = stack->start + len;
52
+ stack->end = stack->start + new_capacity;
53
+ }
54
+ }
55
+
56
+ prof_frame_t* prof_stack_push(prof_stack_t* stack)
57
+ {
58
+ prof_stack_verify_size(stack);
59
+
60
+ prof_frame_t* result = stack->ptr;
61
+ stack->ptr++;
62
+ return result;
63
+ }
64
+
65
+ prof_frame_t* prof_stack_pop(prof_stack_t* stack)
66
+ {
67
+ prof_frame_t* result = prof_stack_last(stack);
68
+ if (result)
69
+ stack->ptr--;
70
+
71
+ return result;
72
+ }
73
+
74
+ // ---------------- Frame Methods ----------------------------
75
+ void prof_frame_pause(prof_frame_t* frame, double current_measurement)
76
+ {
77
+ if (frame && prof_frame_is_unpaused(frame))
78
+ frame->pause_time = current_measurement;
79
+ }
80
+
81
+ void prof_frame_unpause(prof_frame_t* frame, double current_measurement)
82
+ {
83
+ if (prof_frame_is_paused(frame))
84
+ {
85
+ frame->dead_time += (current_measurement - frame->pause_time);
86
+ frame->pause_time = -1;
87
+ }
88
+ }
89
+
90
+ prof_frame_t* prof_frame_current(prof_stack_t* stack)
91
+ {
92
+ return prof_stack_last(stack);
93
+ }
94
+
95
+ prof_frame_t* prof_frame_push(prof_stack_t* stack, prof_call_tree_t* call_tree, double measurement, bool paused)
96
+ {
97
+ prof_frame_t* result = prof_stack_push(stack);
98
+ prof_frame_t* parent_frame = prof_stack_parent(stack);
99
+
100
+ result->call_tree = call_tree;
101
+
102
+ result->start_time = measurement;
103
+ result->pause_time = -1; // init as not paused.
104
+ result->switch_time = 0;
105
+ result->wait_time = 0;
106
+ result->child_time = 0;
107
+ result->dead_time = 0;
108
+ result->source_file = Qnil;
109
+ result->source_line = 0;
110
+
111
+ call_tree->measurement->called++;
112
+ call_tree->visits++;
113
+
114
+ if (call_tree->method->visits > 0)
115
+ {
116
+ call_tree->method->recursive = true;
117
+ }
118
+ call_tree->method->measurement->called++;
119
+ call_tree->method->visits++;
120
+
121
+ // Unpause the parent frame, if it exists.
122
+ // If currently paused then:
123
+ // 1) The child frame will begin paused.
124
+ // 2) The parent will inherit the child's dead time.
125
+ if (parent_frame)
126
+ prof_frame_unpause(parent_frame, measurement);
127
+
128
+ if (paused)
129
+ {
130
+ prof_frame_pause(result, measurement);
131
+ }
132
+
133
+ // Return the result
134
+ return result;
135
+ }
136
+
137
+ prof_frame_t* prof_frame_unshift(prof_stack_t* stack, prof_call_tree_t* parent_call_tree, prof_call_tree_t* call_tree, double measurement)
138
+ {
139
+ if (prof_stack_last(stack))
140
+ rb_raise(rb_eRuntimeError, "Stack unshift can only be called with an empty stack");
141
+
142
+ parent_call_tree->measurement->total_time = call_tree->measurement->total_time;
143
+ parent_call_tree->measurement->self_time = 0;
144
+ parent_call_tree->measurement->wait_time = call_tree->measurement->wait_time;
145
+
146
+ parent_call_tree->method->measurement->total_time += call_tree->measurement->total_time;
147
+ parent_call_tree->method->measurement->wait_time += call_tree->measurement->wait_time;
148
+
149
+ return prof_frame_push(stack, parent_call_tree, measurement, false);
150
+ }
151
+
152
+ prof_frame_t* prof_frame_pop(prof_stack_t* stack, double measurement)
153
+ {
154
+ prof_frame_t* frame = prof_stack_pop(stack);
155
+
156
+ if (!frame)
157
+ return NULL;
158
+
159
+ /* Calculate the total time this method took */
160
+ prof_frame_unpause(frame, measurement);
161
+
162
+ double total_time = measurement - frame->start_time - frame->dead_time;
163
+ double self_time = total_time - frame->child_time - frame->wait_time;
164
+
165
+ /* Update information about the current method */
166
+ prof_call_tree_t* call_tree = frame->call_tree;
167
+
168
+ // Update method measurement
169
+ call_tree->method->measurement->self_time += self_time;
170
+ call_tree->method->measurement->wait_time += frame->wait_time;
171
+ if (call_tree->method->visits == 1)
172
+ call_tree->method->measurement->total_time += total_time;
173
+
174
+ call_tree->method->visits--;
175
+
176
+ // Update method measurement
177
+ call_tree->measurement->self_time += self_time;
178
+ call_tree->measurement->wait_time += frame->wait_time;
179
+ if (call_tree->visits == 1)
180
+ call_tree->measurement->total_time += total_time;
181
+
182
+ call_tree->visits--;
183
+
184
+ prof_frame_t* parent_frame = prof_stack_last(stack);
185
+ if (parent_frame)
186
+ {
187
+ parent_frame->child_time += total_time;
188
+ parent_frame->dead_time += frame->dead_time;
189
+ }
190
+
191
+ frame->source_file = Qnil;
192
+
193
+ return frame;
194
+ }
195
+
196
+ prof_method_t* prof_find_method(prof_stack_t* stack, VALUE source_file, int source_line)
197
+ {
198
+ prof_frame_t* frame = prof_stack_last(stack);
199
+ while (frame >= stack->start)
200
+ {
201
+ if (!frame->call_tree)
202
+ return NULL;
203
+
204
+ if (rb_str_equal(source_file, frame->call_tree->method->source_file) &&
205
+ source_line >= frame->call_tree->method->source_line)
206
+ {
207
+ return frame->call_tree->method;
208
+ }
209
+ frame--;
210
+ }
211
+ return NULL;
212
+ }
@@ -1,51 +1,53 @@
1
- /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
- Please see the LICENSE file for copyright and distribution information */
3
-
4
- #ifndef __RP_STACK__
5
- #define __RP_STACK__
6
-
7
- #include <ruby.h>
8
-
9
- #include "rp_measure.h"
10
- #include "rp_call_info.h"
11
-
12
-
13
- /* Temporary object that maintains profiling information
14
- for active methods. They are created and destroyed
15
- as the program moves up and down its stack. */
16
- typedef struct
17
- {
18
- /* Caching prof_method_t values significantly
19
- increases performance. */
20
- prof_call_info_t *call_info;
21
- double start_time;
22
- double switch_time; /* Time at switch to different thread */
23
- double wait_time;
24
- double child_time;
25
- double pause_time; // Time pause() was initiated
26
- double dead_time; // Time to ignore (i.e. total amount of time between pause/resume blocks)
27
- int depth;
28
- unsigned int line;
29
- } prof_frame_t;
30
-
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
-
36
-
37
- /* Current stack of active methods.*/
38
- typedef struct
39
- {
40
- prof_frame_t *start;
41
- prof_frame_t *end;
42
- prof_frame_t *ptr;
43
- } prof_stack_t;
44
-
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
-
51
- #endif //__RP_STACK__
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #ifndef __RP_STACK__
5
+ #define __RP_STACK__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_call_tree.h"
9
+
10
+ /* Temporary object that maintains profiling information
11
+ for active methods. They are created and destroyed
12
+ as the program moves up and down its stack. */
13
+ typedef struct prof_frame_t
14
+ {
15
+ /* Caching prof_method_t values significantly
16
+ increases performance. */
17
+ prof_call_tree_t* call_tree;
18
+
19
+ VALUE source_file;
20
+ unsigned int source_line;
21
+
22
+ double start_time;
23
+ double switch_time; /* Time at switch to different thread */
24
+ double wait_time;
25
+ double child_time;
26
+ double pause_time; // Time pause() was initiated
27
+ double dead_time; // Time to ignore (i.e. total amount of time between pause/resume blocks)
28
+ } prof_frame_t;
29
+
30
+ #define prof_frame_is_paused(f) (f->pause_time >= 0)
31
+ #define prof_frame_is_unpaused(f) (f->pause_time < 0)
32
+
33
+ void prof_frame_pause(prof_frame_t*, double current_measurement);
34
+ void prof_frame_unpause(prof_frame_t*, double current_measurement);
35
+
36
+ /* Current stack of active methods.*/
37
+ typedef struct prof_stack_t
38
+ {
39
+ prof_frame_t* start;
40
+ prof_frame_t* end;
41
+ prof_frame_t* ptr;
42
+ } prof_stack_t;
43
+
44
+ prof_stack_t* prof_stack_create(void);
45
+ void prof_stack_free(prof_stack_t* stack);
46
+
47
+ prof_frame_t* prof_frame_current(prof_stack_t* stack);
48
+ prof_frame_t* prof_frame_push(prof_stack_t* stack, prof_call_tree_t* call_tree, double measurement, bool paused);
49
+ prof_frame_t* prof_frame_unshift(prof_stack_t* stack, prof_call_tree_t* parent_call_tree, prof_call_tree_t* call_tree, double measurement);
50
+ prof_frame_t* prof_frame_pop(prof_stack_t* stack, double measurement);
51
+ prof_method_t* prof_find_method(prof_stack_t* stack, VALUE source_file, int source_line);
52
+
53
+ #endif //__RP_STACK__