ruby-prof 1.4.4-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +608 -0
  3. data/LICENSE +25 -0
  4. data/README.md +5 -0
  5. data/Rakefile +98 -0
  6. data/bin/ruby-prof +328 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +22 -0
  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 +367 -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 +47 -0
  18. data/ext/ruby_prof/rp_measure_memory.c +46 -0
  19. data/ext/ruby_prof/rp_measure_process_time.c +66 -0
  20. data/ext/ruby_prof/rp_measure_wall_time.c +64 -0
  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 -0
  24. data/ext/ruby_prof/rp_method.h +62 -0
  25. data/ext/ruby_prof/rp_profile.c +915 -0
  26. data/ext/ruby_prof/rp_profile.h +35 -0
  27. data/ext/ruby_prof/rp_stack.c +212 -0
  28. data/ext/ruby_prof/rp_stack.h +53 -0
  29. data/ext/ruby_prof/rp_thread.c +362 -0
  30. data/ext/ruby_prof/rp_thread.h +39 -0
  31. data/ext/ruby_prof/ruby_prof.c +52 -0
  32. data/ext/ruby_prof/ruby_prof.h +26 -0
  33. data/ext/ruby_prof/vc/ruby_prof.sln +39 -0
  34. data/ext/ruby_prof/vc/ruby_prof.vcxproj +160 -0
  35. data/lib/3.1/ruby_prof.so +0 -0
  36. data/lib/ruby-prof/assets/call_stack_printer.html.erb +711 -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 -0
  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 -0
  45. data/lib/ruby-prof/printers/abstract_printer.rb +137 -0
  46. data/lib/ruby-prof/printers/call_info_printer.rb +53 -0
  47. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -0
  48. data/lib/ruby-prof/printers/call_tree_printer.rb +147 -0
  49. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  50. data/lib/ruby-prof/printers/flat_printer.rb +53 -0
  51. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -0
  52. data/lib/ruby-prof/printers/graph_printer.rb +113 -0
  53. data/lib/ruby-prof/printers/multi_printer.rb +127 -0
  54. data/lib/ruby-prof/profile.rb +37 -0
  55. data/lib/ruby-prof/rack.rb +95 -0
  56. data/lib/ruby-prof/task.rb +147 -0
  57. data/lib/ruby-prof/thread.rb +20 -0
  58. data/lib/ruby-prof/version.rb +3 -0
  59. data/lib/ruby-prof.rb +52 -0
  60. data/lib/unprof.rb +10 -0
  61. data/ruby-prof.gemspec +64 -0
  62. data/test/abstract_printer_test.rb +26 -0
  63. data/test/alias_test.rb +122 -0
  64. data/test/basic_test.rb +43 -0
  65. data/test/call_tree_visitor_test.rb +32 -0
  66. data/test/call_trees_test.rb +66 -0
  67. data/test/duplicate_names_test.rb +32 -0
  68. data/test/dynamic_method_test.rb +67 -0
  69. data/test/enumerable_test.rb +21 -0
  70. data/test/exceptions_test.rb +24 -0
  71. data/test/exclude_methods_test.rb +151 -0
  72. data/test/exclude_threads_test.rb +53 -0
  73. data/test/fiber_test.rb +129 -0
  74. data/test/gc_test.rb +100 -0
  75. data/test/inverse_call_tree_test.rb +175 -0
  76. data/test/line_number_test.rb +158 -0
  77. data/test/marshal_test.rb +145 -0
  78. data/test/measure_allocations.rb +26 -0
  79. data/test/measure_allocations_test.rb +333 -0
  80. data/test/measure_memory_test.rb +688 -0
  81. data/test/measure_process_time_test.rb +1614 -0
  82. data/test/measure_times.rb +56 -0
  83. data/test/measure_wall_time_test.rb +426 -0
  84. data/test/multi_printer_test.rb +71 -0
  85. data/test/no_method_class_test.rb +15 -0
  86. data/test/pause_resume_test.rb +175 -0
  87. data/test/prime.rb +54 -0
  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 -0
  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 +430 -0
  99. data/test/singleton_test.rb +38 -0
  100. data/test/stack_printer_test.rb +64 -0
  101. data/test/start_stop_test.rb +109 -0
  102. data/test/test_helper.rb +13 -0
  103. data/test/thread_test.rb +144 -0
  104. data/test/unique_call_path_test.rb +136 -0
  105. data/test/yarv_test.rb +60 -0
  106. metadata +187 -0
@@ -0,0 +1,355 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <style media="all" type="text/css">
5
+ body {
6
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
7
+ background-color: #F5F7FB;
8
+ margin: 0;
9
+ padding: 0;
10
+ font-size: 16px;
11
+ }
12
+
13
+ table {
14
+ border-collapse: collapse;
15
+ /* border: 1px solid #E1E3E7; */
16
+ border: 1px solid #F3F9FE;
17
+ font-size: 14px;
18
+ line-height: normal;
19
+ width: 100%;
20
+ }
21
+
22
+ table:empty {
23
+ display: none;
24
+ }
25
+
26
+ th:first-child {
27
+ border-left: 0;
28
+ }
29
+
30
+ th {
31
+ text-align: center;
32
+ background: #F3F9FE;
33
+ padding: 1rem;
34
+ /* border-left: 1px solid #E1E3E7; */
35
+ text-transform: uppercase;
36
+ font-size: 13px;
37
+ letter-spacing: 1px;
38
+ }
39
+
40
+ tr.break td {
41
+ border: 0;
42
+ border-top: 1px solid #BDC3DD;
43
+ padding: 0;
44
+ margin: 0;
45
+ }
46
+
47
+ tr.method td {
48
+ font-weight: bold;
49
+ }
50
+
51
+ td {
52
+ padding: 0.5em;
53
+ }
54
+
55
+ td:first-child {
56
+ width: 190px;
57
+ }
58
+
59
+ tr > td > table {
60
+ box-shadow: 0px -2px 1px #F9FAFB, 0px 1px 1px #E4EEEE, 0px 1px 2px #EEF3F8;
61
+ border-radius: 2px;
62
+ overflow: hidden;
63
+ }
64
+
65
+ tr.break + tr > td.method_name {
66
+ font-weight: bold;
67
+ }
68
+
69
+ td {
70
+ /* I'm removing this border because I think it looks way cleaner without it but feel free to add it if you feel it's necessary */
71
+ /* border-left: 1px solid #E1E3E7; */
72
+ text-align: center;
73
+ }
74
+
75
+ a {
76
+ text-decoration: none;
77
+ }
78
+
79
+ .method_name {
80
+ text-align: left;
81
+ }
82
+
83
+ tfoot td {
84
+ text-align: left;
85
+ }
86
+
87
+ .report-header {
88
+ background-color: #0D2483;
89
+ color: white;
90
+ padding: 1.5rem 2rem;
91
+ }
92
+
93
+ .report-header > div {
94
+ display: flex;
95
+ flex-direction: row;
96
+ align-items: center;
97
+ }
98
+
99
+ .report-header h1 {
100
+ margin-bottom: 0;
101
+ }
102
+
103
+ h1, h2, h3, h4, h5, h6 {
104
+ margin-top: 0;
105
+ margin-bottom: 0.5rem;
106
+ }
107
+
108
+ h6 {
109
+ font-size: 0.75rem;
110
+ text-transform: uppercase;
111
+ letter-spacing: 1.5px;
112
+ color: rgba(255, 255, 255, 0.6);
113
+ }
114
+
115
+ .table-header {
116
+ padding: 3rem 0 1rem;
117
+ }
118
+
119
+ .table-wrapper {
120
+ margin: 1rem auto;
121
+ max-width: 1440px;
122
+ padding: 4rem 5rem;
123
+ background: white;
124
+ border-radius: 0.5rem;
125
+ }
126
+
127
+ .center {
128
+ max-width: 1440px;
129
+ margin: 0 auto;
130
+ }
131
+
132
+ .layout-right {
133
+ margin-left: auto;
134
+ }
135
+
136
+ .text-right {
137
+ display: flex;
138
+ align-items: flex-end;
139
+ flex-direction: column;
140
+ }
141
+
142
+ .timestamp {
143
+ font-size: 12px;
144
+ margin-bottom: 1rem;
145
+ color: rgba(255, 255, 255, 0.6);
146
+ }
147
+
148
+ .logo {
149
+ width: 140px;
150
+ height: 30px;
151
+ opacity: 0.5;
152
+ background-repeat: no-repeat;
153
+ background-image: url("data:image/svg+xml,%3Csvg id='Layer_1' data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 190 41'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23fff%7D%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='M63.49 16.74c0-1.37-.91-2-2.26-2h-3.38v3.93h3.58c1.24.01 2.06-.56 2.06-1.93zM110.43 14.75h-3.6v5h3.6a2.32 2.32 0 0 0 2.5-2.49 2.34 2.34 0 0 0-2.5-2.51zM128.77 14.75h-3.53v4.94h3.53a2.28 2.28 0 0 0 2.47-2.45 2.3 2.3 0 0 0-2.47-2.49zM61.81 21.83h-4v4.32h3.91c1.44 0 2.45-.62 2.45-2.14s-.99-2.18-2.36-2.18zM21 14.75h-3.57v4.94H21a2.28 2.28 0 0 0 2.47-2.45A2.3 2.3 0 0 0 21 14.75z'/%3E%3Cpath class='cls-1' d='M184 .44H5.87A4.93 4.93 0 0 0 .94 5.37V35.5a4.94 4.94 0 0 0 4.93 4.94H184a4.94 4.94 0 0 0 4.94-4.94V5.37A4.94 4.94 0 0 0 184 .44zm-34.38 10.78c4.79 0 8.46 2.89 9.18 7.54h-3.86a5.48 5.48 0 0 0-10.68 0h-3.83c.71-4.65 4.36-7.54 9.19-7.54zM24 29.44L20.46 23h-3v6.46h-3.72v-18h7.68c3.41 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.82 7.06zm24.31-7.3c0 4.8-2.92 7.56-7.63 7.56S33 26.94 33 22.14V11.48h3.69v10.61c0 2.81 1.37 4.32 4 4.32s3.94-1.51 3.94-4.32V11.48h3.69zm13.92 7.3h-8v-18h7.52c3.24 0 5.59 1.61 5.59 5A4 4 0 0 1 65.51 20 4.22 4.22 0 0 1 68 24.21c0 3.43-2.4 5.23-5.81 5.23zm19.66-6.92v6.92h-3.7v-6.92l-6.81-11h4.29L80 18.85l4.34-7.37h4.32zm16-.5h-7.62v-3.26h7.59zm13 1h-4v6.39h-3.72v-18h7.77c3.41 0 5.79 2.09 5.79 5.79s-2.41 5.85-5.82 5.85zm20.86 6.39L128.26 23h-3v6.46h-3.72v-18h7.69c3.4 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.87 7.08zm17.85.26c-4.88 0-8.55-2.95-9.21-7.68h3.81A5.49 5.49 0 0 0 155 22h3.84c-.69 4.75-4.38 7.7-9.22 7.7zm18.4-.23h-3.72v-3.7H168zm6.36-7.54h-10.05v-3.26h10.08zm1.44-7.16h-11.49v-3.26h11.52z'/%3E%3C/svg%3E");
154
+ }
155
+ </style>
156
+ </head>
157
+ <body>
158
+ <div class="report-header">
159
+ <div class="center">
160
+ <div class="layout-left">
161
+ <h6>Profile Report</h6>
162
+ <h1><%= @result.measure_mode_string.capitalize %></h1>
163
+ </div>
164
+ <div class="layout-right text-right">
165
+ <div class="timestamp"><%= Time.now.strftime(self.time_format) %></div>
166
+ <div class="logo"></div>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <div class="table-wrapper">
171
+ <table>
172
+ <tr>
173
+ <th>Thread ID</th>
174
+ <th>Fiber ID</th>
175
+ <th>Total</th>
176
+ </tr>
177
+ <% for thread in @result.threads %>
178
+ <tr>
179
+ <td><%= thread.id %></td>
180
+ <td><a href="#<%= thread.fiber_id %>"><%= thread.fiber_id %></a></td>
181
+ <td><%= thread.total_time %></td>
182
+ </tr>
183
+ <% end %>
184
+ </table>
185
+
186
+ <!-- Methods Tables -->
187
+ <%
188
+ for thread in @result.threads
189
+ methods = thread.methods
190
+ total_time = thread.total_time
191
+ %>
192
+ <h2><a name="<%= thread.fiber_id %>">Thread <%= thread.id %>, Fiber: <%= thread.fiber_id %></a></h2>
193
+ <table>
194
+ <thead>
195
+ <tr>
196
+ <th>%Total</th>
197
+ <th>%Self</th>
198
+ <th>Total</th>
199
+ <th>Self</th>
200
+ <th>Wait</th>
201
+ <th>Child</th>
202
+ <th>Calls</th>
203
+ <th class="method_name">Name</th>
204
+ <% if @result.track_allocations? %>
205
+ <th>Allocations</th>
206
+ <% end %>
207
+ <th>Line</th>
208
+ </tr>
209
+ </thead>
210
+ <tbody>
211
+ <% min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
212
+ sorted_methods = sort_method ? methods.sort_by(&sort_method) : methods.sort
213
+ sorted_methods.reverse_each do |method|
214
+ total_percentage = (method.total_time/total_time) * 100
215
+ next if total_percentage < min_percent
216
+ next if min_time && method.total_time < min_time
217
+ self_percentage = (method.self_time/total_time) * 100 %>
218
+
219
+ <!-- Parents -->
220
+ <% for caller in method.call_trees.callers.sort
221
+ next if min_time && caller.total_time < min_time %>
222
+ <tr>
223
+ <td>&nbsp;</td>
224
+ <td>&nbsp;</td>
225
+ <td><%= sprintf("%.2f", caller.total_time) %></td>
226
+ <td><%= sprintf("%.2f", caller.self_time) %></td>
227
+ <td><%= sprintf("%.2f", caller.wait_time) %></td>
228
+ <td><%= sprintf("%.2f", caller.children_time) %></td>
229
+ <td><%= "#{caller.called}/#{method.called}" %></td>
230
+ <td class="method_name"><%= create_link(thread, total_time, caller.parent.target) %></td>
231
+ <% if @result.track_allocations? %>
232
+ <td>-</td>
233
+ <% end %>
234
+ <td><%= if caller.parent.target.source_file
235
+ file_link(caller.parent.target.source_file, caller.line)
236
+ end %></td>
237
+ </tr>
238
+ <% end %>
239
+ <tr class="method">
240
+ <td><%= sprintf("%.2f%%", total_percentage) %></td>
241
+ <td><%= sprintf("%.2f%%", self_percentage) %></td>
242
+ <td><%= sprintf("%.2f", method.total_time) %></td>
243
+ <td><%= sprintf("%.2f", method.self_time) %></td>
244
+ <td><%= sprintf("%.2f", method.wait_time) %></td>
245
+ <td><%= sprintf("%.2f", method.children_time) %></td>
246
+ <td><%= sprintf("%i", method.called) %></td>
247
+ <td class="method_name">
248
+ <a name="<%= method_href(thread, method) %>">
249
+ <%= method.recursive? ? "*" : " " %><%= h method.full_name %>
250
+ </a>
251
+ </td>
252
+
253
+ <% if @result.track_allocations? %>
254
+ <td>
255
+ <% count = method.allocations.reduce(0) do |size, allocation|
256
+ size += allocation.count
257
+ end %>
258
+ <% if count > 0 %>
259
+ <a class="allocations" href="#<%= method_href(thread, method) %>_allocations" %><%= count %></a>
260
+ <% else %>
261
+ 0
262
+ <% end %>
263
+ </td>
264
+ <% end %>
265
+
266
+ <td><%= if method.source_file
267
+ file_link(method.source_file, method.line)
268
+ end %></td>
269
+ </tr>
270
+
271
+ <% if @result.track_allocations? %>
272
+ <tr>
273
+ <td colspan="10">
274
+ <table id="<%= method_href(thread, method) %>_allocations" class="allocations" style="display: none">
275
+ <% for allocation in method.allocations %>
276
+ <tr>
277
+ <td>
278
+ <%= allocation.klass_name %>
279
+ </td>
280
+ <td>
281
+ <%= "#{allocation.count} (#{allocation.memory} Bytes)" %>
282
+ </td>
283
+ <td>
284
+ <%= "#{allocation.source_file}:#{allocation.line}" %>
285
+ </td>
286
+ </tr>
287
+ <% end %>
288
+ </table>
289
+
290
+ </td>
291
+ </tr>
292
+ <% end %>
293
+
294
+ <!-- Children -->
295
+ <% for callee in method.call_trees.callees.sort_by(&:total_time).reverse
296
+ next if min_time && callee.total_time < min_time %>
297
+ <tr>
298
+ <td>&nbsp;</td>
299
+ <td>&nbsp;</td>
300
+ <td><%= sprintf("%.2f", callee.total_time) %></td>
301
+ <td><%= sprintf("%.2f", callee.self_time) %></td>
302
+ <td><%= sprintf("%.2f", callee.wait_time) %></td>
303
+ <td><%= sprintf("%.2f", callee.children_time) %></td>
304
+ <td><%= "#{callee.called}/#{callee.target.called}" %></td>
305
+ <td class="method_name"><%= create_link(thread, total_time, callee.target) %></td>
306
+ <% if @result.track_allocations? %>
307
+ <td>-</td>
308
+ <% end %>
309
+ <td><%= file_link(callee.source_file, callee.line) %>
310
+ </tr>
311
+ <% end %>
312
+
313
+ <!-- Create divider row -->
314
+ <tr class="break">
315
+ <td colspan="10"></td>
316
+ </tr>
317
+ <% end %>
318
+ </tbody>
319
+ <tfoot>
320
+ <tr>
321
+ <td colspan="9">* indicates recursively called methods</td>
322
+ </tr>
323
+ </tfoot>
324
+ </table>
325
+ <% end %>
326
+ </div>
327
+
328
+ <script type="application/javascript">
329
+ function toggleAllocations(element)
330
+ {
331
+ if (element.style.display == 'none')
332
+ element.style.display = 'block'
333
+ else
334
+ element.style.display = 'none'
335
+ }
336
+
337
+ function onClick(event)
338
+ {
339
+ if (event.target.tagName == 'A' && event.target.classList.contains('allocations'))
340
+ {
341
+ var url = new URL(event.target.href)
342
+ var element = document.querySelector(url.hash)
343
+ toggleAllocations(element)
344
+ event.preventDefault()
345
+ }
346
+ }
347
+
348
+ window.addEventListener('DOMContentLoaded', function(event)
349
+ {
350
+ document.addEventListener('click', onClick)
351
+ })
352
+
353
+ </script>
354
+ </body>
355
+ </html>
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ module RubyProf
4
+ # The CallTree class is used to track the relationships between methods. It is a helper class used by
5
+ # RubyProf::MethodInfo to keep track of which methods called a given method and which methods a given
6
+ # method called. Each CallTree has a parent and target method. You cannot create a CallTree object directly,
7
+ # they are generated while running a profile.
8
+ class CallTree
9
+ # The number of times the parent method called the target method
10
+ def called
11
+ self.measurement.called
12
+ end
13
+
14
+ # The total time resulting from the parent method calling the target method
15
+ def total_time
16
+ self.measurement.total_time
17
+ end
18
+
19
+ # The self time (of the parent) resulting from the parent method calling the target method
20
+ def self_time
21
+ self.measurement.self_time
22
+ end
23
+
24
+ # The wait time (of the parent) resulting from the parent method calling the target method
25
+ def wait_time
26
+ self.measurement.wait_time
27
+ end
28
+
29
+ # The time spent in child methods resulting from the parent method calling the target method
30
+ def children_time
31
+ self.total_time - self.self_time - self.wait_time
32
+ end
33
+
34
+ # Compares two CallTree instances. The comparison is based on the CallTree#parent, CallTree#target,
35
+ # and total time.
36
+ def <=>(other)
37
+ if self.target == other.target && self.parent == other.parent
38
+ 0
39
+ elsif self.total_time < other.total_time
40
+ -1
41
+ elsif self.total_time > other.total_time
42
+ 1
43
+ else
44
+ self.target.full_name <=> other.target.full_name
45
+ end
46
+ end
47
+
48
+ # :nodoc:
49
+ def to_s
50
+ "<#{self.class.name} - #{self.target.full_name}>"
51
+ end
52
+
53
+ def inspect
54
+ self.to_s
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,36 @@
1
+ module RubyProf
2
+ # The call info visitor class does a depth-first traversal across a
3
+ # list of call infos. At each call_tree node, the visitor executes
4
+ # the block provided in the #visit method. The block is passed two
5
+ # parameters, the event and the call_tree instance. Event will be
6
+ # either :enter or :exit.
7
+ #
8
+ # visitor = RubyProf::CallTreeVisitor.new(result.threads.first.call_tree)
9
+ #
10
+ # method_names = Array.new
11
+ #
12
+ # visitor.visit do |call_tree, event|
13
+ # method_names << call_tree.target.full_name if event == :enter
14
+ # end
15
+ #
16
+ # puts method_names
17
+ class CallTreeVisitor
18
+ def initialize(call_tree)
19
+ @call_tree = call_tree
20
+ end
21
+
22
+ def visit(&block)
23
+ visit_call_tree(@call_tree, &block)
24
+ end
25
+
26
+ private
27
+
28
+ def visit_call_tree(call_tree, &block)
29
+ yield call_tree, :enter
30
+ call_tree.children.each do |child|
31
+ visit_call_tree(child, &block)
32
+ end
33
+ yield call_tree, :exit
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ # These methods are deprecated and are available for backwards compatability.
4
+ module RubyProf
5
+ # call-seq:
6
+ # measure_mode -> measure_mode
7
+ #
8
+ # Returns what ruby-prof is measuring. Valid values include:
9
+ #
10
+ # * RubyProf::WALL_TIME
11
+ # * RubyProf::PROCESS_TIME
12
+ # * RubyProf::ALLOCATIONS
13
+ # * RubyProf::MEMORY
14
+ def self.measure_mode
15
+ @measure_mode ||= RubyProf::WALL_TIME
16
+ end
17
+
18
+ # call-seq:
19
+ # measure_mode=value -> void
20
+ #
21
+ # Specifies what ruby-prof should measure. Valid values include:
22
+ #
23
+ # * RubyProf::WALL_TIME - Wall time measures the real-world time elapsed between any two moments. If there are other processes concurrently running on the system that use significant CPU or disk time during a profiling run then the reported results will be larger than expected. On Windows, wall time is measured using GetTickCount(), on MacOS by mach_absolute_time, on Linux by clock_gettime and otherwise by gettimeofday.
24
+ # * RubyProf::PROCESS_TIME - Process time measures the time used by a process between any two moments. It is unaffected by other processes concurrently running on the system. Remember with process time that calls to methods like sleep will not be included in profiling results. On Windows, process time is measured using GetProcessTimes and on other platforms by clock_gettime.
25
+ # * RubyProf::ALLOCATIONS - Object allocations measures show how many objects each method in a program allocates. Measurements are done via Ruby's GC.stat api.
26
+ # * RubyProf::MEMORY - Memory measures how much memory each method in a program uses. Measurements are done via Ruby's TracePoint api.
27
+ def self.measure_mode=(value)
28
+ @measure_mode = value
29
+ end
30
+
31
+ # Returns the threads that ruby-prof should exclude from profiling
32
+ def self.exclude_threads
33
+ @exclude_threads ||= Array.new
34
+ end
35
+
36
+ # Specifies which threads ruby-prof should exclude from profiling
37
+ def self.exclude_threads=(value)
38
+ @exclude_threads = value
39
+ end
40
+
41
+ # Starts profiling
42
+ def self.start
43
+ ensure_not_running!
44
+ @profile = Profile.new(:measure_mode => measure_mode, :exclude_threads => exclude_threads)
45
+ @profile.start
46
+ end
47
+
48
+ # Pauses profiling
49
+ def self.pause
50
+ ensure_running!
51
+ @profile.pause
52
+ end
53
+
54
+ # Is a profile running?
55
+ def self.running?
56
+ if defined?(@profile) and @profile
57
+ @profile.running?
58
+ else
59
+ false
60
+ end
61
+ end
62
+
63
+ # Resume profiling
64
+ def self.resume
65
+ ensure_running!
66
+ @profile.resume
67
+ end
68
+
69
+ # Stops profiling
70
+ def self.stop
71
+ ensure_running!
72
+ result = @profile.stop
73
+ @profile = nil
74
+ result
75
+ end
76
+
77
+ # Profiles a block
78
+ def self.profile(options = {}, &block)
79
+ ensure_not_running!
80
+ options = {:measure_mode => measure_mode, :exclude_threads => exclude_threads }.merge!(options)
81
+ Profile.profile(options, &block)
82
+ end
83
+
84
+ # :nodoc:
85
+ def self.start_script(script)
86
+ start
87
+ load script
88
+ end
89
+
90
+ private
91
+
92
+ def self.ensure_running!
93
+ raise(RuntimeError, "RubyProf.start was not yet called") unless running?
94
+ end
95
+
96
+ def self.ensure_not_running!
97
+ raise(RuntimeError, "RubyProf is already running") if running?
98
+ end
99
+ end