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
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__