ruby-prof 0.18.0-x64-mingw32 → 1.1.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +32 -0
  3. data/LICENSE +2 -2
  4. data/README.rdoc +1 -483
  5. data/Rakefile +3 -6
  6. data/bin/ruby-prof +65 -30
  7. data/ext/ruby_prof/extconf.rb +6 -38
  8. data/ext/ruby_prof/rp_allocation.c +279 -0
  9. data/ext/ruby_prof/rp_allocation.h +31 -0
  10. data/ext/ruby_prof/rp_call_info.c +129 -283
  11. data/ext/ruby_prof/rp_call_info.h +16 -34
  12. data/ext/ruby_prof/rp_measure_allocations.c +25 -49
  13. data/ext/ruby_prof/rp_measure_memory.c +21 -56
  14. data/ext/ruby_prof/rp_measure_process_time.c +35 -39
  15. data/ext/ruby_prof/rp_measure_wall_time.c +36 -19
  16. data/ext/ruby_prof/rp_measurement.c +230 -0
  17. data/ext/ruby_prof/rp_measurement.h +50 -0
  18. data/ext/ruby_prof/rp_method.c +389 -389
  19. data/ext/ruby_prof/rp_method.h +34 -39
  20. data/ext/ruby_prof/rp_profile.c +895 -0
  21. data/ext/ruby_prof/rp_profile.h +37 -0
  22. data/ext/ruby_prof/rp_stack.c +103 -80
  23. data/ext/ruby_prof/rp_stack.h +5 -12
  24. data/ext/ruby_prof/rp_thread.c +143 -83
  25. data/ext/ruby_prof/rp_thread.h +15 -6
  26. data/ext/ruby_prof/ruby_prof.c +11 -757
  27. data/ext/ruby_prof/ruby_prof.h +4 -47
  28. data/ext/ruby_prof/vc/ruby_prof.vcxproj +10 -8
  29. data/lib/{2.6.3 → 2.6.5}/ruby_prof.so +0 -0
  30. data/lib/ruby-prof.rb +2 -18
  31. data/lib/ruby-prof/assets/call_stack_printer.html.erb +713 -0
  32. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  33. data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
  34. data/lib/ruby-prof/call_info.rb +35 -93
  35. data/lib/ruby-prof/call_info_visitor.rb +19 -21
  36. data/lib/ruby-prof/compatibility.rb +37 -107
  37. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  38. data/lib/ruby-prof/measurement.rb +14 -0
  39. data/lib/ruby-prof/method_info.rb +52 -83
  40. data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
  41. data/lib/ruby-prof/printers/call_info_printer.rb +13 -3
  42. data/lib/ruby-prof/printers/call_stack_printer.rb +62 -145
  43. data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
  44. data/lib/ruby-prof/printers/dot_printer.rb +5 -5
  45. data/lib/ruby-prof/printers/flat_printer.rb +6 -24
  46. data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
  47. data/lib/ruby-prof/printers/graph_printer.rb +13 -15
  48. data/lib/ruby-prof/printers/multi_printer.rb +66 -23
  49. data/lib/ruby-prof/profile.rb +10 -3
  50. data/lib/ruby-prof/rack.rb +0 -3
  51. data/lib/ruby-prof/thread.rb +12 -12
  52. data/lib/ruby-prof/version.rb +1 -1
  53. data/ruby-prof.gemspec +2 -2
  54. data/test/abstract_printer_test.rb +0 -27
  55. data/test/alias_test.rb +129 -0
  56. data/test/basic_test.rb +41 -40
  57. data/test/call_info_visitor_test.rb +3 -3
  58. data/test/dynamic_method_test.rb +0 -2
  59. data/test/fiber_test.rb +11 -17
  60. data/test/gc_test.rb +96 -0
  61. data/test/line_number_test.rb +120 -39
  62. data/test/marshal_test.rb +119 -0
  63. data/test/measure_allocations.rb +30 -0
  64. data/test/measure_allocations_test.rb +371 -12
  65. data/test/measure_allocations_trace_test.rb +385 -0
  66. data/test/measure_memory_trace_test.rb +756 -0
  67. data/test/measure_process_time_test.rb +821 -33
  68. data/test/measure_times.rb +54 -0
  69. data/test/measure_wall_time_test.rb +349 -145
  70. data/test/multi_printer_test.rb +1 -34
  71. data/test/parser_timings.rb +24 -0
  72. data/test/pause_resume_test.rb +5 -5
  73. data/test/prime.rb +2 -0
  74. data/test/printer_call_stack_test.rb +28 -0
  75. data/test/printer_call_tree_test.rb +31 -0
  76. data/test/printer_flat_test.rb +68 -0
  77. data/test/printer_graph_html_test.rb +60 -0
  78. data/test/printer_graph_test.rb +41 -0
  79. data/test/printers_test.rb +32 -166
  80. data/test/printing_recursive_graph_test.rb +26 -72
  81. data/test/recursive_test.rb +72 -77
  82. data/test/stack_printer_test.rb +2 -15
  83. data/test/start_stop_test.rb +22 -25
  84. data/test/test_helper.rb +5 -248
  85. data/test/thread_test.rb +11 -54
  86. data/test/unique_call_path_test.rb +16 -28
  87. data/test/yarv_test.rb +1 -0
  88. metadata +28 -36
  89. data/examples/flat.txt +0 -50
  90. data/examples/graph.dot +0 -84
  91. data/examples/graph.html +0 -823
  92. data/examples/graph.txt +0 -139
  93. data/examples/multi.flat.txt +0 -23
  94. data/examples/multi.graph.html +0 -760
  95. data/examples/multi.grind.dat +0 -114
  96. data/examples/multi.stack.html +0 -547
  97. data/examples/stack.html +0 -547
  98. data/ext/ruby_prof/rp_measure.c +0 -40
  99. data/ext/ruby_prof/rp_measure.h +0 -45
  100. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  101. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  102. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  103. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  104. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  105. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  106. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
  107. data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
  108. data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
  109. data/test/aggregate_test.rb +0 -136
  110. data/test/block_test.rb +0 -74
  111. data/test/call_info_test.rb +0 -78
  112. data/test/issue137_test.rb +0 -63
  113. data/test/measure_cpu_time_test.rb +0 -212
  114. data/test/measure_gc_runs_test.rb +0 -32
  115. data/test/measure_gc_time_test.rb +0 -36
  116. data/test/measure_memory_test.rb +0 -33
  117. data/test/method_elimination_test.rb +0 -84
  118. data/test/module_test.rb +0 -45
  119. data/test/stack_test.rb +0 -138
@@ -1,24 +1,22 @@
1
- # The call info visitor class does a depth-first traversal across a
2
- # list of method infos. At each call_info node, the visitor executes
3
- # the block provided in the #visit method. The block is passed two
4
- # parameters, the event and the call_info instance. Event will be
5
- # either :enter or :exit.
6
- #
7
- # visitor = RubyProf::CallInfoVisitor.new(result.threads.first.top_call_infos)
8
- #
9
- # method_names = Array.new
10
- #
11
- # visitor.visit do |call_info, event|
12
- # method_names << call_info.target.full_name if event == :enter
13
- # end
14
- #
15
- # puts method_names
16
-
17
1
  module RubyProf
2
+ # The call info visitor class does a depth-first traversal across a
3
+ # list of method infos. At each call_info node, the visitor executes
4
+ # the block provided in the #visit method. The block is passed two
5
+ # parameters, the event and the call_info instance. Event will be
6
+ # either :enter or :exit.
7
+ #
8
+ # visitor = RubyProf::CallInfoVisitor.new(result.threads.first.root_methods)
9
+ #
10
+ # method_names = Array.new
11
+ #
12
+ # visitor.visit do |call_info, event|
13
+ # method_names << call_info.target.full_name if event == :enter
14
+ # end
15
+ #
16
+ # puts method_names
18
17
  class CallInfoVisitor
19
-
20
- def initialize(call_infos)
21
- @call_infos = CallInfo.roots_of(call_infos)
18
+ def initialize(root_methods)
19
+ @call_infos = root_methods.map(&:callers).flatten
22
20
  end
23
21
 
24
22
  def visit(&block)
@@ -28,13 +26,13 @@ module RubyProf
28
26
  end
29
27
 
30
28
  private
29
+
31
30
  def visit_call_info(call_info, &block)
32
31
  yield call_info, :enter
33
- call_info.children.each do |child|
32
+ call_info.target.callees.each do |child|
34
33
  visit_call_info(child, &block)
35
34
  end
36
35
  yield call_info, :exit
37
36
  end
38
37
  end
39
-
40
38
  end
@@ -1,53 +1,16 @@
1
1
  # encoding: utf-8
2
2
 
3
- # These methods are here for backwards compatability with previous RubyProf releases
3
+ # These methods are deprecated and are available for backwards compatability.
4
4
  module RubyProf
5
- # Measurements
6
- def self.cpu_frequency
7
- Measure::CpuTime.frequency
8
- end
9
-
10
- def self.measure_allocations
11
- Measure::Allocations.measure
12
- end
13
-
14
- def self.measure_cpu_time
15
- Measure::CpuTime.measure
16
- end
17
-
18
- def self.measure_gc_runs
19
- Measure::GcRuns.measure
20
- end
21
-
22
- def self.measure_gc_time
23
- Measure::GcTime.measure
24
- end
25
-
26
- def self.measure_memory
27
- Measure::Memory.measure
28
- end
29
-
30
- def self.measure_process_time
31
- Measure::ProcessTime.measure
32
- end
33
-
34
- def self.measure_wall_time
35
- Measure::WallTime.measure
36
- end
37
-
38
5
  # call-seq:
39
6
  # measure_mode -> measure_mode
40
7
  #
41
8
  # Returns what ruby-prof is measuring. Valid values include:
42
9
  #
43
- # *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows. This is default.
44
- # *RubyProf::PROCESS_TIME - Measure process time. It is implemented using the clock functions in the C Runtime library.
45
- # *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
46
- # *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
47
- # *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
48
- # *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
49
- # *RubyProf::GC_TIME - Measure time spent doing garbage collection. This requires a patched Ruby interpreter.*/
50
-
10
+ # * RubyProf::WALL_TIME
11
+ # * RubyProf::PROCESS_TIME
12
+ # * RubyProf::ALLOCATIONS
13
+ # * RubyProf::MEMORY
51
14
  def self.measure_mode
52
15
  @measure_mode ||= RubyProf::WALL_TIME
53
16
  end
@@ -57,66 +20,38 @@ module RubyProf
57
20
  #
58
21
  # Specifies what ruby-prof should measure. Valid values include:
59
22
  #
60
- # *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows. This is default.
61
- # *RubyProf::PROCESS_TIME - Measure process time. It is implemented using the clock functions in the C Runtime library.
62
- # *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
63
- # *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
64
- # *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
65
- # *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
66
- # *RubyProf::GC_TIME - Measure time spent doing garbage collection. This requires a patched Ruby interpreter.*/
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.
67
27
  def self.measure_mode=(value)
68
28
  @measure_mode = value
69
29
  end
70
30
 
71
- def self.measure_mode_string
72
- case measure_mode
73
- when WALL_TIME then "wall_time"
74
- when CPU_TIME then "cpu_time"
75
- when PROCESS_TIME then "process_time_time"
76
- when ALLOCATIONS then "allocations"
77
- when MEMORY then "memory"
78
- when GC_TIME then "gc_time"
79
- when GC_RUNS then "gc_runs"
80
- end
81
- end
82
-
83
- # call-seq:
84
- # exclude_threads -> exclude_threads
85
- #
86
- # Returns threads ruby-prof should exclude from profiling
87
-
31
+ # Returns the threads that ruby-prof should exclude from profiling
88
32
  def self.exclude_threads
89
33
  @exclude_threads ||= Array.new
90
34
  end
91
35
 
92
- # call-seq:
93
- # exclude_threads= -> void
94
- #
95
- # Specifies what threads ruby-prof should exclude from profiling
96
-
36
+ # Specifies which threads ruby-prof should exclude from profiling
97
37
  def self.exclude_threads=(value)
98
38
  @exclude_threads = value
99
39
  end
100
40
 
101
- # Profiling
102
- def self.start_script(script)
103
- start
104
- load script
105
- end
106
-
41
+ # Starts profiling
107
42
  def self.start
108
43
  ensure_not_running!
109
- @profile = Profile.new(measure_mode: measure_mode, exclude_threads: exclude_threads)
110
- enable_gc_stats_if_needed
44
+ @profile = Profile.new(:measure_mode => measure_mode, :exclude_threads => exclude_threads)
111
45
  @profile.start
112
46
  end
113
47
 
48
+ # Pauses profiling
114
49
  def self.pause
115
50
  ensure_running!
116
- disable_gc_stats_if_needed
117
51
  @profile.pause
118
52
  end
119
53
 
54
+ # Is a profile running?
120
55
  def self.running?
121
56
  if defined?(@profile) and @profile
122
57
  @profile.running?
@@ -125,55 +60,50 @@ module RubyProf
125
60
  end
126
61
  end
127
62
 
63
+ # Resume profiling
128
64
  def self.resume
129
65
  ensure_running!
130
- enable_gc_stats_if_needed
131
66
  @profile.resume
132
67
  end
133
68
 
69
+ # Stops profiling
134
70
  def self.stop
135
71
  ensure_running!
136
72
  result = @profile.stop
137
- disable_gc_stats_if_needed
138
73
  @profile = nil
139
74
  result
140
75
  end
141
76
 
142
- # Profile a block
77
+ # Profiles a block
143
78
  def self.profile(options = {}, &block)
144
79
  ensure_not_running!
145
- gc_stat_was_enabled = enable_gc_stats_if_needed
146
- options = { measure_mode: measure_mode, exclude_threads: exclude_threads }.merge!(options)
147
- result = Profile.profile(options, &block)
148
- ensure
149
- disable_gc_stats_if_needed(gc_stat_was_enabled)
150
- result
80
+ options = {:measure_mode => measure_mode, :exclude_threads => exclude_threads }.merge!(options)
81
+ Profile.profile(options, &block)
151
82
  end
152
83
 
153
-
154
- private
155
- def self.ensure_running!
156
- raise(RuntimeError, "RubyProf.start was not yet called") unless running?
84
+ # :nodoc:
85
+ def self.measure_mode_string
86
+ case measure_mode
87
+ when WALL_TIME then "wall_time"
88
+ when PROCESS_TIME then "process_time"
89
+ when ALLOCATIONS then "allocations"
90
+ when MEMORY then "memory"
91
+ end
157
92
  end
158
93
 
159
- def self.ensure_not_running!
160
- raise(RuntimeError, "RubyProf is already running") if running?
94
+ # :nodoc:
95
+ def self.start_script(script)
96
+ start
97
+ load script
161
98
  end
162
99
 
163
- # for GC.allocated_size to work GC statistics should be enabled
164
- def self.enable_gc_stats_if_needed
165
- if measure_mode_requires_gc_stats_enabled?
166
- @gc_stat_was_enabled = GC.enable_stats
167
- end
168
- end
100
+ private
169
101
 
170
- def self.disable_gc_stats_if_needed(was_enabled=nil)
171
- was_enabled ||= defined?(@gc_stat_was_enabled) && @gc_stat_was_enabled
172
- GC.disable_stats if measure_mode_requires_gc_stats_enabled? && !was_enabled
102
+ def self.ensure_running!
103
+ raise(RuntimeError, "RubyProf.start was not yet called") unless running?
173
104
  end
174
105
 
175
- def self.measure_mode_requires_gc_stats_enabled?
176
- GC.respond_to?(:enable_stats) &&
177
- [RubyProf::MEMORY, RubyProf::GC_TIME, RubyProf::GC_RUNS].include?(measure_mode)
106
+ def self.ensure_not_running!
107
+ raise(RuntimeError, "RubyProf is already running") if running?
178
108
  end
179
109
  end
@@ -0,0 +1,198 @@
1
+ require 'set'
2
+
3
+ # :enddoc:
4
+ module RubyProf
5
+ module ExcludeCommonMethods
6
+ ENUMERABLE_NAMES = Enumerable.instance_methods(false)
7
+
8
+ def self.apply!(profile)
9
+ ##
10
+ # Kernel Methods
11
+ ##
12
+
13
+ exclude_methods(profile, Kernel, [
14
+ :dup,
15
+ :initialize_dup,
16
+ :tap,
17
+ :send,
18
+ :public_send,
19
+ ])
20
+
21
+ ##
22
+ # Fundamental Types
23
+ ##
24
+
25
+ exclude_methods(profile, BasicObject, :"!=")
26
+ exclude_methods(profile, Method, :"[]")
27
+ exclude_methods(profile, Module, :new)
28
+ exclude_methods(profile, Class, :new)
29
+ exclude_methods(profile, Proc, :call, :yield)
30
+ exclude_methods(profile, Range, :each)
31
+ exclude_methods(profile, Integer, :times)
32
+
33
+ ##
34
+ # Value Types
35
+ ##
36
+
37
+ exclude_methods(profile, String, [
38
+ :sub,
39
+ :sub!,
40
+ :gsub,
41
+ :gsub!,
42
+ ])
43
+
44
+ ##
45
+ # Emumerables
46
+ ##
47
+
48
+ exclude_enumerable(profile, Enumerable)
49
+ exclude_enumerable(profile, Enumerator)
50
+
51
+ ##
52
+ # Collections
53
+ ##
54
+
55
+ exclude_enumerable(profile, Array, [
56
+ :each_index,
57
+ :map!,
58
+ :select!,
59
+ :reject!,
60
+ :collect!,
61
+ :sort!,
62
+ :sort_by!,
63
+ :index,
64
+ :delete_if,
65
+ :keep_if,
66
+ :drop_while,
67
+ :uniq,
68
+ :uniq!,
69
+ :"==",
70
+ :eql?,
71
+ :hash,
72
+ :to_json,
73
+ :as_json,
74
+ :encode_json,
75
+ ])
76
+
77
+ exclude_enumerable(profile, Hash, [
78
+ :dup,
79
+ :initialize_dup,
80
+ :fetch,
81
+ :"[]",
82
+ :"[]=",
83
+ :each_key,
84
+ :each_value,
85
+ :each_pair,
86
+ :map!,
87
+ :select!,
88
+ :reject!,
89
+ :collect!,
90
+ :delete_if,
91
+ :keep_if,
92
+ :slice,
93
+ :slice!,
94
+ :except,
95
+ :except!,
96
+ :"==",
97
+ :eql?,
98
+ :hash,
99
+ :to_json,
100
+ :as_json,
101
+ :encode_json,
102
+ ])
103
+
104
+ exclude_enumerable(profile, Set, [
105
+ :map!,
106
+ :select!,
107
+ :reject!,
108
+ :collect!,
109
+ :classify,
110
+ :delete_if,
111
+ :keep_if,
112
+ :divide,
113
+ :"==",
114
+ :eql?,
115
+ :hash,
116
+ :to_json,
117
+ :as_json,
118
+ :encode_json,
119
+ ])
120
+
121
+ ##
122
+ # Garbage Collection
123
+ ##
124
+
125
+ exclude_singleton_methods(profile, GC, [
126
+ :start
127
+ ])
128
+
129
+ ##
130
+ # Unicorn
131
+ ##
132
+
133
+ if defined?(Unicorn)
134
+ exclude_methods(profile, Unicorn::HttpServer, :process_client)
135
+ end
136
+
137
+ if defined?(Unicorn::OobGC)
138
+ exclude_methods(profile, Unicorn::OobGC, :process_client)
139
+ end
140
+
141
+ ##
142
+ # New Relic
143
+ ##
144
+
145
+ if defined?(NewRelic::Agent)
146
+ if defined?(NewRelic::Agent::Instrumentation::MiddlewareTracing)
147
+ exclude_methods(profile, NewRelic::Agent::Instrumentation::MiddlewareTracing, [
148
+ :call
149
+ ])
150
+ end
151
+
152
+ if defined?(NewRelic::Agent::MethodTracerHelpers)
153
+ exclude_methods(profile, NewRelic::Agent::MethodTracerHelpers, [
154
+ :trace_execution_scoped,
155
+ :log_errors,
156
+ ])
157
+
158
+ exclude_singleton_methods(profile, NewRelic::Agent::MethodTracerHelpers, [
159
+ :trace_execution_scoped,
160
+ :log_errors,
161
+ ])
162
+ end
163
+
164
+ if defined?(NewRelic::Agent::MethodTracer)
165
+ exclude_methods(profile, NewRelic::Agent::MethodTracer, [
166
+ :trace_execution_scoped,
167
+ :trace_execution_unscoped,
168
+ ])
169
+ end
170
+ end
171
+
172
+ ##
173
+ # Miscellaneous Methods
174
+ ##
175
+
176
+ if defined?(Mustache)
177
+ exclude_methods(profile, Mustache::Context, [
178
+ :fetch
179
+ ])
180
+ end
181
+ end
182
+
183
+ private
184
+
185
+ def self.exclude_enumerable(profile, mod, *method_or_methods)
186
+ exclude_methods(profile, mod, [:each, *method_or_methods])
187
+ exclude_methods(profile, mod, ENUMERABLE_NAMES)
188
+ end
189
+
190
+ def self.exclude_methods(profile, mod, *method_or_methods)
191
+ profile.exclude_methods!(mod, method_or_methods)
192
+ end
193
+
194
+ def self.exclude_singleton_methods(profile, mod, *method_or_methods)
195
+ profile.exclude_singleton_methods!(mod, method_or_methods)
196
+ end
197
+ end
198
+ end