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;