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

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 (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
data/Rakefile CHANGED
@@ -40,7 +40,7 @@ Rake::ExtensionTask.new do |ext|
40
40
  ext.ext_dir = "ext/#{SO_NAME}"
41
41
  ext.lib_dir = "lib/#{RUBY_VERSION}"
42
42
  ext.cross_compile = true
43
- ext.cross_platform = ['x86-mswin32-60', 'x86-mingw32-60']
43
+ ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
44
44
  end
45
45
 
46
46
  # Rake task to build the default package
@@ -80,12 +80,9 @@ RDoc::Task.new("rdoc") do |rdoc|
80
80
  rdoc.options << '--main' << 'README.rdoc'
81
81
  rdoc.rdoc_files.include('bin/*',
82
82
  'doc/*.rdoc',
83
- 'examples/flat.txt',
84
- 'examples/graph.txt',
85
- 'examples/graph.html',
86
83
  'lib/**/*.rb',
87
- 'ext/ruby_prof/ruby_prof.c',
88
- 'ext/ruby_prof/measure_*.h',
84
+ 'ext/ruby_prof/*.c',
85
+ 'ext/ruby_prof/*.h',
89
86
  'README.rdoc',
90
87
  'LICENSE')
91
88
  end
data/bin/ruby-prof CHANGED
@@ -1,18 +1,5 @@
1
1
  #! /usr/bin/env ruby
2
2
 
3
- # == Synopsis
4
- #
5
- # Profiles a Ruby program.
6
- #
7
- # == Usage
8
- #
9
- # ruby_prof [options] <script.rb> [--] [script-options]"
10
- #
11
- # Various options:
12
- # run "$ ruby-prof --help" to see them
13
- #
14
- # See also the readme "reports" section for the various outputs
15
-
16
3
  # First require ruby-prof
17
4
  require 'rubygems'
18
5
  require 'ruby-prof'
@@ -22,7 +9,68 @@ require 'ostruct'
22
9
  require 'optparse'
23
10
 
24
11
  module RubyProf
12
+ # == Synopsis
13
+ #
14
+ # Profiles a Ruby program.
15
+ #
16
+ # == Usage
17
+ #
18
+ # ruby_prof [options] <script.rb> [--] [script-options]
19
+ #
20
+ # Options:
21
+ # -p, --printer=printer Select a printer:
22
+ # flat - Prints a flat profile as text (default).
23
+ # graph - Prints a graph profile as text.
24
+ # graph_html - Prints a graph profile as html.
25
+ # call_tree - format for KCacheGrind
26
+ # call_stack - prints a HTML visualization of the call tree
27
+ # dot - Prints a graph profile as a dot file
28
+ # multi - Creates several reports in output directory
29
+ #
30
+ # -m, --min_percent=min_percent The minimum percent a method must take before
31
+ # being included in output reports. This option is not supported for call tree reports.
32
+ #
33
+ # -f, --file=path Output results to a file instead of standard out.
34
+ #
35
+ # --mode=measure_mode Select what ruby-prof should measure:
36
+ # wall - Wall time (default)
37
+ # process - Process time
38
+ # allocations - Object allocations
39
+ # memory - Allocated memory
40
+ #
41
+ # -s, --sort=sort_mode Select how ruby-prof results should be sorted:
42
+ # total - Total time
43
+ # self - Self time
44
+ # wait - Wait time
45
+ # child - Child time
46
+ #
47
+ # --replace-progname Replace $0 when loading the .rb files.
48
+ #
49
+ # --specialized-instruction Turn on specified instruction.
50
+ #
51
+ # -v Show version, set $VERBOSE to true, profile script if option given
52
+ #
53
+ # -d Set $DEBUG to true
54
+ #
55
+ # -R, --require-noprof lib Require a specific library (not profiled)
56
+ #
57
+ # -E, --eval-noprof code Execute the ruby statements (not profiled)
58
+ #
59
+ # -x, --exclude regexp Exclude methods by regexp (see method elimination)
60
+ #
61
+ # -X, --exclude-file file Exclude methods by regexp listed in file (see method elimination)
62
+ #
63
+ # --exclude-common-cycles Make common iterators like Integer#times appear inlined
64
+ #
65
+ # --exclude-common-callbacks Make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph
66
+ #
67
+ # -h, --help Show help message
68
+ #
69
+ # --version Show version
70
+ #
71
+ #
25
72
  class Cmd
73
+ # :enddoc:
26
74
  attr_accessor :options
27
75
 
28
76
  def initialize
@@ -56,7 +104,6 @@ module RubyProf
56
104
  opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot, :multi],
57
105
  'Select a printer:',
58
106
  ' flat - Prints a flat profile as text (default).',
59
- ' flat_with_line_numbers - same as flat, with line numbers.',
60
107
  ' graph - Prints a graph profile as text.',
61
108
  ' graph_html - Prints a graph profile as html.',
62
109
  ' call_tree - format for KCacheGrind',
@@ -65,12 +112,9 @@ module RubyProf
65
112
  ' multi - Creates several reports in output directory'
66
113
  ) do |printer|
67
114
 
68
-
69
115
  case printer
70
116
  when :flat
71
117
  options.printer = RubyProf::FlatPrinter
72
- when :flat_with_line_numbers
73
- options.printer = RubyProf::FlatPrinterWithLineNumbers
74
118
  when :graph
75
119
  options.printer = RubyProf::GraphPrinter
76
120
  when :graph_html
@@ -89,7 +133,7 @@ module RubyProf
89
133
  opts.on('-m min_percent', '--min_percent=min_percent', Float,
90
134
  'The minimum percent a method must take before ',
91
135
  ' being included in output reports.',
92
- ' this option is not supported for call tree.') do |min_percent|
136
+ ' This option is not supported for call tree.') do |min_percent|
93
137
  options.min_percent = min_percent
94
138
  end
95
139
 
@@ -100,31 +144,22 @@ module RubyProf
100
144
  end
101
145
 
102
146
  opts.on('--mode=measure_mode',
103
- [:process, :wall, :cpu, :allocations, :memory, :gc_runs, :gc_time],
147
+ [:process, :wall, :allocations, :memory],
104
148
  'Select what ruby-prof should measure:',
105
149
  ' wall - Wall time (default).',
106
150
  ' process - Process time.',
107
- ' cpu - CPU time (Pentium and PowerPCs only).',
108
151
  ' allocations - Object allocations (requires patched Ruby interpreter).',
109
- ' memory - Allocated memory in KB (requires patched Ruby interpreter).',
110
- ' gc_runs - Number of garbage collections (requires patched Ruby interpreter).',
111
- ' gc_time - Time spent in garbage collection (requires patched Ruby interpreter).') do |measure_mode|
152
+ ' memory - Allocated memory in KB (requires patched Ruby interpreter).') do |measure_mode|
112
153
 
113
154
  case measure_mode
114
155
  when :wall
115
156
  options.measure_mode = RubyProf::WALL_TIME
116
157
  when :process
117
158
  options.measure_mode = RubyProf::PROCESS_TIME
118
- when :cpu
119
- options.measure_mode = RubyProf::CPU_TIME
120
159
  when :allocations
121
160
  options.measure_mode = RubyProf::ALLOCATIONS
122
161
  when :memory
123
162
  options.measure_mode = RubyProf::MEMORY
124
- when :gc_runs
125
- options.measure_mode = RubyProf::GC_RUNS
126
- when :gc_time
127
- options.measure_mode = RubyProf::GC_TIME
128
163
  end
129
164
  end
130
165
 
@@ -184,7 +219,7 @@ module RubyProf
184
219
  options.pre_execs << code
185
220
  end
186
221
 
187
- opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do|meth|
222
+ opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do |meth|
188
223
  options.eliminate_methods ||= []
189
224
  options.eliminate_methods << Regexp.new(meth)
190
225
  end
@@ -5,34 +5,16 @@ if RUBY_ENGINE != "ruby"
5
5
  exit(1)
6
6
  end
7
7
 
8
- if RUBY_VERSION < "1.9.3"
9
- STDERR.puts("\n\n***** Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to 1.9.3 or higher. *****\n\n")
8
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4.0')
9
+ STDERR.puts("\n\n***** Ruby version #{RUBY_VERSION} is no longer supported. Please upgrade to 2.3 or higher. *****\n\n")
10
10
  exit(1)
11
11
  end
12
12
 
13
13
  # For the love of bitfields...
14
14
  $CFLAGS += ' -std=c99'
15
15
 
16
- # standard ruby methods
17
- have_func("rb_gc_stat")
18
- have_func("rb_gc_count")
19
- have_func("rb_remove_event_hook_with_data")
20
-
21
- # Alexander Dymo GC patch
22
- have_func("rb_os_allocated_objects")
23
- have_func("rb_gc_allocated_size")
24
-
25
- # Stefan Kaes GC patches
26
- have_func("rb_gc_collections")
27
- have_func("rb_gc_time")
28
- # for ruby 2.1
29
- have_func("rb_gc_total_time")
30
- have_func("rb_gc_total_mallocs")
31
- have_func("rb_gc_total_malloced_bytes")
32
-
33
- # Lloyd Hilaiel's heap info patch
34
- have_func("rb_heap_total_mem")
35
- have_func("rb_gc_heap_info")
16
+ # And since we are using C99
17
+ CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
36
18
 
37
19
  def add_define(name, value = nil)
38
20
  if value
@@ -46,23 +28,9 @@ def windows?
46
28
  RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
47
29
  end
48
30
 
49
- if !windows? && RUBY_PLATFORM !~ /(darwin|openbsd)/
50
- $LDFLAGS += " -lrt" # for clock_gettime
51
- end
52
31
  add_define("RUBY_PROF_RUBY_VERSION", RUBY_VERSION.split('.')[0..2].inject(0){|v,d| v*100+d.to_i})
53
32
 
54
- # for ruby 1.9, determine whether threads inherit trace flags (latest 1.9.2 and later should work correctly)
55
- if RUBY_VERSION > "1.9"
56
- require 'set'
57
- threads = Set.new
58
- set_trace_func lambda { |*args| threads << Thread.current.object_id }
59
- Thread.new{1}.join
60
- set_trace_func nil
61
- if threads.size < 2
62
- # if we end up here, ruby does not automatically activate tracing in spawned threads
63
- STDERR.puts("Ruby #{RUBY_VERSION} does not activate tracing in spawned threads. Consider upgrading.")
64
- exit(1)
65
- end
66
- end
33
+ # This function was added in Ruby 2.5, so once Ruby 2.4 is no longer supported this can be removed
34
+ have_func('rb_tracearg_callee_id', ["ruby.h"])
67
35
 
68
36
  create_makefile("ruby_prof")
@@ -0,0 +1,279 @@
1
+ /* Copyright (C) 2005-2013 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_allocation.h"
5
+
6
+ VALUE cRpAllocation;
7
+
8
+ prof_allocation_t*
9
+ allocations_table_lookup(st_table *table, st_data_t key)
10
+ {
11
+ prof_allocation_t* result = NULL;
12
+ st_data_t value;
13
+ if (st_lookup(table, key, &value))
14
+ {
15
+ result = (prof_allocation_t*)value;
16
+ }
17
+
18
+ return result;
19
+ }
20
+
21
+ void
22
+ allocations_table_insert(st_table *table, st_data_t key, prof_allocation_t * allocation)
23
+ {
24
+ st_insert(table, (st_data_t)key, (st_data_t)allocation);
25
+ }
26
+
27
+ st_data_t
28
+ allocations_key(VALUE klass, int source_line)
29
+ {
30
+ return (klass << 4) + source_line;
31
+ }
32
+
33
+ /* ====== prof_allocation_t ====== */
34
+ prof_allocation_t*
35
+ prof_allocation_create(void)
36
+ {
37
+ prof_allocation_t *result = ALLOC(prof_allocation_t);
38
+ result->count = 0;
39
+ result->klass = Qnil;
40
+ result->klass_name = Qnil;
41
+ result->object = Qnil;
42
+ result->memory = 0;
43
+ result->source_line = 0;
44
+ result->source_file = Qnil;
45
+ result->key = 0;
46
+
47
+ return result;
48
+ }
49
+
50
+ prof_allocation_t*
51
+ prof_allocate_increment(prof_method_t* method, rb_trace_arg_t* trace_arg)
52
+ {
53
+ VALUE object = rb_tracearg_object(trace_arg);
54
+ if (BUILTIN_TYPE(object) == T_IMEMO)
55
+ return NULL;
56
+
57
+ VALUE klass = rb_obj_class(object);
58
+
59
+ int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
60
+ st_data_t key = allocations_key(klass, source_line);
61
+
62
+ prof_allocation_t* allocation = allocations_table_lookup(method->allocations_table, key);
63
+ if (!allocation)
64
+ {
65
+ allocation = prof_allocation_create();
66
+ allocation->source_line = source_line;
67
+ allocation->source_file = rb_tracearg_path(trace_arg);
68
+ allocation->klass_flags = 0;
69
+ allocation->klass = resolve_klass(klass, &allocation->klass_flags);
70
+
71
+ allocation->key = key;
72
+ allocations_table_insert(method->allocations_table, key, allocation);
73
+ }
74
+
75
+ allocation->count++;
76
+ allocation->memory += rb_obj_memsize_of(object);
77
+
78
+ return allocation;
79
+ }
80
+
81
+ static void
82
+ prof_allocation_ruby_gc_free(void *data)
83
+ {
84
+ prof_allocation_t* allocation = (prof_allocation_t*)data;
85
+
86
+ /* Has this allocation object been accessed by Ruby? If
87
+ yes clean it up so to avoid a segmentation fault. */
88
+ if (allocation->object != Qnil)
89
+ {
90
+ RDATA(allocation->object)->dmark = NULL;
91
+ RDATA(allocation->object)->dfree = NULL;
92
+ RDATA(allocation->object)->data = NULL;
93
+ allocation->object = Qnil;
94
+ }
95
+ }
96
+
97
+ void
98
+ prof_allocation_free(prof_allocation_t* allocation)
99
+ {
100
+ prof_allocation_ruby_gc_free(allocation);
101
+ xfree(allocation);
102
+ }
103
+
104
+ size_t
105
+ prof_allocation_size(const void* data)
106
+ {
107
+ return sizeof(prof_allocation_t);
108
+ }
109
+
110
+ void
111
+ prof_allocation_mark(void *data)
112
+ {
113
+ prof_allocation_t* allocation = (prof_allocation_t*)data;
114
+ if (allocation->klass != Qnil)
115
+ rb_gc_mark(allocation->klass);
116
+
117
+ if (allocation->klass_name != Qnil)
118
+ rb_gc_mark(allocation->klass_name);
119
+
120
+ if (allocation->object != Qnil)
121
+ rb_gc_mark(allocation->object);
122
+
123
+ if (allocation->source_file != Qnil)
124
+ rb_gc_mark(allocation->source_file);
125
+ }
126
+
127
+ VALUE
128
+ prof_allocation_wrap(prof_allocation_t *allocation)
129
+ {
130
+ if (allocation->object == Qnil)
131
+ {
132
+ allocation->object = Data_Wrap_Struct(cRpAllocation, prof_allocation_mark , prof_allocation_ruby_gc_free, allocation);
133
+ }
134
+ return allocation->object;
135
+ }
136
+
137
+ static VALUE
138
+ prof_allocation_allocate(VALUE klass)
139
+ {
140
+ prof_allocation_t* allocation = prof_allocation_create();
141
+ allocation->object = prof_allocation_wrap(allocation);
142
+ return allocation->object;
143
+ }
144
+
145
+ prof_allocation_t*
146
+ prof_allocation_get(VALUE self)
147
+ {
148
+ /* Can't use Data_Get_Struct because that triggers the event hook
149
+ ending up in endless recursion. */
150
+ prof_allocation_t* result = DATA_PTR(self);
151
+ if (!result)
152
+ rb_raise(rb_eRuntimeError, "This RubyProf::Allocation instance has already been freed, likely because its profile has been freed.");
153
+
154
+ return result;
155
+ }
156
+
157
+ /* call-seq:
158
+ klass -> Class
159
+
160
+ Returns the type of Class being allocated. */
161
+ static VALUE
162
+ prof_allocation_klass_name(VALUE self)
163
+ {
164
+ prof_allocation_t* allocation = prof_allocation_get(self);
165
+
166
+ if (allocation->klass_name == Qnil)
167
+ allocation->klass_name = resolve_klass_name(allocation->klass, &allocation->klass_flags);
168
+
169
+ return allocation->klass_name;
170
+ }
171
+
172
+ /* call-seq:
173
+ klass_flags -> integer
174
+
175
+ Returns the klass flags */
176
+
177
+ static VALUE
178
+ prof_allocation_klass_flags(VALUE self)
179
+ {
180
+ prof_allocation_t* allocation = prof_allocation_get(self);
181
+ return INT2FIX(allocation->klass_flags);
182
+ }
183
+
184
+ /* call-seq:
185
+ source_file -> string
186
+
187
+ Returns the the line number where objects were allocated. */
188
+ static VALUE
189
+ prof_allocation_source_file(VALUE self)
190
+ {
191
+ prof_allocation_t* allocation = prof_allocation_get(self);
192
+ return allocation->source_file;
193
+ }
194
+
195
+ /* call-seq:
196
+ line -> number
197
+
198
+ Returns the the line number where objects were allocated. */
199
+ static VALUE
200
+ prof_allocation_source_line(VALUE self)
201
+ {
202
+ prof_allocation_t* allocation = prof_allocation_get(self);
203
+ return INT2FIX(allocation->source_line);
204
+ }
205
+
206
+ /* call-seq:
207
+ count -> number
208
+
209
+ Returns the number of times this class has been allocated. */
210
+ static VALUE
211
+ prof_allocation_count(VALUE self)
212
+ {
213
+ prof_allocation_t* allocation = prof_allocation_get(self);
214
+ return INT2FIX(allocation->count);
215
+ }
216
+
217
+ /* call-seq:
218
+ memory -> number
219
+
220
+ Returns the amount of memory allocated. */
221
+ static VALUE
222
+ prof_allocation_memory(VALUE self)
223
+ {
224
+ prof_allocation_t* allocation = prof_allocation_get(self);
225
+ return ULL2NUM(allocation->memory);
226
+ }
227
+
228
+ /* :nodoc: */
229
+ static VALUE
230
+ prof_allocation_dump(VALUE self)
231
+ {
232
+ prof_allocation_t* allocation = DATA_PTR(self);
233
+
234
+ VALUE result = rb_hash_new();
235
+
236
+ rb_hash_aset(result, ID2SYM(rb_intern("key")), INT2FIX(allocation->key));
237
+ rb_hash_aset(result, ID2SYM(rb_intern("klass_name")), prof_allocation_klass_name(self));
238
+ rb_hash_aset(result, ID2SYM(rb_intern("klass_flags")), INT2FIX(allocation->klass_flags));
239
+ rb_hash_aset(result, ID2SYM(rb_intern("source_file")), allocation->source_file);
240
+ rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(allocation->source_line));
241
+ rb_hash_aset(result, ID2SYM(rb_intern("count")), INT2FIX(allocation->count));
242
+ rb_hash_aset(result, ID2SYM(rb_intern("memory")), LONG2FIX(allocation->memory));
243
+
244
+ return result;
245
+ }
246
+
247
+ /* :nodoc: */
248
+ static VALUE
249
+ prof_allocation_load(VALUE self, VALUE data)
250
+ {
251
+ prof_allocation_t* allocation = DATA_PTR(self);
252
+ allocation->object = self;
253
+
254
+ allocation->key = FIX2LONG(rb_hash_aref(data, ID2SYM(rb_intern("key"))));
255
+ allocation->klass_name = rb_hash_aref(data, ID2SYM(rb_intern("klass_name")));
256
+ allocation->klass_flags = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("klass_flags"))));
257
+ allocation->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
258
+ allocation->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));
259
+ allocation->count = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("count"))));
260
+ allocation->memory = FIX2LONG(rb_hash_aref(data, ID2SYM(rb_intern("memory"))));
261
+
262
+ return data;
263
+ }
264
+
265
+ void rp_init_allocation(void)
266
+ {
267
+ cRpAllocation = rb_define_class_under(mProf, "Allocation", rb_cData);
268
+ rb_undef_method(CLASS_OF(cRpAllocation), "new");
269
+ rb_define_alloc_func(cRpAllocation, prof_allocation_allocate);
270
+
271
+ rb_define_method(cRpAllocation, "klass_name", prof_allocation_klass_name, 0);
272
+ rb_define_method(cRpAllocation, "klass_flags", prof_allocation_klass_flags, 0);
273
+ rb_define_method(cRpAllocation, "source_file", prof_allocation_source_file, 0);
274
+ rb_define_method(cRpAllocation, "line", prof_allocation_source_line, 0);
275
+ rb_define_method(cRpAllocation, "count", prof_allocation_count, 0);
276
+ rb_define_method(cRpAllocation, "memory", prof_allocation_memory, 0);
277
+ rb_define_method(cRpAllocation, "_dump_data", prof_allocation_dump, 0);
278
+ rb_define_method(cRpAllocation, "_load_data", prof_allocation_load, 1);
279
+ }