ruby-prof 1.1.0-x64-mingw32 → 1.3.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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
- }