ruby-prof 0.5.0-mswin32 → 0.5.1-mswin32
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.
- data/CHANGES +37 -9
- data/README +48 -11
- data/Rakefile +11 -11
- data/bin/ruby-prof +14 -11
- data/ext/ruby_prof.c +66 -31
- data/lib/ruby-prof/graph_html_printer.rb +7 -5
- data/lib/ruby-prof/graph_printer.rb +3 -0
- data/lib/ruby_prof.so +0 -0
- data/test/basic_test.rb +4 -4
- data/test/gc.log +599 -5
- data/test/line_number_test.rb +69 -0
- data/test/module_test.rb +2 -3
- data/test/prime.rb +31 -29
- data/test/recursive_test.rb +2 -2
- data/test/test_suite.rb +1 -0
- data/test/thread_test.rb +4 -10
- data/test/timing_test.rb +2 -0
- metadata +3 -7
- data/lib/ruby-prof/rails_plugin/ruby-prof/init.rb +0 -6
- data/lib/ruby-prof/rails_plugin/ruby-prof/lib/profiling.rb +0 -52
data/CHANGES
CHANGED
@@ -1,33 +1,61 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.1 (2007-07-18)
|
2
|
+
========================
|
3
|
+
|
4
|
+
ruby-prof 0.5.1 is a bug fix and performance release.
|
5
|
+
|
6
|
+
Performance
|
7
|
+
--------
|
8
|
+
* Significantly reduced the number of thread lookups by
|
9
|
+
caching the last executed thread.
|
10
|
+
|
11
|
+
Fixes
|
12
|
+
-------
|
13
|
+
* Properly escape method names in HTML reports
|
14
|
+
* Fix use of -m and --min-percent command line switches
|
15
|
+
* Default source file information to ruby_runtime#0 for c calls
|
16
|
+
* Moved rails_plugin to top level so it is more obvious
|
17
|
+
* Updated rails_plugin to write reports to the current
|
18
|
+
Rails log directory
|
19
|
+
* Added additional tests
|
20
|
+
|
21
|
+
|
22
|
+
0.5.0 (2007-07-09)
|
2
23
|
========================
|
3
24
|
|
4
25
|
Features
|
5
26
|
--------
|
6
|
-
* Added support for
|
27
|
+
* Added support for timing multi-threaded applications
|
28
|
+
* Added support for 64 bit systems (patch from Diego 'Flameeyes' Petten)
|
7
29
|
* Added suport for outputting data in the format used by
|
8
30
|
KCacheGrind (patch from Carl Shimer)
|
9
31
|
* Add filename and line numbers to call tree information (patch from Carl Shimer)
|
10
32
|
* Added Visual Studio 2005 project file.
|
33
|
+
* Added replace-progname switch, als rcov.
|
34
|
+
* Added better support for recursive methods
|
35
|
+
* Added better support for profiling Rails applications
|
11
36
|
|
12
37
|
Fixes
|
13
38
|
-------
|
14
|
-
* Fixes
|
15
|
-
from T_OBJECT as opposed to being a T_OBJECT (identified by Francis Cianfrocca)
|
16
|
-
|
39
|
+
* Fixes bug when the type of an attached object (singleton) is inherited
|
40
|
+
from T_OBJECT as opposed to being a T_OBJECT (identified by Francis Cianfrocca)
|
41
|
+
* ruby-prof now works in IRB.
|
42
|
+
* Fix sort order in reports.
|
43
|
+
* Fixed rdoc compile error.
|
44
|
+
* Fix tabs in erb template for graph html report on windows.
|
17
45
|
|
18
46
|
0.4.1 (2006-06-26)
|
19
47
|
========================
|
20
48
|
|
21
49
|
Features
|
22
50
|
--------
|
23
|
-
* Added a RubyProf.running? method to indicate whether a profile is in progress.
|
51
|
+
* Added a RubyProf.running? method to indicate whether a profile is in progress.
|
24
52
|
* Added tgz and zip archives to release
|
25
53
|
|
26
54
|
Fixes
|
27
55
|
-------
|
28
|
-
* Duplicate method names are now allowed
|
29
|
-
* The documentation has been updated to show the correct API usage is RubyProf.stop not RubyProf.end
|
30
|
-
|
56
|
+
* Duplicate method names are now allowed
|
57
|
+
* The documentation has been updated to show the correct API usage is RubyProf.stop not RubyProf.end
|
58
|
+
|
31
59
|
|
32
60
|
0.4.0 (2006-06-16)
|
33
61
|
========================
|
data/README
CHANGED
@@ -61,7 +61,7 @@ particular segments of code.
|
|
61
61
|
# Print a flat profile to text
|
62
62
|
printer = RubyProf::TextPrinter.new(result)
|
63
63
|
printer.print(STDOUT, 0)
|
64
|
-
|
64
|
+
|
65
65
|
Alternatively, you can use a block to tell ruby-prof what
|
66
66
|
to profile:
|
67
67
|
|
@@ -83,7 +83,7 @@ to profile:
|
|
83
83
|
|
84
84
|
The third way of using ruby-prof is by requiring unprof.rb:
|
85
85
|
|
86
|
-
|
86
|
+
require 'unprof'
|
87
87
|
|
88
88
|
This will start profiling immediately and will output the results
|
89
89
|
using a flat profile report.
|
@@ -195,11 +195,11 @@ You may also specify the measure_mode by using the RUBY_PROF_MEASURE_MODE
|
|
195
195
|
environment variable:
|
196
196
|
|
197
197
|
* export RUBY_PROF_MEASURE_MODE=process
|
198
|
-
*
|
198
|
+
* export RUBY_PROF_MEASURE_MODE=wall
|
199
199
|
* export RUBY_PROF_MEASURE_MODE=cpu
|
200
200
|
* export RUBY_PROF_MEASURE_MODE=allocations
|
201
201
|
|
202
|
-
Note that these values have changed since ruby-prof-0.3.0.
|
202
|
+
Note that these values have changed since ruby-prof-0.3.0.
|
203
203
|
|
204
204
|
On Linux, process time is measured using the clock method provided
|
205
205
|
by the C runtime library. Note that the clock method does not
|
@@ -214,6 +214,12 @@ provided by the C runtime library. Note though, these values are
|
|
214
214
|
wall times on Windows and not process times like on Linux.
|
215
215
|
Wall time is measured using the GetLocalTime API.
|
216
216
|
|
217
|
+
If you use wall time, the results will be affected by other
|
218
|
+
processes running on your computer, network delays, disk access,
|
219
|
+
etc. As result, for the best results, try to make sure your
|
220
|
+
computer is only performing your profiling run and is
|
221
|
+
otherwise quiescent.
|
222
|
+
|
217
223
|
On both platforms, cpu time is measured using the RDTSC assembly
|
218
224
|
function provided by the Pentium and PowerPC platforms. CPU time
|
219
225
|
is dependent on the cpu's frequency. On Linux, ruby-prof attempts
|
@@ -221,31 +227,62 @@ to read this value from "/proc/cpuinfo." On Windows, you must
|
|
221
227
|
specify the clock frequency. This can be done using the
|
222
228
|
RUBY_PROF_CPU_FREQUENCY environment variable:
|
223
229
|
|
224
|
-
|
225
|
-
|
230
|
+
export RUBY_PROF_CPU_FREQUENCY=<value>
|
231
|
+
|
226
232
|
You can also directly set the cpu frequency by calling:
|
227
233
|
|
228
|
-
|
234
|
+
RubyProf.cpu_frequency = <value>
|
229
235
|
|
230
236
|
|
231
237
|
== Recursive Calls
|
232
238
|
|
233
239
|
Recursive calls occur when method A calls method A and cycles
|
234
240
|
occur when method A calls method B calls method C calls method A.
|
235
|
-
ruby-prof
|
236
|
-
|
241
|
+
ruby-prof detects both direct recursive calls and cycles. Both
|
242
|
+
are indicated in reports by a dash and number following a method
|
243
|
+
name. For example, here is a flat profile from the test method
|
244
|
+
RecursiveTest#test_recursive:
|
245
|
+
|
246
|
+
|
247
|
+
%self total self wait child calls name
|
248
|
+
100.00 2.00 2.00 0.00 0.00 2 Kernel#sleep
|
249
|
+
0.00 2.00 0.00 0.00 2.00 0 RecursiveTest#test_cycle
|
250
|
+
0.00 0.00 0.00 0.00 0.00 2 Fixnum#==
|
251
|
+
0.00 0.00 0.00 0.00 0.00 2 Fixnum#-
|
252
|
+
0.00 1.00 0.00 0.00 1.00 1 Object#sub_cycle-1
|
253
|
+
0.00 2.00 0.00 0.00 2.00 1 Object#sub_cycle
|
254
|
+
0.00 2.00 0.00 0.00 2.00 1 Object#cycle
|
255
|
+
0.00 1.00 0.00 0.00 1.00 1 Object#cycle-1
|
256
|
+
|
257
|
+
Notice the presence of Object#cycle and Object#cycle-1. The -1 means
|
258
|
+
the method was either recursively called (directly or indirectly).
|
237
259
|
|
238
260
|
However, the self time values for recursive calls should always
|
239
261
|
be accurate. It is also believed that the total times are
|
240
262
|
accurate, but these should be carefully analyzed to verify their veracity.
|
241
263
|
|
264
|
+
== Multi-threaded Applications
|
265
|
+
|
266
|
+
Unfortunately, Ruby does not provide an internal api
|
267
|
+
for detecting thread context switches. As a result, the
|
268
|
+
timings ruby-prof reports for each thread may be slightly
|
269
|
+
inaccurate. In particular, this will happen for newly
|
270
|
+
spanned threads that immediately go to sleep. For instance,
|
271
|
+
if you use Ruby's timeout library to wait for 2 seconds,
|
272
|
+
the 2 seconds will be assigned to the foreground thread
|
273
|
+
and not the newly created background thread. These errors
|
274
|
+
can largely be avoided if the background thread performs an
|
275
|
+
operation before going to sleeep.
|
276
|
+
|
277
|
+
|
242
278
|
== Performance
|
243
279
|
|
244
280
|
Significant effort has been put into reducing ruby-prof's overhead
|
245
281
|
as much as possible. Our tests show that the overhead associated
|
246
282
|
with profiling code varies considerably with the code being
|
247
|
-
profiled.
|
248
|
-
|
283
|
+
profiled. Most programs will run approximately twice as slow
|
284
|
+
while highly recursive programs (like the fibonacci series test)
|
285
|
+
will run three times slower.
|
249
286
|
|
250
287
|
== Windows Binary
|
251
288
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
|
|
5
5
|
SO_NAME = "ruby_prof.so"
|
6
6
|
|
7
7
|
# ------- Default Package ----------
|
8
|
-
RUBY_PROF_VERSION = "0.5.
|
8
|
+
RUBY_PROF_VERSION = "0.5.1"
|
9
9
|
|
10
10
|
FILES = FileList[
|
11
11
|
'Rakefile',
|
@@ -117,16 +117,16 @@ Rake::RDocTask.new("rdoc") do |rdoc|
|
|
117
117
|
rdoc.options << "--inline-source" << "--line-numbers"
|
118
118
|
# Make the readme file the start page for the generated html
|
119
119
|
rdoc.options << '--main' << 'README'
|
120
|
-
rdoc.rdoc_files.include('bin/**/*',
|
121
|
-
'doc/*.rdoc',
|
122
|
-
'examples/flat.txt',
|
123
|
-
'examples/graph.txt',
|
124
|
-
'examples/graph.html',
|
125
|
-
'lib/**/*.rb',
|
126
|
-
'ext/**/ruby_prof.c',
|
127
|
-
'README',
|
128
|
-
'LICENSE')
|
129
|
-
end
|
120
|
+
rdoc.rdoc_files.include('bin/**/*',
|
121
|
+
'doc/*.rdoc',
|
122
|
+
'examples/flat.txt',
|
123
|
+
'examples/graph.txt',
|
124
|
+
'examples/graph.html',
|
125
|
+
'lib/**/*.rb',
|
126
|
+
'ext/**/ruby_prof.c',
|
127
|
+
'README',
|
128
|
+
'LICENSE')
|
129
|
+
end
|
130
130
|
|
131
131
|
|
132
132
|
# --------- Publish to RubyForge ----------------
|
data/bin/ruby-prof
CHANGED
@@ -15,7 +15,10 @@
|
|
15
15
|
# graph_html - Prints a graph profile as html.
|
16
16
|
# call_tree - format for KCacheGrind
|
17
17
|
# -f, --file=path Output results to a file instead of standard out.
|
18
|
-
# -m, --
|
18
|
+
# -m, --min_percent=min_percent The minimum percent a method must take before ',
|
19
|
+
# being included in output reports. Should be an
|
20
|
+
# integer between 1 and 100. 0 means all methods are printed.
|
21
|
+
# --mode=measure_mode Select a measurement mode:
|
19
22
|
# process - Use process time (default).
|
20
23
|
# wall - Use wall time.
|
21
24
|
# cpu - Use the CPU clock counter
|
@@ -79,16 +82,15 @@ opts = OptionParser.new do |opts|
|
|
79
82
|
options.file = file
|
80
83
|
end
|
81
84
|
|
82
|
-
opts.on('
|
85
|
+
opts.on('--mode=measure_mode',
|
83
86
|
[:process, :wall, :cpu, :allocations],
|
84
87
|
'Select what ruby-prof should measure:',
|
85
88
|
' process - Process time (default).',
|
86
89
|
' wall - Wall time.',
|
87
|
-
' cpu - CPU time',
|
88
|
-
'
|
89
|
-
' allocations - O3bject allocations (required patched Ruby interpreter).') do |measure_mode|
|
90
|
+
' cpu - CPU time (Pentium and PowerPCs only).',
|
91
|
+
' allocations - Object allocations (requires patched Ruby interpreter).') do |measure_mode|
|
90
92
|
|
91
|
-
case
|
93
|
+
case mode
|
92
94
|
when :process
|
93
95
|
options.measure_mode = RubyProf::PROCESS_TIME
|
94
96
|
when :wall
|
@@ -100,14 +102,15 @@ opts = OptionParser.new do |opts|
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
|
-
|
104
|
-
|
105
|
-
|
105
|
+
opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
|
106
|
+
options.replace_prog_name = true
|
107
|
+
end
|
106
108
|
|
107
109
|
opts.on_tail("-h", "--help", "Show help message") do
|
108
110
|
puts opts
|
109
111
|
exit
|
110
112
|
end
|
113
|
+
|
111
114
|
opts.on_tail("-v", "--version", "Show version") do
|
112
115
|
puts "ruby_prof " + RubyProf::VERSION
|
113
116
|
exit
|
@@ -147,11 +150,11 @@ at_exit {
|
|
147
150
|
# Get output
|
148
151
|
if options.file
|
149
152
|
File.open(options.file, 'w') do |file|
|
150
|
-
printer.print(file, options.min_percent)
|
153
|
+
printer.print(file, {:min_percent => options.min_percent})
|
151
154
|
end
|
152
155
|
else
|
153
156
|
# Print out results
|
154
|
-
printer.print(STDOUT, options.min_percent)
|
157
|
+
printer.print(STDOUT, {:min_percent => options.min_percent})
|
155
158
|
end
|
156
159
|
}
|
157
160
|
|
data/ext/ruby_prof.c
CHANGED
@@ -57,7 +57,7 @@
|
|
57
57
|
|
58
58
|
/* ================ Constants =================*/
|
59
59
|
#define INITIAL_STACK_SIZE 8
|
60
|
-
#define PROF_VERSION "0.5.
|
60
|
+
#define PROF_VERSION "0.5.1"
|
61
61
|
|
62
62
|
|
63
63
|
/* ================ Measurement =================*/
|
@@ -159,7 +159,9 @@ static thread_data_t* last_thread_data = NULL;
|
|
159
159
|
static inline long
|
160
160
|
get_thread_id(VALUE thread)
|
161
161
|
{
|
162
|
-
return NUM2ULONG(rb_obj_id(thread));
|
162
|
+
//return NUM2ULONG(rb_obj_id(thread));
|
163
|
+
// From line 1997 in gc.c
|
164
|
+
return (long)thread;
|
163
165
|
}
|
164
166
|
|
165
167
|
static VALUE
|
@@ -572,7 +574,8 @@ the RubyProf::Result object.
|
|
572
574
|
|
573
575
|
/* :nodoc: */
|
574
576
|
static prof_method_t *
|
575
|
-
prof_method_create(
|
577
|
+
prof_method_create(st_data_t key, VALUE klass, ID mid, int depth,
|
578
|
+
const char* source_file, int line)
|
576
579
|
{
|
577
580
|
prof_method_t *result = ALLOC(prof_method_t);
|
578
581
|
|
@@ -590,8 +593,8 @@ prof_method_create(NODE *node, st_data_t key, VALUE klass, ID mid, int depth)
|
|
590
593
|
result->active_frame = 0;
|
591
594
|
result->base = result;
|
592
595
|
|
593
|
-
result->source_file =
|
594
|
-
result->line =
|
596
|
+
result->source_file = source_file;
|
597
|
+
result->line = line;
|
595
598
|
return result;
|
596
599
|
}
|
597
600
|
|
@@ -706,7 +709,7 @@ static VALUE prof_method_source_file(VALUE self)
|
|
706
709
|
const char* sf = get_prof_method(self)->source_file;
|
707
710
|
if(!sf)
|
708
711
|
{
|
709
|
-
return
|
712
|
+
return rb_str_new2("ruby_runtime");
|
710
713
|
}
|
711
714
|
else
|
712
715
|
{
|
@@ -917,25 +920,23 @@ threads_table_insert(st_table *table, VALUE thread, thread_data_t *thread_data)
|
|
917
920
|
}
|
918
921
|
|
919
922
|
static inline thread_data_t *
|
920
|
-
threads_table_lookup(st_table *table,
|
923
|
+
threads_table_lookup(st_table *table, long thread_id)
|
921
924
|
{
|
922
925
|
thread_data_t* result;
|
923
926
|
st_data_t val;
|
924
927
|
|
925
928
|
/* Its too slow to key on the real thread id so just typecast thread instead. */
|
926
|
-
if (st_lookup(table, (st_data_t)
|
929
|
+
if (st_lookup(table, (st_data_t) thread_id, &val))
|
927
930
|
{
|
928
931
|
result = (thread_data_t *) val;
|
929
932
|
}
|
930
933
|
else
|
931
934
|
{
|
932
935
|
result = thread_data_create();
|
933
|
-
|
934
|
-
/* Store the real thread id here so it can be shown in the results. */
|
935
|
-
result->thread_id = get_thread_id(thread);
|
936
|
+
result->thread_id = thread_id;
|
936
937
|
|
937
938
|
/* Insert the table */
|
938
|
-
threads_table_insert(threads_tbl,
|
939
|
+
threads_table_insert(threads_tbl, thread_id, result);
|
939
940
|
}
|
940
941
|
return result;
|
941
942
|
}
|
@@ -1076,10 +1077,11 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
1076
1077
|
VALUE thread;
|
1077
1078
|
prof_measure_t now = 0;
|
1078
1079
|
thread_data_t* thread_data = NULL;
|
1080
|
+
long thread_id = 0;
|
1079
1081
|
prof_frame_t *frame = NULL;
|
1080
1082
|
|
1081
|
-
|
1082
|
-
|
1083
|
+
/*
|
1084
|
+
{
|
1083
1085
|
st_data_t key = 0;
|
1084
1086
|
static unsigned long last_thread_id = 0;
|
1085
1087
|
|
@@ -1110,29 +1112,42 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
1110
1112
|
/* Get current measurement*/
|
1111
1113
|
now = get_measurement();
|
1112
1114
|
|
1113
|
-
/* Get the current thread
|
1115
|
+
/* Get the current thread information. */
|
1114
1116
|
thread = rb_thread_current();
|
1115
|
-
|
1117
|
+
thread_id = get_thread_id(thread);
|
1116
1118
|
|
1117
|
-
/*
|
1118
|
-
|
1119
|
-
previous method (EVENT_CALL).*/
|
1120
|
-
frame = stack_peek(thread_data->stack);
|
1121
|
-
|
1122
|
-
/* Check for a context switch */
|
1123
|
-
if (last_thread_data && last_thread_data != thread_data)
|
1119
|
+
/* Was there a context switch? */
|
1120
|
+
if (!last_thread_data || last_thread_data->thread_id != thread_id)
|
1124
1121
|
{
|
1125
|
-
|
1126
|
-
|
1122
|
+
prof_measure_t wait_time = 0;
|
1123
|
+
|
1124
|
+
/* Get new thread information. */
|
1125
|
+
thread_data = threads_table_lookup(threads_tbl, thread_id);
|
1126
|
+
|
1127
|
+
/* How long has this thread been waiting? */
|
1128
|
+
wait_time = now - thread_data->last_switch;
|
1129
|
+
thread_data->last_switch = 0;
|
1130
|
+
|
1131
|
+
/* Get the frame at the top of the stack. This may represent
|
1132
|
+
the current method (EVENT_LINE, EVENT_RETURN) or the
|
1133
|
+
previous method (EVENT_CALL).*/
|
1134
|
+
frame = stack_peek(thread_data->stack);
|
1135
|
+
|
1127
1136
|
if (frame)
|
1128
1137
|
frame->wait_time += wait_time;
|
1129
1138
|
|
1130
1139
|
/* Save on the last thread the time of the context switch
|
1131
1140
|
and reset this thread's last context switch to 0.*/
|
1132
|
-
last_thread_data
|
1133
|
-
|
1141
|
+
if (last_thread_data)
|
1142
|
+
last_thread_data->last_switch = now;
|
1143
|
+
|
1144
|
+
last_thread_data = thread_data;
|
1145
|
+
}
|
1146
|
+
else
|
1147
|
+
{
|
1148
|
+
thread_data = last_thread_data;
|
1149
|
+
frame = stack_peek(thread_data->stack);
|
1134
1150
|
}
|
1135
|
-
last_thread_data = thread_data;
|
1136
1151
|
|
1137
1152
|
switch (event) {
|
1138
1153
|
case RUBY_EVENT_LINE:
|
@@ -1156,7 +1171,7 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
1156
1171
|
int depth = 0;
|
1157
1172
|
st_data_t key = 0;
|
1158
1173
|
prof_method_t *method = NULL;
|
1159
|
-
|
1174
|
+
|
1160
1175
|
/* Is this an include for a module? If so get the actual
|
1161
1176
|
module class since we want to combine all profiling
|
1162
1177
|
results for that module. */
|
@@ -1170,7 +1185,17 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
1170
1185
|
|
1171
1186
|
if (!method)
|
1172
1187
|
{
|
1173
|
-
|
1188
|
+
const char* source_file = (node ? node->nd_file : 0);
|
1189
|
+
int line = (node ? nd_line(node) : 0);
|
1190
|
+
|
1191
|
+
/* Line numbers are not accurate for c method calls */
|
1192
|
+
if (event == RUBY_EVENT_C_CALL)
|
1193
|
+
{
|
1194
|
+
line = 0;
|
1195
|
+
source_file = NULL;
|
1196
|
+
}
|
1197
|
+
|
1198
|
+
method = prof_method_create(key, klass, mid, depth, source_file, line);
|
1174
1199
|
method_info_table_insert(thread_data->method_info_table, key, method);
|
1175
1200
|
}
|
1176
1201
|
|
@@ -1185,7 +1210,17 @@ prof_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
1185
1210
|
|
1186
1211
|
if (!method)
|
1187
1212
|
{
|
1188
|
-
|
1213
|
+
const char* source_file = (node ? node->nd_file : 0);
|
1214
|
+
int line = (node ? nd_line(node) : 0);
|
1215
|
+
|
1216
|
+
/* Line numbers are not accurate for c method calls */
|
1217
|
+
if (event == RUBY_EVENT_C_CALL)
|
1218
|
+
{
|
1219
|
+
line = 0;
|
1220
|
+
source_file = NULL;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
method = prof_method_create(key, klass, mid, depth, source_file, line);
|
1189
1224
|
method->base = base_method;
|
1190
1225
|
method_info_table_insert(thread_data->method_info_table, key, method);
|
1191
1226
|
}
|