ruby-prof 1.4.4-x64-mingw-ucrt

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 (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
data/Rakefile ADDED
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+
3
+ require "rubygems/package_task"
4
+ require "rake/extensiontask"
5
+ require "rake/testtask"
6
+ require "rdoc/task"
7
+ require "date"
8
+ require "rake/clean"
9
+
10
+ # To release a version of ruby-prof:
11
+ # * Update lib/ruby-prof/version.rb
12
+ # * Update CHANGES
13
+ # * git commit to commit files
14
+ # * rake clobber to remove extra files
15
+ # * rake compile to build windows gems
16
+ # * rake package to create the gems
17
+ # * Tag the release (git tag 0.10.1)
18
+ # * Push to ruybgems.org (gem push pkg/<gem files>)
19
+
20
+ GEM_NAME = 'ruby-prof'
21
+ SO_NAME = 'ruby_prof'
22
+
23
+ default_spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
24
+
25
+ # specify which versions/builds to cross compile
26
+ Rake::ExtensionTask.new do |ext|
27
+ ext.gem_spec = default_spec
28
+ ext.name = SO_NAME
29
+ ext.ext_dir = "ext/#{SO_NAME}"
30
+ ext.lib_dir = "lib/#{Gem::Version.new(RUBY_VERSION).segments[0..1].join('.')}"
31
+ ext.cross_compile = true
32
+ ext.cross_platform = ['x64-mingw32']
33
+ end
34
+
35
+ # Rake task to build the default package
36
+ Gem::PackageTask.new(default_spec) do |pkg|
37
+ pkg.need_tar = true
38
+ end
39
+
40
+ # make sure rdoc has been built when packaging
41
+ # why do we ship rdoc as part of the gem?
42
+ Rake::Task[:package].enhance [:rdoc]
43
+
44
+ # Setup Windows Gem
45
+ if RUBY_PLATFORM.match(/mswin|mingw/)
46
+ # Windows specification
47
+ win_spec = default_spec.clone
48
+ win_spec.platform = Gem::Platform::CURRENT
49
+ win_spec.files += Dir.glob('lib/**/*.so')
50
+
51
+ # Unset extensions
52
+ win_spec.extensions = nil
53
+
54
+ # Rake task to build the windows package
55
+ Gem::PackageTask.new(win_spec) do |pkg|
56
+ pkg.need_tar = false
57
+ end
58
+ end
59
+
60
+ # --------- RDoc Documentation ------
61
+ desc "Generate rdoc documentation"
62
+ RDoc::Task.new("rdoc") do |rdoc|
63
+ rdoc.rdoc_dir = 'doc'
64
+ rdoc.title = "ruby-prof"
65
+ # Show source inline with line numbers
66
+ rdoc.options << "--line-numbers"
67
+ # Make the readme file the start page for the generated html
68
+ rdoc.options << '--main' << 'README.md'
69
+ rdoc.rdoc_files.include('bin/*',
70
+ 'doc/*.rdoc',
71
+ 'lib/**/*.rb',
72
+ 'ext/ruby_prof/*.c',
73
+ 'ext/ruby_prof/*.h',
74
+ 'README.md',
75
+ 'LICENSE')
76
+ end
77
+
78
+ task :default => :test
79
+
80
+ for file in Dir['lib/**/*.{o,so,bundle}']
81
+ CLEAN.include file
82
+ end
83
+ for file in Dir['doc/**/*.{txt,dat,png,html}']
84
+ CLEAN.include file
85
+ end
86
+ CLEAN.reject!{|f| !File.exist?(f)}
87
+ task :clean do
88
+ # remove tmp dir contents completely after cleaning
89
+ FileUtils.rm_rf('tmp/*')
90
+ end
91
+
92
+ desc 'Run the ruby-prof test suite'
93
+ Rake::TestTask.new do |t|
94
+ t.libs += %w(lib ext test)
95
+ t.test_files = Dir['test/**_test.rb']
96
+ t.verbose = true
97
+ t.warning = true
98
+ end
data/bin/ruby-prof ADDED
@@ -0,0 +1,328 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ # First require ruby-prof
4
+ require 'ruby-prof'
5
+
6
+ # Now setup option parser
7
+ require 'ostruct'
8
+ require 'optparse'
9
+
10
+ module RubyProf
11
+ # == Synopsis
12
+ #
13
+ # Profiles a Ruby program.
14
+ #
15
+ # == Usage
16
+ # ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]
17
+ #
18
+ # Options:
19
+ # -p, --printer=printer Select a printer:
20
+ # flat - Prints a flat profile as text (default).
21
+ # graph - Prints a graph profile as text.
22
+ # graph_html - Prints a graph profile as html.
23
+ # call_tree - format for KCacheGrind
24
+ # call_stack - prints a HTML visualization of the call tree
25
+ # dot - Prints a graph profile as a dot file
26
+ # multi - Creates several reports in output directory
27
+ # -m, --min_percent=min_percent The minimum percent a method must take before
28
+ # being included in output reports.
29
+ # This option is not supported for call tree.
30
+ # -f, --file=path Output results to a file instead of standard out.
31
+ # --mode=measure_mode Select what ruby-prof should measure:
32
+ # wall - Wall time (default).
33
+ # process - Process time.
34
+ # allocations - Object allocations (requires patched Ruby interpreter).
35
+ # memory - Allocated memory in KB (requires patched Ruby interpreter).
36
+ # -s, --sort=sort_mode Select how ruby-prof results should be sorted:
37
+ # total - Total time
38
+ # self - Self time
39
+ # wait - Wait time
40
+ # child - Child time
41
+ # --allow_exceptions Raise exceptions encountered during profiling (true) or suppress them (false)
42
+ # -R, --require-noprof=lib require a specific library (not profiled)
43
+ # -E, --eval-noprof=code execute the ruby statements (not profiled)
44
+ # --exclude=methods A comma separated list of methods to exclude.
45
+ # Specify instance methods via # (Integer#times)
46
+ # Specify class methods via . (Integer.superclass)
47
+ # --exclude-common Remove common methods from the profile
48
+ # -h, --help Show help message
49
+ # -v, --version version Show version (1.1.0)
50
+
51
+ class Cmd
52
+ # :enddoc:
53
+ attr_accessor :options
54
+ attr_reader :profile
55
+
56
+ def initialize
57
+ setup_options
58
+ parse_args
59
+
60
+ load_pre_libs
61
+ load_pre_execs
62
+ end
63
+
64
+ def setup_options
65
+ @options = OpenStruct.new
66
+ options.printer = RubyProf::FlatPrinter
67
+ options.measure_mode = RubyProf::WALL_TIME
68
+ options.min_percent = 0
69
+ options.file = nil
70
+ options.allow_exceptions = false
71
+ options.exclude_common = false
72
+ options.exclude = Array.new
73
+ options.pre_libs = Array.new
74
+ options.pre_execs = Array.new
75
+ end
76
+
77
+ # This is copied from ActiveSupport:
78
+ def constantize(camel_cased_word)
79
+ if !camel_cased_word.include?("::")
80
+ Object.const_get(camel_cased_word)
81
+ else
82
+ names = camel_cased_word.split("::")
83
+
84
+ # Trigger a built-in NameError exception including the ill-formed constant in the message.
85
+ Object.const_get(camel_cased_word) if names.empty?
86
+
87
+ # Remove the first blank element in case of '::ClassName' notation.
88
+ names.shift if names.size > 1 && names.first.empty?
89
+
90
+ names.inject(Object) do |constant, name|
91
+ if constant == Object
92
+ constant.const_get(name)
93
+ else
94
+ candidate = constant.const_get(name)
95
+ next candidate if constant.const_defined?(name, false)
96
+ next candidate unless Object.const_defined?(name)
97
+
98
+ # Go down the ancestors to check if it is owned directly. The check
99
+ # stops when we reach Object or the end of ancestors tree.
100
+ constant = constant.ancestors.inject(constant) do |const, ancestor|
101
+ break const if ancestor == Object
102
+ break ancestor if ancestor.const_defined?(name, false)
103
+ const
104
+ end
105
+
106
+ # owner is in Object, so raise
107
+ constant.const_get(name, false)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ def option_parser
114
+ OptionParser.new do |opts|
115
+ opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
116
+ "Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
117
+
118
+ opts.separator ""
119
+ opts.separator "Options:"
120
+
121
+ opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot, :multi],
122
+ 'Select a printer:',
123
+ ' flat - Prints a flat profile as text (default).',
124
+ ' graph - Prints a graph profile as text.',
125
+ ' graph_html - Prints a graph profile as html.',
126
+ ' call_tree - format for KCacheGrind',
127
+ ' call_stack - prints a HTML visualization of the call tree',
128
+ ' dot - Prints a graph profile as a dot file',
129
+ ' multi - Creates several reports in output directory'
130
+ ) do |printer|
131
+
132
+ case printer
133
+ when :flat
134
+ options.printer = RubyProf::FlatPrinter
135
+ when :graph
136
+ options.printer = RubyProf::GraphPrinter
137
+ when :graph_html
138
+ options.printer = RubyProf::GraphHtmlPrinter
139
+ when :call_tree
140
+ options.printer = RubyProf::CallTreePrinter
141
+ when :call_stack
142
+ options.printer = RubyProf::CallStackPrinter
143
+ when :dot
144
+ options.printer = RubyProf::DotPrinter
145
+ when :multi
146
+ options.printer = RubyProf::MultiPrinter
147
+ end
148
+ end
149
+
150
+ opts.on('-m min_percent', '--min_percent=min_percent', Float,
151
+ 'The minimum percent a method must take before ',
152
+ ' being included in output reports.',
153
+ ' This option is not supported for call tree.') do |min_percent|
154
+ options.min_percent = min_percent
155
+ end
156
+
157
+ opts.on('-f path', '--file=path',
158
+ 'Output results to a file instead of standard out.') do |file|
159
+ options.file = file
160
+ options.old_wd = Dir.pwd
161
+ end
162
+
163
+ opts.on('--mode=measure_mode',
164
+ [:process, :wall, :allocations, :memory],
165
+ 'Select what ruby-prof should measure:',
166
+ ' wall - Wall time (default).',
167
+ ' process - Process time.',
168
+ ' allocations - Object allocations (requires patched Ruby interpreter).',
169
+ ' memory - Allocated memory in KB (requires patched Ruby interpreter).') do |measure_mode|
170
+
171
+ case measure_mode
172
+ when :wall
173
+ options.measure_mode = RubyProf::WALL_TIME
174
+ when :process
175
+ options.measure_mode = RubyProf::PROCESS_TIME
176
+ when :allocations
177
+ options.measure_mode = RubyProf::ALLOCATIONS
178
+ when :memory
179
+ options.measure_mode = RubyProf::MEMORY
180
+ end
181
+ end
182
+
183
+ opts.on('-s sort_mode', '--sort=sort_mode', [:total, :self, :wait, :child],
184
+ 'Select how ruby-prof results should be sorted:',
185
+ ' total - Total time',
186
+ ' self - Self time',
187
+ ' wait - Wait time',
188
+ ' child - Child time') do |sort_mode|
189
+
190
+ options.sort_method = case sort_mode
191
+ when :total
192
+ :total_time
193
+ when :self
194
+ :self_time
195
+ when :wait
196
+ :wait_time
197
+ when :child
198
+ :children_time
199
+ end
200
+ end
201
+
202
+ opts.on_tail("-h", "--help", "Show help message") do
203
+ puts opts
204
+ exit
205
+ end
206
+
207
+ opts.on_tail("-v version", "--version", "Show version (#{RubyProf::VERSION})") do
208
+ puts "ruby_prof " + RubyProf::VERSION
209
+ exit
210
+ end
211
+
212
+ opts.on('--allow_exceptions', 'Raise exceptions encountered during profiling (true) or suppress them (false)') do
213
+ options.allow_exceptions = true
214
+ end
215
+
216
+ opts.on('-R lib', '--require-noprof=lib', 'require a specific library (not profiled)') do |lib|
217
+ options.pre_libs << lib
218
+ end
219
+
220
+ opts.on('-E code', '--eval-noprof=code', 'execute the ruby statements (not profiled)') do |code|
221
+ options.pre_execs << code
222
+ end
223
+
224
+ opts.on('--exclude=methods', String,
225
+ 'A comma separated list of methods to exclude.',
226
+ ' Specify instance methods via # (Integer#times)',
227
+ ' Specify class methods via . (Integer.superclass)') do |exclude_string|
228
+ exclude_string.split(',').each do |string|
229
+ match = string.strip.match(/(.*)(#|\.)(.*)/)
230
+ klass = constantize(match[1])
231
+ if match[2] == '.'
232
+ klass = klass.singleton_class
233
+ end
234
+ method = match[3].to_sym
235
+ options.exclude << [klass, method]
236
+ end
237
+ end
238
+
239
+ opts.on('--exclude-common', 'Remove common methods from the profile') do
240
+ options.exclude_common = true
241
+ end
242
+ end
243
+ end
244
+
245
+ def parse_args
246
+ # Make sure the user specified at least one file
247
+ if ARGV.length < 1 and not options.exec
248
+ puts self.option_parser
249
+ puts ""
250
+ puts "Must specify a script to run"
251
+ exit(-1)
252
+ end
253
+
254
+ self.option_parser.parse! ARGV
255
+
256
+ if options.printer.needs_dir?
257
+ options.file ||= "."
258
+ options.old_wd ||= Dir.pwd
259
+ if !File.directory?(options.file)
260
+ puts "'#{options.file}' is not a directory"
261
+ puts "#{options.printer} needs an existing directory path to put profiles under."
262
+ exit(-1)
263
+ end
264
+ end
265
+ rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
266
+ puts self.option_parser
267
+ puts e.message
268
+ exit(-1)
269
+ end
270
+
271
+ def load_pre_libs
272
+ options.pre_libs.each do |lib|
273
+ require lib
274
+ end
275
+ end
276
+
277
+ def load_pre_execs
278
+ options.pre_execs.each do |exec|
279
+ eval(exec)
280
+ end
281
+ end
282
+
283
+ def run
284
+ script = ARGV.shift
285
+ @profile = Profile.new(options.to_h)
286
+ options.exclude.each do |klass, method|
287
+ @profile.exclude_method!(klass, method)
288
+ end
289
+
290
+ profile.profile do
291
+ load script
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+ # Parse command line options
298
+ cmd = RubyProf::Cmd.new
299
+
300
+ # Install at_exit handler. It is important that we do this
301
+ # before loading the scripts so our at_exit handler run
302
+ # *after* any other one that will be installed.
303
+
304
+ at_exit {
305
+ # Create a printer
306
+ printer = cmd.options.printer.new(cmd.profile)
307
+ printer_options = {:min_percent => cmd.options.min_percent, :sort_method => cmd.options.sort_method}
308
+
309
+ # Get output
310
+ if cmd.options.file
311
+ # write it relative to the dir they *started* in, as it's a bit surprising to write it in the dir they end up in.
312
+ Dir.chdir(cmd.options.old_wd) do
313
+ if printer.class.needs_dir?
314
+ printer.print(printer_options.merge(:path => cmd.options.file))
315
+ else
316
+ File.open(cmd.options.file, 'w') do |file|
317
+ printer.print(file, printer_options)
318
+ end
319
+ end
320
+ end
321
+ else
322
+ # Print out results
323
+ printer.print(STDOUT, printer_options)
324
+ end
325
+ }
326
+
327
+ # Now profile some code
328
+ cmd.run
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ stacks = Hash.new{|h,k| h[k] = Hash.new{|h,k| h[k] = []}}
4
+ i = 0
5
+ File.open(ARGV[0]).each_line do |l|
6
+ i += 1
7
+ unless l =~ /^(\d+):(\d+): *\d+ms *([^ ]+) *(.*): *(\d+) *(.+)$/
8
+ next if l =~/^ *$/
9
+ puts "line doesn't match: #{l}"
10
+ next
11
+ end
12
+ details = $1.to_i, $2.to_i, $3, $4, $5.to_i, $6
13
+ thread, fiber, event, file, line, method = *details
14
+ # puts method
15
+ stack = stacks[thread][fiber]
16
+ case event
17
+ when 'call', 'c-call'
18
+ stack << method
19
+ when 'return', 'c-return'
20
+ last_method = stack.pop
21
+ if last_method != method
22
+ puts "LINE #{i}: return event without call: #{method}"
23
+ puts "STACK: #{stack.inspect}"
24
+ if stack.find(method)
25
+ puts "fixing stack"
26
+ while (popped = stack.pop) && (popped != method)
27
+ puts "popped #{popped}"
28
+ end
29
+ else
30
+ raise "stack unfixable"
31
+ end
32
+ # stack << last_method
33
+ end
34
+ when 'line'
35
+ last_method = stack[-1]
36
+ if last_method != method
37
+ unless stack.find(method)
38
+ raise "LINE #{i}: line event without call: #{method}"
39
+ end
40
+ end
41
+ else
42
+ puts "unkown event"
43
+ end
44
+ end
45
+ puts stacks.inspect
@@ -0,0 +1,22 @@
1
+ require "mkmf"
2
+
3
+ # Let's go with a modern version of C! want to intermix declarations and code (ie, don't define
4
+ # all variables at the top of the method). If using Visual Studio, you'll need 2019 version
5
+ # 16.8 or higher
6
+ if RUBY_PLATFORM =~ /mswin/
7
+ $CFLAGS += ' /std:c11'
8
+ else
9
+ $CFLAGS += ' -std=c11'
10
+ end
11
+
12
+ # For gcc add -s to strip symbols, reducing library size from 17MB to 78KB (at least on Windows with mingw64)
13
+ if RUBY_PLATFORM !~ /mswin/
14
+ $LDFLAGS += ' -s'
15
+ end
16
+
17
+ # And since we are using C99 we want to disable Ruby sending these warnings to gcc
18
+ if CONFIG['warnflags']
19
+ CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
20
+ end
21
+
22
+ create_makefile("ruby_prof")
@@ -0,0 +1,59 @@
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_aggregate_call_tree.h"
5
+
6
+ VALUE cRpAggregateCallTree;
7
+
8
+ void prof_aggregate_call_tree_mark(void* data)
9
+ {
10
+ prof_call_tree_t* call_tree = (prof_call_tree_t*)data;
11
+
12
+ if (call_tree->object != Qnil)
13
+ rb_gc_mark(call_tree->object);
14
+
15
+ if (call_tree->source_file != Qnil)
16
+ rb_gc_mark(call_tree->source_file);
17
+
18
+ prof_measurement_mark(call_tree->measurement);
19
+ }
20
+
21
+ static void prof_aggregate_call_tree_ruby_gc_free(void* data)
22
+ {
23
+ prof_call_tree_t* call_tree = (prof_call_tree_t*)data;
24
+ prof_call_tree_free(call_tree);
25
+ }
26
+
27
+ size_t prof_aggregate_call_tree_size(const void* data)
28
+ {
29
+ return sizeof(prof_call_tree_t);
30
+ }
31
+
32
+ static const rb_data_type_t aggregate_call_tree_type =
33
+ {
34
+ .wrap_struct_name = "Aggregate_CallTree",
35
+ .function =
36
+ {
37
+ .dmark = prof_aggregate_call_tree_mark,
38
+ .dfree = prof_aggregate_call_tree_ruby_gc_free,
39
+ .dsize = prof_aggregate_call_tree_size,
40
+ },
41
+ .data = NULL,
42
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
43
+ };
44
+
45
+ VALUE prof_aggregate_call_tree_wrap(prof_call_tree_t* call_tree)
46
+ {
47
+ if (call_tree->object == Qnil)
48
+ {
49
+ call_tree->object = TypedData_Wrap_Struct(cRpAggregateCallTree, &aggregate_call_tree_type, call_tree);
50
+ }
51
+ return call_tree->object;
52
+ }
53
+
54
+ void rp_init_aggregate_call_tree()
55
+ {
56
+ // AggregateCallTree
57
+ cRpAggregateCallTree = rb_define_class_under(mProf, "AggregateCallTree", cRpCallTree);
58
+ rb_undef_method(CLASS_OF(cRpAggregateCallTree), "new");
59
+ }
@@ -0,0 +1,13 @@
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_AGGREGATE_CALL_TREE_H__
5
+ #define __RP_AGGREGATE_CALL_TREE_H__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_call_tree.h"
9
+
10
+ void rp_init_aggregate_call_tree(void);
11
+ VALUE prof_aggregate_call_tree_wrap(prof_call_tree_t* call_tree);
12
+
13
+ #endif //__RP_AGGREGATE_CALL_TREE_H__