ruby-prof 1.7.1 → 2.0.0

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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGES → CHANGELOG.md} +118 -176
  3. data/README.md +5 -5
  4. data/bin/ruby-prof +1 -4
  5. data/docs/advanced-usage.md +132 -0
  6. data/docs/alternatives.md +98 -0
  7. data/docs/architecture.md +122 -0
  8. data/docs/best-practices.md +27 -0
  9. data/docs/getting-started.md +130 -0
  10. data/docs/history.md +11 -0
  11. data/docs/index.md +45 -0
  12. data/docs/profiling-rails.md +64 -0
  13. data/docs/public/examples/example.rb +33 -0
  14. data/docs/public/examples/generate_reports.rb +92 -0
  15. data/docs/public/examples/reports/call_info.txt +27 -0
  16. data/docs/public/examples/reports/call_stack.html +835 -0
  17. data/docs/public/examples/reports/callgrind.out +150 -0
  18. data/docs/public/examples/reports/flame_graph.html +408 -0
  19. data/docs/public/examples/reports/flat.txt +45 -0
  20. data/docs/public/examples/reports/graph.dot +129 -0
  21. data/docs/public/examples/reports/graph.html +1319 -0
  22. data/docs/public/examples/reports/graph.txt +100 -0
  23. data/docs/public/examples/reports/graphviz_viewer.html +1 -0
  24. data/docs/public/images/call_stack.png +0 -0
  25. data/docs/public/images/class_diagram.png +0 -0
  26. data/docs/public/images/dot_printer.png +0 -0
  27. data/docs/public/images/flame_graph.png +0 -0
  28. data/docs/public/images/flat.png +0 -0
  29. data/docs/public/images/graph.png +0 -0
  30. data/docs/public/images/graph_html.png +0 -0
  31. data/docs/public/images/ruby-prof-logo.svg +1 -0
  32. data/docs/reports.md +150 -0
  33. data/docs/stylesheets/extra.css +80 -0
  34. data/ext/ruby_prof/extconf.rb +23 -22
  35. data/ext/ruby_prof/rp_allocation.c +0 -15
  36. data/ext/ruby_prof/rp_allocation.h +29 -33
  37. data/ext/ruby_prof/rp_call_tree.c +3 -0
  38. data/ext/ruby_prof/rp_call_tree.h +1 -4
  39. data/ext/ruby_prof/rp_call_trees.c +296 -296
  40. data/ext/ruby_prof/rp_call_trees.h +25 -28
  41. data/ext/ruby_prof/rp_measure_allocations.c +47 -47
  42. data/ext/ruby_prof/rp_measure_process_time.c +64 -66
  43. data/ext/ruby_prof/rp_measure_wall_time.c +52 -64
  44. data/ext/ruby_prof/rp_measurement.c +0 -5
  45. data/ext/ruby_prof/rp_measurement.h +49 -53
  46. data/ext/ruby_prof/rp_method.c +554 -551
  47. data/ext/ruby_prof/rp_method.h +1 -4
  48. data/ext/ruby_prof/rp_profile.c +1 -1
  49. data/ext/ruby_prof/rp_profile.h +1 -5
  50. data/ext/ruby_prof/rp_stack.c +212 -212
  51. data/ext/ruby_prof/rp_stack.h +50 -53
  52. data/ext/ruby_prof/rp_thread.h +1 -4
  53. data/ext/ruby_prof/ruby_prof.c +50 -50
  54. data/ext/ruby_prof/ruby_prof.h +4 -6
  55. data/ext/ruby_prof/vc/ruby_prof.vcxproj +7 -8
  56. data/lib/ruby-prof/assets/call_stack_printer.html.erb +746 -711
  57. data/lib/ruby-prof/assets/flame_graph_printer.html.erb +412 -0
  58. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -355
  59. data/lib/ruby-prof/call_tree.rb +57 -57
  60. data/lib/ruby-prof/call_tree_visitor.rb +36 -36
  61. data/lib/ruby-prof/exclude_common_methods.rb +204 -204
  62. data/lib/ruby-prof/measurement.rb +17 -17
  63. data/lib/ruby-prof/printers/abstract_printer.rb +142 -138
  64. data/lib/ruby-prof/printers/call_info_printer.rb +53 -53
  65. data/lib/ruby-prof/printers/call_stack_printer.rb +168 -180
  66. data/lib/ruby-prof/printers/call_tree_printer.rb +132 -145
  67. data/lib/ruby-prof/printers/dot_printer.rb +177 -132
  68. data/lib/ruby-prof/printers/flame_graph_printer.rb +79 -0
  69. data/lib/ruby-prof/printers/flat_printer.rb +52 -52
  70. data/lib/ruby-prof/printers/graph_html_printer.rb +62 -63
  71. data/lib/ruby-prof/printers/graph_printer.rb +112 -113
  72. data/lib/ruby-prof/printers/multi_printer.rb +134 -127
  73. data/lib/ruby-prof/profile.rb +13 -0
  74. data/lib/ruby-prof/rack.rb +114 -105
  75. data/lib/ruby-prof/task.rb +147 -147
  76. data/lib/ruby-prof/thread.rb +20 -20
  77. data/lib/ruby-prof/version.rb +3 -3
  78. data/lib/ruby-prof.rb +50 -52
  79. data/lib/unprof.rb +10 -10
  80. data/ruby-prof.gemspec +66 -65
  81. data/test/abstract_printer_test.rb +25 -27
  82. data/test/alias_test.rb +203 -117
  83. data/test/call_tree_builder.rb +126 -126
  84. data/test/call_tree_visitor_test.rb +27 -27
  85. data/test/call_trees_test.rb +66 -66
  86. data/test/duplicate_names_test.rb +32 -32
  87. data/test/dynamic_method_test.rb +50 -62
  88. data/test/enumerable_test.rb +23 -21
  89. data/test/exceptions_test.rb +24 -24
  90. data/test/exclude_methods_test.rb +363 -257
  91. data/test/exclude_threads_test.rb +48 -48
  92. data/test/fiber_test.rb +195 -195
  93. data/test/gc_test.rb +104 -102
  94. data/test/inverse_call_tree_test.rb +174 -174
  95. data/test/line_number_test.rb +563 -289
  96. data/test/marshal_test.rb +144 -145
  97. data/test/measure_allocations.rb +26 -26
  98. data/test/measure_allocations_test.rb +1511 -1081
  99. data/test/measure_process_time_test.rb +3286 -2477
  100. data/test/measure_times.rb +56 -56
  101. data/test/measure_wall_time_test.rb +773 -568
  102. data/test/measurement_test.rb +82 -82
  103. data/test/merge_test.rb +146 -146
  104. data/test/method_info_test.rb +100 -95
  105. data/test/multi_printer_test.rb +52 -66
  106. data/test/no_method_class_test.rb +15 -15
  107. data/test/pause_resume_test.rb +171 -171
  108. data/test/prime.rb +54 -54
  109. data/test/prime_script.rb +5 -5
  110. data/test/printer_call_stack_test.rb +28 -27
  111. data/test/printer_call_tree_test.rb +30 -30
  112. data/test/printer_flame_graph_test.rb +82 -0
  113. data/test/printer_flat_test.rb +99 -99
  114. data/test/printer_graph_html_test.rb +62 -59
  115. data/test/printer_graph_test.rb +42 -40
  116. data/test/printers_test.rb +162 -135
  117. data/test/printing_recursive_graph_test.rb +81 -81
  118. data/test/profile_test.rb +101 -101
  119. data/test/rack_test.rb +103 -93
  120. data/test/recursive_test.rb +796 -622
  121. data/test/scheduler.rb +4 -0
  122. data/test/singleton_test.rb +39 -38
  123. data/test/stack_printer_test.rb +61 -61
  124. data/test/start_stop_test.rb +106 -106
  125. data/test/test_helper.rb +24 -20
  126. data/test/thread_test.rb +229 -231
  127. data/test/unique_call_path_test.rb +123 -136
  128. data/test/yarv_test.rb +56 -60
  129. metadata +68 -16
  130. data/ext/ruby_prof/rp_measure_memory.c +0 -46
  131. data/lib/ruby-prof/compatibility.rb +0 -113
  132. data/test/compatibility_test.rb +0 -49
  133. data/test/crash2.rb +0 -144
  134. data/test/measure_memory_test.rb +0 -1456
@@ -1,8 +1,7 @@
1
1
  /* Copyright (C) 2005-2019 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
- #ifndef __RP_METHOD_INFO__
5
- #define __RP_METHOD_INFO__
4
+ #pragma once
6
5
 
7
6
  #include "ruby_prof.h"
8
7
  #include "rp_measurement.h"
@@ -62,5 +61,3 @@ void prof_method_mark(void* data);
62
61
 
63
62
  VALUE resolve_klass(VALUE klass, unsigned int* klass_flags);
64
63
  VALUE resolve_klass_name(VALUE klass, unsigned int* klass_flags);
65
-
66
- #endif //__RP_METHOD_INFO__
@@ -186,7 +186,7 @@ static void prof_trace(prof_profile_t* profile, rb_trace_arg_t* trace_arg, doubl
186
186
  const char* source_file_char = (source_file != Qnil ? StringValuePtr(source_file) : "");
187
187
 
188
188
  fprintf(trace_file, "%2lu:%2f %-8s %s#%s %s:%2d\n",
189
- FIX2ULONG(fiber), (double)measurement,
189
+ NUM2ULONG(rb_obj_id(fiber)), (double)measurement,
190
190
  event_name, class_name, method_name_char, source_file_char, source_line);
191
191
  fflush(trace_file);
192
192
  last_fiber = fiber;
@@ -1,8 +1,7 @@
1
1
  /* Copyright (C) 2005-2019 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
- #ifndef __RP_PROFILE_H__
5
- #define __RP_PROFILE_H__
4
+ #pragma once
6
5
 
7
6
  #include "ruby_prof.h"
8
7
  #include "rp_measurement.h"
@@ -31,6 +30,3 @@ typedef struct prof_profile_t
31
30
 
32
31
  void rp_init_profile(void);
33
32
  prof_profile_t* prof_get_profile(VALUE self);
34
-
35
-
36
- #endif //__RP_PROFILE_H__
@@ -1,212 +1,212 @@
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(void)
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
+ /* 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(void)
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,53 +1,50 @@
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__
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
+ #pragma once
5
+
6
+ #include "ruby_prof.h"
7
+ #include "rp_call_tree.h"
8
+
9
+ /* Temporary object that maintains profiling information
10
+ for active methods. They are created and destroyed
11
+ as the program moves up and down its stack. */
12
+ typedef struct prof_frame_t
13
+ {
14
+ /* Caching prof_method_t values significantly
15
+ increases performance. */
16
+ prof_call_tree_t* call_tree;
17
+
18
+ VALUE source_file;
19
+ unsigned int source_line;
20
+
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
+ } prof_frame_t;
28
+
29
+ static inline bool prof_frame_is_paused(prof_frame_t* f) { return f->pause_time >= 0; }
30
+ static inline bool prof_frame_is_unpaused(prof_frame_t* f) { return f->pause_time < 0; }
31
+
32
+ void prof_frame_pause(prof_frame_t*, double current_measurement);
33
+ void prof_frame_unpause(prof_frame_t*, double current_measurement);
34
+
35
+ /* Current stack of active methods.*/
36
+ typedef struct prof_stack_t
37
+ {
38
+ prof_frame_t* start;
39
+ prof_frame_t* end;
40
+ prof_frame_t* ptr;
41
+ } prof_stack_t;
42
+
43
+ prof_stack_t* prof_stack_create(void);
44
+ void prof_stack_free(prof_stack_t* stack);
45
+
46
+ prof_frame_t* prof_frame_current(prof_stack_t* stack);
47
+ prof_frame_t* prof_frame_push(prof_stack_t* stack, prof_call_tree_t* call_tree, double measurement, bool paused);
48
+ 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);
49
+ prof_frame_t* prof_frame_pop(prof_stack_t* stack, double measurement);
50
+ prof_method_t* prof_find_method(prof_stack_t* stack, VALUE source_file, int source_line);
@@ -1,8 +1,7 @@
1
1
  /* Copyright (C) 2005-2019 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
- #ifndef __RP_THREAD__
5
- #define __RP_THREAD__
4
+ #pragma once
6
5
 
7
6
  #include "ruby_prof.h"
8
7
  #include "rp_stack.h"
@@ -35,5 +34,3 @@ void prof_thread_mark(void* data);
35
34
  void switch_thread(void* profile, thread_data_t* thread_data, double measurement);
36
35
  int pause_thread(st_data_t key, st_data_t value, st_data_t data);
37
36
  int unpause_thread(st_data_t key, st_data_t value, st_data_t data);
38
-
39
- #endif //__RP_THREAD__