ruby-prof 1.1.0-x64-mingw32 → 1.3.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +19 -1
  3. data/bin/ruby-prof +100 -152
  4. data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
  5. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  6. data/ext/ruby_prof/rp_allocation.c +67 -59
  7. data/ext/ruby_prof/rp_allocation.h +3 -3
  8. data/ext/ruby_prof/rp_call_tree.c +369 -0
  9. data/ext/ruby_prof/rp_call_tree.h +43 -0
  10. data/ext/ruby_prof/rp_call_trees.c +288 -0
  11. data/ext/ruby_prof/rp_call_trees.h +28 -0
  12. data/ext/ruby_prof/rp_measure_allocations.c +11 -13
  13. data/ext/ruby_prof/rp_measure_process_time.c +11 -13
  14. data/ext/ruby_prof/rp_measure_wall_time.c +17 -15
  15. data/ext/ruby_prof/rp_measurement.c +47 -40
  16. data/ext/ruby_prof/rp_measurement.h +7 -7
  17. data/ext/ruby_prof/rp_method.c +116 -255
  18. data/ext/ruby_prof/rp_method.h +31 -39
  19. data/ext/ruby_prof/rp_profile.c +311 -281
  20. data/ext/ruby_prof/rp_profile.h +1 -2
  21. data/ext/ruby_prof/rp_stack.c +113 -105
  22. data/ext/ruby_prof/rp_stack.h +17 -20
  23. data/ext/ruby_prof/rp_thread.c +136 -111
  24. data/ext/ruby_prof/rp_thread.h +12 -9
  25. data/ext/ruby_prof/ruby_prof.c +27 -23
  26. data/ext/ruby_prof/ruby_prof.h +9 -0
  27. data/ext/ruby_prof/vc/ruby_prof.vcxproj +11 -7
  28. data/lib/ruby-prof.rb +2 -3
  29. data/lib/ruby-prof/assets/call_stack_printer.html.erb +4 -7
  30. data/lib/ruby-prof/assets/graph_printer.html.erb +5 -6
  31. data/lib/ruby-prof/{call_info.rb → call_tree.rb} +6 -6
  32. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  33. data/lib/ruby-prof/measurement.rb +5 -2
  34. data/lib/ruby-prof/method_info.rb +3 -15
  35. data/lib/ruby-prof/printers/call_info_printer.rb +12 -10
  36. data/lib/ruby-prof/printers/call_stack_printer.rb +19 -22
  37. data/lib/ruby-prof/printers/call_tree_printer.rb +1 -1
  38. data/lib/ruby-prof/printers/dot_printer.rb +3 -3
  39. data/lib/ruby-prof/printers/graph_printer.rb +3 -4
  40. data/lib/ruby-prof/printers/multi_printer.rb +2 -2
  41. data/lib/ruby-prof/rack.rb +3 -0
  42. data/lib/ruby-prof/thread.rb +3 -18
  43. data/lib/ruby-prof/version.rb +1 -1
  44. data/ruby-prof.gemspec +7 -0
  45. data/test/alias_test.rb +42 -45
  46. data/test/basic_test.rb +0 -86
  47. data/test/{call_info_visitor_test.rb → call_tree_visitor_test.rb} +6 -5
  48. data/test/call_trees_test.rb +66 -0
  49. data/test/exclude_methods_test.rb +17 -12
  50. data/test/fiber_test.rb +197 -9
  51. data/test/gc_test.rb +36 -42
  52. data/test/inverse_call_tree_test.rb +175 -0
  53. data/test/line_number_test.rb +67 -70
  54. data/test/marshal_test.rb +7 -11
  55. data/test/measure_allocations_test.rb +224 -234
  56. data/test/measure_allocations_trace_test.rb +224 -234
  57. data/test/measure_memory_trace_test.rb +814 -469
  58. data/test/measure_process_time_test.rb +0 -64
  59. data/test/measure_times.rb +2 -0
  60. data/test/measure_wall_time_test.rb +34 -58
  61. data/test/pause_resume_test.rb +19 -10
  62. data/test/prime.rb +1 -3
  63. data/test/prime_script.rb +6 -0
  64. data/test/printers_test.rb +1 -1
  65. data/test/recursive_test.rb +50 -54
  66. data/test/start_stop_test.rb +19 -19
  67. data/test/test_helper.rb +3 -15
  68. data/test/thread_test.rb +11 -11
  69. data/test/unique_call_path_test.rb +25 -95
  70. metadata +19 -10
  71. data/ext/ruby_prof/rp_call_info.c +0 -271
  72. data/ext/ruby_prof/rp_call_info.h +0 -35
  73. data/lib/2.6.5/ruby_prof.so +0 -0
  74. data/lib/ruby-prof/call_info_visitor.rb +0 -38
  75. data/test/parser_timings.rb +0 -24
@@ -56,9 +56,9 @@ class StartStopTest < TestCase
56
56
  assert_in_delta(0, method.self_time, 0.02)
57
57
  assert_in_delta(2, method.children_time, 0.05)
58
58
 
59
- assert_equal(1, method.callees.length)
60
- call_info = method.callees[0]
61
- assert_equal('StartStopTest#method2', call_info.target.full_name)
59
+ assert_equal(1, method.call_trees.callees.length)
60
+ call_tree = method.call_trees.callees[0]
61
+ assert_equal('StartStopTest#method2', call_tree.target.full_name)
62
62
 
63
63
  method = methods[1]
64
64
  assert_equal('StartStopTest#method2', method.full_name)
@@ -68,13 +68,13 @@ class StartStopTest < TestCase
68
68
  assert_in_delta(0, method.self_time, 0.02)
69
69
  assert_in_delta(2, method.children_time, 0.05)
70
70
 
71
- assert_equal(1, method.callers.length)
72
- call_info = method.callers[0]
73
- assert_equal('StartStopTest#method1', call_info.parent.full_name)
71
+ assert_equal(1, method.call_trees.callers.length)
72
+ call_tree = method.call_trees.callers[0]
73
+ assert_equal('StartStopTest#method1', call_tree.parent.target.full_name)
74
74
 
75
- assert_equal(1, method.callees.length)
76
- call_info = method.callees[0]
77
- assert_equal('StartStopTest#method3', call_info.target.full_name)
75
+ assert_equal(1, method.call_trees.callees.length)
76
+ call_tree = method.call_trees.callees[0]
77
+ assert_equal('StartStopTest#method3', call_tree.target.full_name)
78
78
 
79
79
  method = methods[2]
80
80
  assert_equal('StartStopTest#method3', method.full_name)
@@ -84,13 +84,13 @@ class StartStopTest < TestCase
84
84
  assert_in_delta(0, method.self_time, 0.02)
85
85
  assert_in_delta(2, method.children_time, 0.02)
86
86
 
87
- assert_equal(1, method.callers.length)
88
- call_info = method.callers[0]
89
- assert_equal('StartStopTest#method2', call_info.parent.full_name)
87
+ assert_equal(1, method.call_trees.callers.length)
88
+ call_tree = method.call_trees.callers[0]
89
+ assert_equal('StartStopTest#method2', call_tree.parent.target.full_name)
90
90
 
91
- assert_equal(1, method.callees.length)
92
- call_info = method.callees[0]
93
- assert_equal('Kernel#sleep', call_info.target.full_name)
91
+ assert_equal(1, method.call_trees.callees.length)
92
+ call_tree = method.call_trees.callees[0]
93
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
94
94
 
95
95
  method = methods[3]
96
96
  assert_equal('Kernel#sleep', method.full_name)
@@ -100,10 +100,10 @@ class StartStopTest < TestCase
100
100
  assert_in_delta(2, method.self_time, 0.02)
101
101
  assert_in_delta(0, method.children_time, 0.02)
102
102
 
103
- assert_equal(1, method.callers.length)
104
- call_info = method.callers[0]
105
- assert_equal('StartStopTest#method3', call_info.parent.full_name)
103
+ assert_equal(1, method.call_trees.callers.length)
104
+ call_tree = method.call_trees.callers[0]
105
+ assert_equal('StartStopTest#method3', call_tree.parent.target.full_name)
106
106
 
107
- assert_equal(0, method.callees.length)
107
+ assert_equal(0, method.call_trees.callees.length)
108
108
  end
109
109
  end
@@ -1,24 +1,12 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require "rubygems"
4
- gem "minitest"
5
- require 'singleton'
6
-
7
- # To make testing/debugging easier, test within this source tree versus an installed gem
8
- dir = File.dirname(__FILE__)
9
- root = File.expand_path(File.join(dir, '..'))
10
- lib = File.expand_path(File.join(root, 'lib'))
11
- ext = File.expand_path(File.join(root, 'ext', 'ruby_prof'))
12
-
13
- $LOAD_PATH << lib
14
- $LOAD_PATH << ext
15
-
16
- require 'ruby-prof'
17
-
18
3
  # Disable minitest parallel tests. The problem is the thread switching will cahnge test results
19
4
  # (self vs wait time)
20
5
  ENV["N"] = "0"
6
+
7
+ require 'bundler/setup'
21
8
  require 'minitest/autorun'
9
+ require 'ruby-prof'
22
10
 
23
11
  class TestCase < Minitest::Test
24
12
  end
@@ -75,7 +75,7 @@ class ThreadTest < TestCase
75
75
  assert_in_delta(0, method.self_time, 0.05)
76
76
  assert_in_delta(0, method.wait_time, 0.05)
77
77
  assert_in_delta(1, method.children_time, 0.05)
78
- assert_equal(1, method.callers.length)
78
+ assert_equal(0, method.call_trees.callers.length)
79
79
 
80
80
  method = methods[1]
81
81
  assert_equal('Kernel#sleep', method.full_name)
@@ -85,8 +85,8 @@ class ThreadTest < TestCase
85
85
  assert_in_delta(0, method.wait_time, 0.05)
86
86
  assert_in_delta(0, method.children_time, 0.05)
87
87
 
88
- assert_equal(1, method.callers.length)
89
- assert_equal(0, method.callees.length)
88
+ assert_equal(1, method.call_trees.callers.length)
89
+ assert_equal(0, method.call_trees.callees.length)
90
90
 
91
91
  # Check foreground thread
92
92
  rp_thread = result.threads.detect {|athread| athread.id == Thread.current.object_id}
@@ -105,8 +105,8 @@ class ThreadTest < TestCase
105
105
  assert_in_delta(0, method.wait_time, 0.05)
106
106
  assert_in_delta(1, method.children_time, 0.05)
107
107
 
108
- assert_equal(1, method.callers.length)
109
- assert_equal(2, method.callees.length)
108
+ assert_equal(0, method.call_trees.callers.length)
109
+ assert_equal(2, method.call_trees.callees.length)
110
110
 
111
111
  method = methods[1]
112
112
  assert_equal('Thread#join', method.full_name)
@@ -116,8 +116,8 @@ class ThreadTest < TestCase
116
116
  assert_in_delta(1.0, method.wait_time, 0.05)
117
117
  assert_in_delta(0, method.children_time, 0.05)
118
118
 
119
- assert_equal(1, method.callers.length)
120
- assert_equal(0, method.callees.length)
119
+ assert_equal(1, method.call_trees.callers.length)
120
+ assert_equal(0, method.call_trees.callees.length)
121
121
 
122
122
  method = methods[2]
123
123
  assert_equal('<Class::Thread>#new', method.full_name)
@@ -127,8 +127,8 @@ class ThreadTest < TestCase
127
127
  assert_in_delta(0, method.wait_time, 0.05)
128
128
  assert_in_delta(0, method.children_time, 0.05)
129
129
 
130
- assert_equal(1, method.callers.length)
131
- assert_equal(1, method.callees.length)
130
+ assert_equal(1, method.call_trees.callers.length)
131
+ assert_equal(1, method.call_trees.callees.length)
132
132
 
133
133
  method = methods[3]
134
134
  assert_equal('Thread#initialize', method.full_name)
@@ -138,7 +138,7 @@ class ThreadTest < TestCase
138
138
  assert_in_delta(0, method.wait_time, 0.05)
139
139
  assert_in_delta(0, method.children_time, 0.05)
140
140
 
141
- assert_equal(1, method.callers.length)
142
- assert_equal(0, method.callees.length)
141
+ assert_equal(1, method.call_trees.callers.length)
142
+ assert_equal(0, method.call_trees.callees.length)
143
143
  end
144
144
  end
@@ -27,24 +27,15 @@ end
27
27
 
28
28
  # -- Tests ----
29
29
  class UniqueCallPathTest < TestCase
30
- def test_root_method
30
+ def test_root
31
31
  unique_call_path = UniqueCallPath.new
32
32
 
33
33
  result = RubyProf.profile do
34
34
  unique_call_path.method_a(1)
35
35
  end
36
36
 
37
- root_methods = Array.new
38
- result.threads.each do |thread|
39
- thread.methods.each do | m |
40
- if m.root?
41
- root_methods.push(m)
42
- end
43
- end
44
- end
45
-
46
- assert_equal(1, root_methods.length)
47
- assert_equal("UniqueCallPathTest#test_root_method", root_methods[0].full_name)
37
+ root_call_info = result.threads.first.call_tree
38
+ assert_equal("UniqueCallPathTest#test_root", root_call_info.target.full_name)
48
39
  end
49
40
 
50
41
  def test_root_children
@@ -55,25 +46,8 @@ class UniqueCallPathTest < TestCase
55
46
  unique_call_path.method_k(2)
56
47
  end
57
48
 
58
- root_methods = Array.new
59
- result.threads.each do |thread|
60
- thread.methods.each do | m |
61
- if m.root?
62
- root_methods.push(m)
63
- end
64
- end
65
- end
66
-
67
- assert_equal(1, root_methods.length)
68
-
69
- root_children = Array.new
70
- root_methods[0].callees.each do | c |
71
- if c.parent.eql?(root_methods[0])
72
- root_children.push(c)
73
- end
74
- end
75
-
76
- children = root_children.sort do |c1, c2|
49
+ root_call_info = result.threads.first.call_tree
50
+ children = root_call_info.children.sort do |c1, c2|
77
51
  c1.target.full_name <=> c2.target.full_name
78
52
  end
79
53
 
@@ -90,60 +64,23 @@ class UniqueCallPathTest < TestCase
90
64
  unique_call_path.method_k(2)
91
65
  end
92
66
 
93
- root_methods = Array.new
94
- result.threads.each do |thread|
95
- thread.methods.each do | m |
96
- if m.root?
97
- root_methods.push(m)
98
- end
99
- end
100
- end
67
+ root_call_info = result.threads.first.call_tree
68
+ assert_equal("UniqueCallPathTest#test_children_of", root_call_info.target.full_name)
101
69
 
102
- assert_equal(1, root_methods.length)
103
- method = root_methods[0]
104
- assert_equal('UniqueCallPathTest#test_children_of', method.full_name)
105
-
106
- call_info_a = root_methods[0].callees.detect do |call_info|
107
- call_info.target.full_name == "UniqueCallPath#method_a"
70
+ call_info_a = root_call_info.children.detect do |call_tree|
71
+ call_tree.target.full_name == "UniqueCallPath#method_a"
108
72
  end
109
73
  refute_nil(call_info_a)
110
74
 
111
- children_of_a = Array.new
112
-
113
- call_info_a.target.callees.each do | c |
75
+ _children_of_a = call_info_a.children.inject(Array.new) do |array, c|
114
76
  if c.parent.eql?(call_info_a)
115
- children_of_a.push(c)
77
+ array << c
116
78
  end
79
+ array
117
80
  end
118
81
 
119
- assert_equal(2, call_info_a.target.callees.length)
120
-
121
- children_of_a = children_of_a.sort do |c1, c2|
122
- c1.target.full_name <=> c2.target.full_name
123
- end
124
-
125
- assert_equal(0, children_of_a.length)
126
- end
127
-
128
- def test_id2ref
129
- unique_call_path = UniqueCallPath.new
130
-
131
- result = RubyProf.profile do
132
- unique_call_path.method_a(1)
133
- end
134
-
135
- root_methods = Array.new
136
- result.threads.each do |thread|
137
- thread.methods.each do | m |
138
- if m.root?
139
- root_methods.push(m)
140
- end
141
- end
142
- end
143
-
144
- child = root_methods[0].callees[0]
145
- refute_equal(0, child.object_id)
146
- #assert_equal(RubyProf::CallInfo.id2ref(child.id).target.full_name, child.target.full_name)
82
+ assert_equal(1, call_info_a.children.length)
83
+ assert_equal("UniqueCallPath#method_b", call_info_a.children.first.target.full_name)
147
84
  end
148
85
 
149
86
  def test_unique_path
@@ -154,37 +91,30 @@ class UniqueCallPathTest < TestCase
154
91
  unique_call_path.method_k(1)
155
92
  end
156
93
 
157
- root_methods = Array.new
158
- result.threads.each do |thread|
159
- thread.methods.each do | m |
160
- if m.root?
161
- root_methods.push(m)
162
- end
163
- end
164
- end
165
-
166
- assert_equal(1, root_methods.length)
94
+ root_call_info = result.threads.first.call_tree
95
+ assert_equal("UniqueCallPathTest#test_unique_path", root_call_info.target.full_name)
167
96
 
168
- call_info_a = root_methods[0].callees.detect do |call_info|
169
- call_info.target.full_name == "UniqueCallPath#method_a"
97
+ call_info_a = root_call_info.children.detect do |call_tree|
98
+ call_tree.target.full_name == "UniqueCallPath#method_a"
170
99
  end
171
100
  refute_nil(call_info_a)
172
101
 
173
- children_of_a = Array.new
174
- call_info_a.target.callees.each do |c|
175
- if c.parent.eql?(call_info_a.target)
176
- children_of_a.push(c)
102
+ children_of_a = call_info_a.children.reduce(Array.new) do |array, c|
103
+ if c.parent.eql?(call_info_a)
104
+ array << c
177
105
  end
106
+ array
178
107
  end
179
108
 
180
- assert_equal(1, call_info_a.target.callees.length)
109
+ assert_equal(1, call_info_a.children.length)
110
+ assert_equal(1, children_of_a.length)
181
111
 
182
112
  children_of_a = children_of_a.sort do |c1, c2|
183
113
  c1.target.full_name <=> c2.target.full_name
184
114
  end
185
115
 
186
116
  assert_equal(1, children_of_a.length)
187
- assert_equal(2, children_of_a[0].called)
117
+ assert_equal(1, children_of_a[0].called)
188
118
  assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
189
119
  end
190
120
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: x64-mingw32
6
6
  authors:
7
7
  - Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-14 00:00:00.000000000 Z
11
+ date: 2020-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -73,10 +73,14 @@ files:
73
73
  - bin/ruby-prof
74
74
  - bin/ruby-prof-check-trace
75
75
  - ext/ruby_prof/extconf.rb
76
+ - ext/ruby_prof/rp_aggregate_call_tree.c
77
+ - ext/ruby_prof/rp_aggregate_call_tree.h
76
78
  - ext/ruby_prof/rp_allocation.c
77
79
  - ext/ruby_prof/rp_allocation.h
78
- - ext/ruby_prof/rp_call_info.c
79
- - ext/ruby_prof/rp_call_info.h
80
+ - ext/ruby_prof/rp_call_tree.c
81
+ - ext/ruby_prof/rp_call_tree.h
82
+ - ext/ruby_prof/rp_call_trees.c
83
+ - ext/ruby_prof/rp_call_trees.h
80
84
  - ext/ruby_prof/rp_measure_allocations.c
81
85
  - ext/ruby_prof/rp_measure_memory.c
82
86
  - ext/ruby_prof/rp_measure_process_time.c
@@ -95,13 +99,12 @@ files:
95
99
  - ext/ruby_prof/ruby_prof.h
96
100
  - ext/ruby_prof/vc/ruby_prof.sln
97
101
  - ext/ruby_prof/vc/ruby_prof.vcxproj
98
- - lib/2.6.5/ruby_prof.so
99
102
  - lib/ruby-prof.rb
100
103
  - lib/ruby-prof/assets/call_stack_printer.html.erb
101
104
  - lib/ruby-prof/assets/call_stack_printer.png
102
105
  - lib/ruby-prof/assets/graph_printer.html.erb
103
- - lib/ruby-prof/call_info.rb
104
- - lib/ruby-prof/call_info_visitor.rb
106
+ - lib/ruby-prof/call_tree.rb
107
+ - lib/ruby-prof/call_tree_visitor.rb
105
108
  - lib/ruby-prof/compatibility.rb
106
109
  - lib/ruby-prof/exclude_common_methods.rb
107
110
  - lib/ruby-prof/measurement.rb
@@ -125,7 +128,8 @@ files:
125
128
  - test/abstract_printer_test.rb
126
129
  - test/alias_test.rb
127
130
  - test/basic_test.rb
128
- - test/call_info_visitor_test.rb
131
+ - test/call_tree_visitor_test.rb
132
+ - test/call_trees_test.rb
129
133
  - test/duplicate_names_test.rb
130
134
  - test/dynamic_method_test.rb
131
135
  - test/enumerable_test.rb
@@ -134,6 +138,7 @@ files:
134
138
  - test/exclude_threads_test.rb
135
139
  - test/fiber_test.rb
136
140
  - test/gc_test.rb
141
+ - test/inverse_call_tree_test.rb
137
142
  - test/line_number_test.rb
138
143
  - test/marshal_test.rb
139
144
  - test/measure_allocations.rb
@@ -145,9 +150,9 @@ files:
145
150
  - test/measure_wall_time_test.rb
146
151
  - test/multi_printer_test.rb
147
152
  - test/no_method_class_test.rb
148
- - test/parser_timings.rb
149
153
  - test/pause_resume_test.rb
150
154
  - test/prime.rb
155
+ - test/prime_script.rb
151
156
  - test/printer_call_stack_test.rb
152
157
  - test/printer_call_tree_test.rb
153
158
  - test/printer_flat_test.rb
@@ -167,7 +172,11 @@ files:
167
172
  homepage: https://github.com/ruby-prof/ruby-prof
168
173
  licenses:
169
174
  - BSD-2-Clause
170
- metadata: {}
175
+ metadata:
176
+ bug_tracker_uri: https://github.com/ruby-prof/ruby-prof/issues
177
+ changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/CHANGES
178
+ documentation_uri: https://ruby-prof.github.io/
179
+ source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/v1.3.0
171
180
  post_install_message:
172
181
  rdoc_options: []
173
182
  require_paths:
@@ -1,271 +0,0 @@
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_call_info.h"
5
-
6
- #define INITIAL_CALL_INFOS_SIZE 2
7
-
8
- VALUE cRpCallnfo;
9
-
10
- /* ======= prof_call_info_t ========*/
11
- prof_call_info_t *
12
- prof_call_info_create(prof_method_t *method, prof_method_t *parent, VALUE source_file, int source_line)
13
- {
14
- prof_call_info_t *result = ALLOC(prof_call_info_t);
15
- result->method = method;
16
- result->parent = parent;
17
- result->object = Qnil;
18
- result->measurement = prof_measurement_create();
19
-
20
- result->visits = 0;
21
-
22
- result->depth = 0;
23
- result->source_line = source_line;
24
- result->source_file = source_file;
25
-
26
- return result;
27
- }
28
-
29
- static void
30
- prof_call_info_ruby_gc_free(void *data)
31
- {
32
- prof_call_info_t *call_info = (prof_call_info_t*)data;
33
-
34
- /* Has this call info object been accessed by Ruby? If
35
- yes clean it up so to avoid a segmentation fault. */
36
- if (call_info->object != Qnil)
37
- {
38
- RDATA(call_info->object)->dmark = NULL;
39
- RDATA(call_info->object)->dfree = NULL;
40
- RDATA(call_info->object)->data = NULL;
41
- call_info->object = Qnil;
42
- }
43
- }
44
-
45
- void
46
- prof_call_info_free(prof_call_info_t *call_info)
47
- {
48
- prof_measurement_free(call_info->measurement);
49
- prof_call_info_ruby_gc_free(call_info);
50
- xfree(call_info);
51
- }
52
-
53
- size_t
54
- prof_call_info_size(const void *data)
55
- {
56
- return sizeof(prof_call_info_t);
57
- }
58
-
59
- void
60
- prof_call_info_mark(void *data)
61
- {
62
- prof_call_info_t *call_info = (prof_call_info_t*)data;
63
-
64
- if (call_info->source_file != Qnil)
65
- rb_gc_mark(call_info->source_file);
66
-
67
- if (call_info->object != Qnil)
68
- rb_gc_mark(call_info->object);
69
-
70
- if (call_info->method && call_info->method->object != Qnil)
71
- rb_gc_mark(call_info->method->object);
72
-
73
- if (call_info->parent && call_info->parent->object != Qnil)
74
- rb_gc_mark(call_info->parent->object);
75
-
76
- prof_measurement_mark(call_info->measurement);
77
- }
78
-
79
- VALUE
80
- prof_call_info_wrap(prof_call_info_t *call_info)
81
- {
82
- if (call_info->object == Qnil)
83
- {
84
- call_info->object = Data_Wrap_Struct(cRpCallnfo, prof_call_info_mark, prof_call_info_ruby_gc_free, call_info);
85
- }
86
- return call_info->object;
87
- }
88
-
89
- static VALUE
90
- prof_call_info_allocate(VALUE klass)
91
- {
92
- prof_call_info_t* call_info = prof_call_info_create(NULL, NULL, Qnil, 0);
93
- call_info->object = prof_call_info_wrap(call_info);
94
- return call_info->object;
95
- }
96
-
97
- prof_call_info_t *
98
- prof_get_call_info(VALUE self)
99
- {
100
- /* Can't use Data_Get_Struct because that triggers the event hook
101
- ending up in endless recursion. */
102
- prof_call_info_t* result = DATA_PTR(self);
103
-
104
- if (!result)
105
- rb_raise(rb_eRuntimeError, "This RubyProf::CallInfo instance has already been freed, likely because its profile has been freed.");
106
-
107
- return result;
108
- }
109
-
110
- /* ======= Call Info Table ========*/
111
- st_table *
112
- call_info_table_create()
113
- {
114
- return st_init_numtable();
115
- }
116
-
117
- size_t
118
- call_info_table_insert(st_table *table, st_data_t key, prof_call_info_t *val)
119
- {
120
- return st_insert(table, (st_data_t) key, (st_data_t) val);
121
- }
122
-
123
- prof_call_info_t *
124
- call_info_table_lookup(st_table *table, st_data_t key)
125
- {
126
- st_data_t val;
127
- if (st_lookup(table, (st_data_t) key, &val))
128
- {
129
- return (prof_call_info_t *) val;
130
- }
131
- else
132
- {
133
- return NULL;
134
- }
135
- }
136
-
137
- /* ======= RubyProf::CallInfo ========*/
138
-
139
- /* call-seq:
140
- parent -> call_info
141
-
142
- Returns the call_infos parent call_info object (the method that called this method).*/
143
- static VALUE
144
- prof_call_info_parent(VALUE self)
145
- {
146
- prof_call_info_t* call_info = prof_get_call_info(self);
147
- if (call_info->parent)
148
- return prof_method_wrap(call_info->parent);
149
- else
150
- return Qnil;
151
- }
152
-
153
- /* call-seq:
154
- called -> MethodInfo
155
-
156
- Returns the target method. */
157
- static VALUE
158
- prof_call_info_target(VALUE self)
159
- {
160
- prof_call_info_t *call_info = prof_get_call_info(self);
161
- return prof_method_wrap(call_info->method);
162
- }
163
-
164
- /* call-seq:
165
- called -> Measurement
166
-
167
- Returns the measurement associated with this call_info. */
168
- static VALUE
169
- prof_call_info_measurement(VALUE self)
170
- {
171
- prof_call_info_t* call_info = prof_get_call_info(self);
172
- return prof_measurement_wrap(call_info->measurement);
173
- }
174
-
175
- /* call-seq:
176
- depth -> int
177
-
178
- returns the depth of this call info in the call graph */
179
- static VALUE
180
- prof_call_info_depth(VALUE self)
181
- {
182
- prof_call_info_t *result = prof_get_call_info(self);
183
- return rb_int_new(result->depth);
184
- }
185
-
186
- /* call-seq:
187
- source_file => string
188
-
189
- return the source file of the method
190
- */
191
- static VALUE
192
- prof_call_info_source_file(VALUE self)
193
- {
194
- prof_call_info_t* result = prof_get_call_info(self);
195
- return result->source_file;
196
- }
197
-
198
- /* call-seq:
199
- line_no -> int
200
-
201
- returns the line number of the method */
202
- static VALUE
203
- prof_call_info_line(VALUE self)
204
- {
205
- prof_call_info_t *result = prof_get_call_info(self);
206
- return INT2FIX(result->source_line);
207
- }
208
-
209
- /* :nodoc: */
210
- static VALUE
211
- prof_call_info_dump(VALUE self)
212
- {
213
- prof_call_info_t* call_info_data = prof_get_call_info(self);
214
- VALUE result = rb_hash_new();
215
-
216
- rb_hash_aset(result, ID2SYM(rb_intern("measurement")), prof_measurement_wrap(call_info_data->measurement));
217
-
218
- rb_hash_aset(result, ID2SYM(rb_intern("depth")), INT2FIX(call_info_data->depth));
219
- rb_hash_aset(result, ID2SYM(rb_intern("source_file")), call_info_data->source_file);
220
- rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(call_info_data->source_line));
221
-
222
- rb_hash_aset(result, ID2SYM(rb_intern("parent")), prof_call_info_parent(self));
223
- rb_hash_aset(result, ID2SYM(rb_intern("target")), prof_call_info_target(self));
224
-
225
- return result;
226
- }
227
-
228
- /* :nodoc: */
229
- static VALUE
230
- prof_call_info_load(VALUE self, VALUE data)
231
- {
232
- VALUE target = Qnil;
233
- VALUE parent = Qnil;
234
- prof_call_info_t* call_info = prof_get_call_info(self);
235
- call_info->object = self;
236
-
237
- VALUE measurement = rb_hash_aref(data, ID2SYM(rb_intern("measurement")));
238
- call_info->measurement = prof_get_measurement(measurement);
239
-
240
- call_info->depth = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("depth"))));
241
- call_info->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
242
- call_info->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));
243
-
244
- parent = rb_hash_aref(data, ID2SYM(rb_intern("parent")));
245
- if (parent != Qnil)
246
- call_info->parent = prof_method_get(parent);
247
-
248
- target = rb_hash_aref(data, ID2SYM(rb_intern("target")));
249
- call_info->method = prof_method_get(target);
250
-
251
- return data;
252
- }
253
-
254
- void rp_init_call_info()
255
- {
256
- /* CallInfo */
257
- cRpCallnfo = rb_define_class_under(mProf, "CallInfo", rb_cData);
258
- rb_undef_method(CLASS_OF(cRpCallnfo), "new");
259
- rb_define_alloc_func(cRpCallnfo, prof_call_info_allocate);
260
-
261
- rb_define_method(cRpCallnfo, "parent", prof_call_info_parent, 0);
262
- rb_define_method(cRpCallnfo, "target", prof_call_info_target, 0);
263
- rb_define_method(cRpCallnfo, "measurement", prof_call_info_measurement, 0);
264
-
265
- rb_define_method(cRpCallnfo, "depth", prof_call_info_depth, 0);
266
- rb_define_method(cRpCallnfo, "source_file", prof_call_info_source_file, 0);
267
- rb_define_method(cRpCallnfo, "line", prof_call_info_line, 0);
268
-
269
- rb_define_method(cRpCallnfo, "_dump_data", prof_call_info_dump, 0);
270
- rb_define_method(cRpCallnfo, "_load_data", prof_call_info_load, 1);
271
- }