ext/ruby_prof.c in ruby-prof-0.7.7 vs ext/ruby_prof.c in ruby-prof-0.7.8
- old
+ new
@@ -147,11 +147,11 @@
result = rb_String(ID2SYM(mid));
if (depth > 0)
{
char buffer[65];
- sprintf(buffer, "%i", depth);
+ sprintf(buffer, "d%i", depth);
rb_str_cat2(result, "-");
rb_str_cat2(result, buffer);
}
return result;
@@ -1052,21 +1052,21 @@
#ifdef RUBY_VM
if (event != RUBY_EVENT_C_CALL && event != RUBY_EVENT_C_RETURN) {
+ // guess these are already set for C call in 1.9?
rb_frame_method_id_and_class(&mid, &klass);
}
#endif
#ifdef DEBUG
/* This code is here for debug purposes - uncomment it out
when debugging to see a print out of exactly what the
profiler is tracing. */
{
- char* key = 0;
static VALUE last_thread_id = Qnil;
VALUE thread = rb_thread_current();
VALUE thread_id = rb_obj_id(thread);
char* class_name = NULL;
@@ -1083,12 +1083,12 @@
if (last_thread_id != thread_id) {
printf("\n");
}
- printf("%2u: %-8s :%2d %s#%s\n",
- thread_id, event_name, source_line, class_name, method_name);
+ printf("%2u: %-8s %s:%2d %s#%s\n",
+ thread_id, event_name, source_file, source_line, class_name, method_name);
fflush(stdout);
last_thread_id = thread_id;
}
#endif
@@ -1158,25 +1158,21 @@
#ifdef RUBY_VM
method = get_method(event, klass, mid, 0, thread_data->method_table);
#else
method = get_method(event, node, klass, mid, 0, thread_data->method_table);
#endif
-
/* Check for a recursive call */
- while (method->active) // it's while because if you replace this while with an if, the assertion fails... [ltodo figure out why]
+ while (method->active) // it's while because we start at 0 and then go down to the right depth
{
- /* Yes, this method is already active */
+ /* Yes, this method is already active somewhere up the stack */
#ifdef RUBY_VM
method = get_method(event, klass, mid, method->key->depth + 1, thread_data->method_table);
#else
method = get_method(event, node, klass, mid, method->key->depth + 1, thread_data->method_table);
#endif
- }
- assert(!method->active);
-
- method->active = 1;
-
+ }
+ method->active = 1;
if (!frame)
{
call_info = prof_call_info_create(method, NULL);
prof_add_call_info(method->call_infos, call_info);
@@ -1191,11 +1187,11 @@
call_info_table_insert(frame->call_info->call_infos, method->key, call_info);
prof_add_call_info(method->call_infos, call_info);
}
}
- /* Push a new frame onto the stack */
+ /* Push a new frame onto the stack for a new c-call or ruby call (into a method) */
frame = stack_push(thread_data->stack);
frame->call_info = call_info;
frame->start_time = now;
frame->wait_time = 0;
frame->child_time = 0;
@@ -1204,12 +1200,17 @@
break;
}
case RUBY_EVENT_RETURN:
case RUBY_EVENT_C_RETURN:
{
- // this assumes that all C calls take 100% user cpu, I guess.
- pop_frame(thread_data, now);
+ frame = pop_frame(thread_data, now);
+#ifdef RUBY_VM
+ // we need to go up the stack to find the right one [http://redmine.ruby-lang.org/issues/show/2610] (for now)
+ while( (frame->call_info->target->key->mid != mid) || (frame->call_info->target->key->klass != klass)){
+ frame = pop_frame(thread_data, now);
+ }
+#endif
break;
}
}
}
@@ -1225,10 +1226,9 @@
table keyed on thread ID. For each thread id, the hash table
stores another hash table that contains profiling information
for each method called during the threads execution. That
hash table is keyed on method name and contains
RubyProf::MethodInfo objects. */
-
static void
prof_result_mark(prof_result_t *prof_result)
{
VALUE threads = prof_result->threads;