hprof_trace.c

来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 867 行 · 第 1/2 页

C
867
字号
{    TraceInfo *info;    table_lock_enter(gdata->trace_table); {	info              = get_info(index);	info->num_hits   += num_hits;	info->self_cost  += self_cost;	info->total_cost += total_cost;    } table_lock_exit(gdata->trace_table);}TraceIndextrace_find_or_create(SerialNumber thread_serial_num, jint n_frames, FrameIndex *frames, jvmtiFrameInfo *jframes_buffer){    return find_or_create(thread_serial_num, n_frames, frames, getPhase(),				(TraceKey*)jframes_buffer);}/* We may need to ask for more frames than the user asked for */static intget_real_depth(int depth, jboolean skip_init){    int extra_frames;        extra_frames = 0;    /* This is only needed if we are doing BCI */    if ( gdata->bci && depth > 0 ) {	/* Account for Java and native Tracker methods */        extra_frames = 2;	if ( skip_init ) {	    /* Also allow for ignoring the java.lang.Object.<init> method */	    extra_frames += 1;	}    }    return depth + extra_frames;}/* Fill in FrameIndex array from jvmtiFrameInfo array, return n_frames */static intfill_frame_buffer(int depth, int real_depth, 		 int frame_count, jboolean skip_init,		 jvmtiFrameInfo *jframes_buffer, FrameIndex *frames_buffer){    int  n_frames;    jint topframe;    /* If real_depth is 0, just return 0 */    if ( real_depth == 0 ) {	return 0;    }        /* Assume top frame index is 0 for now */    topframe = 0;        /* Possible top frames belong to the hprof Tracker class, remove them */    if ( gdata->bci ) {	while ( ( ( frame_count - topframe ) > 0 ) &&		( topframe < (real_depth-depth) ) &&		( tracker_method(jframes_buffer[topframe].method) || 		  ( skip_init		    && jframes_buffer[topframe].method==gdata->object_init_method ) )	     ) {	    topframe++;	}    }        /* Adjust count to match depth request */    if ( ( frame_count - topframe ) > depth ) {	frame_count =  depth + topframe;    }    /* The actual frame count we will process */    n_frames = frame_count - topframe;    if ( n_frames > 0 ) {	int i;        for (i = 0; i < n_frames; i++) {            jmethodID method;            jlocation location;            method = jframes_buffer[i+topframe].method;            location = jframes_buffer[i+topframe].location;            frames_buffer[i] = frame_find_or_create(method, location);        }    }    return n_frames;}/* Get the trace for the supplied thread */TraceIndextrace_get_current(jthread thread, SerialNumber thread_serial_num,                        int depth, jboolean skip_init,                        FrameIndex *frames_buffer,                        jvmtiFrameInfo *jframes_buffer){    TraceIndex index;    jint       frame_count;    int        real_depth;    int        n_frames;    HPROF_ASSERT(thread!=NULL);    HPROF_ASSERT(frames_buffer!=NULL);    HPROF_ASSERT(jframes_buffer!=NULL);    /* We may need to ask for more frames than the user asked for */    real_depth = get_real_depth(depth, skip_init);    /* Get the stack trace for this one thread */    frame_count = 0;    if ( real_depth > 0 ) {        getStackTrace(thread, jframes_buffer, real_depth, &frame_count);    }        /* Create FrameIndex's */    n_frames = fill_frame_buffer(depth, real_depth, frame_count, skip_init,				 jframes_buffer, frames_buffer);    /* Lookup or create new TraceIndex */    index = find_or_create(thread_serial_num, n_frames, frames_buffer, 		getPhase(), (TraceKey*)jframes_buffer);    return index;}/* Get traces for all threads in list (traces[i]==0 if thread not running) */voidtrace_get_all_current(jint thread_count, jthread *threads, 		      SerialNumber *thread_serial_nums, 		      int depth, jboolean skip_init,                      TraceIndex *traces, jboolean always_care){    jvmtiStackInfo *stack_info;    int             nbytes;    int             real_depth;    int             i;    FrameIndex     *frames_buffer;    TraceKey       *trace_key_buffer;    jvmtiPhase      phase;    HPROF_ASSERT(threads!=NULL);    HPROF_ASSERT(thread_serial_nums!=NULL);    HPROF_ASSERT(traces!=NULL);    HPROF_ASSERT(thread_count > 0);    /* Find out what the phase is for all these traces */    phase = getPhase();    /* We may need to ask for more frames than the user asked for */    real_depth = get_real_depth(depth, skip_init);        /* Get the stack traces for all the threads */    getThreadListStackTraces(thread_count, threads, real_depth, &stack_info);    /* Allocate a frames_buffer and trace key buffer */    nbytes = (int)sizeof(FrameIndex)*real_depth;    frames_buffer = (FrameIndex*)HPROF_MALLOC(nbytes);    nbytes += (int)sizeof(TraceKey);    trace_key_buffer = (TraceKey*)HPROF_MALLOC(nbytes);    /* Loop over the stack traces we have for these 'thread_count' threads */    for ( i = 0 ; i < thread_count ; i++ ) {	int n_frames;	/* Assume 0 at first (no trace) */	traces[i] = 0;	/* If thread has frames, is runnable, and isn't suspended, we care */	if ( always_care || 	     ( stack_info[i].frame_count > 0	       && (stack_info[i].state & JVMTI_THREAD_STATE_RUNNABLE)!=0	       && (stack_info[i].state & JVMTI_THREAD_STATE_SUSPENDED)==0	       && (stack_info[i].state & JVMTI_THREAD_STATE_INTERRUPTED)==0 )	    ) {	    	    /* Create FrameIndex's */	    n_frames = fill_frame_buffer(depth, real_depth,					 stack_info[i].frame_count, 					 skip_init,					 stack_info[i].frame_buffer,					 frames_buffer);	    	    /* Lookup or create new TraceIndex */	    traces[i] = find_or_create(thread_serial_nums[i], 			   n_frames, frames_buffer, phase, trace_key_buffer);        }    }    /* Make sure we free the space */    HPROF_FREE(frames_buffer);    HPROF_FREE(trace_key_buffer);    jvmtiDeallocate(stack_info);}/* Increment the trace costs for all the threads (for cpu=samples) */voidtrace_increment_all_sample_costs(jint thread_count, jthread *threads, 		      SerialNumber *thread_serial_nums, 		      int depth, jboolean skip_init){    TraceIndex *traces;    int         nbytes;    HPROF_ASSERT(threads!=NULL);    HPROF_ASSERT(thread_serial_nums!=NULL);    HPROF_ASSERT(thread_count > 0);    HPROF_ASSERT(depth >= 0);        if ( depth == 0 ) {	return;    }       /* Allocate a traces array */    nbytes = (int)sizeof(TraceIndex)*thread_count;    traces = (TraceIndex*)HPROF_MALLOC(nbytes);    /* Get all the current traces for these threads */    trace_get_all_current(thread_count, threads, thread_serial_nums, 		      depth, skip_init, traces, JNI_FALSE);      /* Increment the cpu=samples cost on these traces */    table_lock_enter(gdata->trace_table); {	int i;	for ( i = 0 ; i < thread_count ; i++ ) {	    /* Each trace gets a hit and an increment of it's total cost */	    if ( traces[i] != 0 ) {		TraceInfo *info;				info              = get_info(traces[i]);		info->num_hits   += 1;	        info->self_cost  += (jlong)1;		info->total_cost += (jlong)1;	    }	}    } table_lock_exit(gdata->trace_table);    /* Free up the memory allocated */    HPROF_FREE(traces);}void trace_output_unmarked(JNIEnv *env){    rawMonitorEnter(gdata->data_access_lock); {        table_walk_items(gdata->trace_table, &output_trace, (void*)env);    } rawMonitorExit(gdata->data_access_lock);}/* output info on the cost associated with traces  */voidtrace_output_cost(JNIEnv *env, double cutoff){    IterateInfo iterate;    int i, trace_table_size, n_items;    double accum;    int n_entries;    rawMonitorEnter(gdata->data_access_lock); {        n_entries = table_element_count(gdata->trace_table);        iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);        iterate.count = 0;        iterate.grand_total_cost = 0;        table_walk_items(gdata->trace_table, &collect_iterator, &iterate);        trace_table_size = iterate.count;        /* sort all the traces according to the cost */        qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),                     &qsort_compare_cost);                n_items = 0;        for (i = 0; i < trace_table_size; i++) {            TraceInfo *info;            TraceIndex trace_index;            double percent;                        trace_index = iterate.traces[i];            info = get_info(trace_index);	    /* As soon as a trace with zero hits is seen, we need no others */            if (info->num_hits == 0 ) {                break;            }            percent = (double)info->self_cost / (double)iterate.grand_total_cost;            if (percent < cutoff) {                break;            }            n_items++;        }                /* Now write all trace we might refer to. */        output_list(env, iterate.traces, n_items);        io_write_cpu_samples_header(iterate.grand_total_cost, n_items);                accum = 0;                        for (i = 0; i < n_items; i++) {            SerialNumber frame_serial_num;	    TraceInfo *info;            TraceKey *key;            TraceIndex trace_index;            double percent;            char *csig;            char *mname;            char *msig;                        trace_index = iterate.traces[i];            info = get_info(trace_index);            key = get_pkey(trace_index);            percent = ((double)info->self_cost / (double)iterate.grand_total_cost) * 100.0;            accum += percent;                        csig = NULL;            mname = NULL;            msig  = NULL;                        if (key->n_frames > 0) {                get_frame_details(env, key->frames[0], &frame_serial_num, 			&csig, NULL, &mname, &msig, NULL, NULL);            }                        io_write_cpu_samples_elem(i+1, percent, accum, info->num_hits,			(jint)info->self_cost, info->serial_num,                        key->n_frames, csig, mname);            	    jvmtiDeallocate(csig);	    jvmtiDeallocate(mname);	    jvmtiDeallocate(msig);        }                io_write_cpu_samples_footer();                HPROF_FREE(iterate.traces);    } rawMonitorExit(gdata->data_access_lock);}/* output the trace cost in old prof format */void trace_output_cost_in_prof_format(JNIEnv *env) {    IterateInfo iterate;    int i, trace_table_size;    int n_entries;    rawMonitorEnter(gdata->data_access_lock); {        n_entries = table_element_count(gdata->trace_table);	iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);        iterate.count = 0;        iterate.grand_total_cost = 0;        table_walk_items(gdata->trace_table, &collect_iterator, &iterate);                trace_table_size = iterate.count;                /* sort all the traces according to the number of hits */        qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),                     &qsort_compare_num_hits);        io_write_oldprof_header();        for (i = 0; i < trace_table_size; i++) {            SerialNumber frame_serial_num;            TraceInfo *info;            TraceKey *key;            TraceIndex trace_index;            int num_frames;            int num_hits;            char *csig_callee;            char *mname_callee;            char *msig_callee;            char *csig_caller;            char *mname_caller;            char *msig_caller;            trace_index = iterate.traces[i];            key = get_pkey(trace_index);            info = get_info(trace_index);            num_hits = info->num_hits;                        if (num_hits == 0) {                break;            }                        csig_callee  = NULL;            mname_callee = NULL;            msig_callee  = NULL;            csig_caller  = NULL;            mname_caller = NULL;            msig_caller  = NULL;                        num_frames = (int)key->n_frames;                        if (num_frames >= 1) {                get_frame_details(env, key->frames[0], &frame_serial_num, 			&csig_callee, NULL,			&mname_callee, &msig_callee, NULL, NULL);            }                        if (num_frames > 1) {                get_frame_details(env, key->frames[1], &frame_serial_num, 			&csig_caller, NULL,			&mname_caller, &msig_caller, NULL, NULL);            }            	    io_write_oldprof_elem(info->num_hits, num_frames,                                       csig_callee, mname_callee, msig_callee,                                    csig_caller, mname_caller, msig_caller,                                    (int)info->total_cost);               	    jvmtiDeallocate(csig_callee);	    jvmtiDeallocate(mname_callee);	    jvmtiDeallocate(msig_callee);	    jvmtiDeallocate(csig_caller);	    jvmtiDeallocate(mname_caller);	    jvmtiDeallocate(msig_caller);        }                io_write_oldprof_footer();                HPROF_FREE(iterate.traces);    } rawMonitorExit(gdata->data_access_lock);}       void trace_clear_cost(void){    table_walk_items(gdata->trace_table, &clear_cost, NULL);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?