00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include "hprof.h"
00061
00062 typedef struct TraceKey {
00063 SerialNumber thread_serial_num;
00064 short n_frames;
00065 jvmtiPhase phase : 8;
00066 FrameIndex frames[1];
00067 } TraceKey;
00068
00069 typedef struct TraceInfo {
00070 SerialNumber serial_num;
00071 jint num_hits;
00072 jlong total_cost;
00073 jlong self_cost;
00074 jint status;
00075 } TraceInfo;
00076
00077 typedef struct IterateInfo {
00078 TraceIndex* traces;
00079 int count;
00080 jlong grand_total_cost;
00081 } IterateInfo;
00082
00083
00084
00085 static TraceKey*
00086 get_pkey(TraceIndex index)
00087 {
00088 void * pkey;
00089 int key_len;
00090
00091 table_get_key(gdata->trace_table, index, &pkey, &key_len);
00092 HPROF_ASSERT(pkey!=NULL);
00093 HPROF_ASSERT(key_len>=(int)sizeof(TraceKey));
00094 HPROF_ASSERT(((TraceKey*)pkey)->n_frames<=1?key_len==(int)sizeof(TraceKey) :
00095 key_len==(int)sizeof(TraceKey)+
00096 (int)sizeof(FrameIndex)*(((TraceKey*)pkey)->n_frames-1));
00097 return (TraceKey*)pkey;
00098 }
00099
00100 static TraceInfo *
00101 get_info(TraceIndex index)
00102 {
00103 TraceInfo * info;
00104
00105 info = (TraceInfo*)table_get_info(gdata->trace_table, index);
00106 return info;
00107 }
00108
00109 static TraceIndex
00110 find_or_create(SerialNumber thread_serial_num, jint n_frames,
00111 FrameIndex *frames, jvmtiPhase phase, TraceKey *trace_key_buffer)
00112 {
00113 TraceInfo * info;
00114 TraceKey * pkey;
00115 int key_len;
00116 TraceIndex index;
00117 jboolean new_one;
00118 static TraceKey empty_key;
00119
00120 HPROF_ASSERT(frames!=NULL);
00121 HPROF_ASSERT(trace_key_buffer!=NULL);
00122 key_len = (int)sizeof(TraceKey);
00123 if ( n_frames > 1 ) {
00124 key_len += (int)((n_frames-1)*(int)sizeof(FrameIndex));
00125 }
00126 pkey = trace_key_buffer;
00127 *pkey = empty_key;
00128 pkey->thread_serial_num = (gdata->thread_in_traces ? thread_serial_num : 0);
00129 pkey->n_frames = (short)n_frames;
00130 pkey->phase = phase;
00131 if ( n_frames > 0 ) {
00132 (void)memcpy(pkey->frames, frames, (n_frames*(int)sizeof(FrameIndex)));
00133 }
00134
00135 new_one = JNI_FALSE;
00136 index = table_find_or_create_entry(gdata->trace_table,
00137 pkey, key_len, &new_one, NULL);
00138 if ( new_one ) {
00139 info = get_info(index);
00140 info->serial_num = gdata->trace_serial_number_counter++;
00141 }
00142 return index;
00143 }
00144
00145 static void
00146 list_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
00147 {
00148 TraceInfo *info;
00149 TraceKey *key;
00150 int i;
00151
00152 HPROF_ASSERT(key_ptr!=NULL);
00153 HPROF_ASSERT(key_len>0);
00154 HPROF_ASSERT(info_ptr!=NULL);
00155 key = (TraceKey*)key_ptr;
00156 info = (TraceInfo *)info_ptr;
00157
00158 debug_message( "Trace 0x%08x: SN=%u, threadSN=%u, n_frames=%d, frames=(",
00159 index,
00160 info->serial_num,
00161 key->thread_serial_num,
00162 key->n_frames);
00163 for ( i = 0 ; i < key->n_frames ; i++ ) {
00164 debug_message( "0x%08x, ", key->frames[i]);
00165 }
00166 debug_message( "), traceSN=%u, num_hits=%d, self_cost=(%d,%d), "
00167 "total_cost=(%d,%d), status=0x%08x\n",
00168 info->serial_num,
00169 info->num_hits,
00170 jlong_high(info->self_cost),
00171 jlong_low(info->self_cost),
00172 jlong_high(info->total_cost),
00173 jlong_low(info->total_cost),
00174 info->status);
00175 }
00176
00177 static void
00178 clear_cost(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00179 {
00180 TraceInfo *info;
00181
00182 HPROF_ASSERT(key_ptr!=NULL);
00183 HPROF_ASSERT(key_len>0);
00184 HPROF_ASSERT(info_ptr!=NULL);
00185 info = (TraceInfo *)info_ptr;
00186 info->num_hits = 0;
00187 info->total_cost = 0;
00188 info->self_cost = 0;
00189 }
00190
00191
00192 static void
00193 get_frame_details(JNIEnv *env, FrameIndex frame_index,
00194 SerialNumber *frame_serial_num, char **pcsig, ClassIndex *pcnum,
00195 char **pmname, char **pmsig, char **psname, jint *plineno)
00196 {
00197 jmethodID method;
00198 jlocation location;
00199 jint lineno;
00200
00201 HPROF_ASSERT(frame_index!=0);
00202 *pmname = NULL;
00203 *pmsig = NULL;
00204 *pcsig = NULL;
00205 if ( psname != NULL ) {
00206 *psname = NULL;
00207 }
00208 if ( plineno != NULL ) {
00209 *plineno = -1;
00210 }
00211 if ( pcnum != NULL ) {
00212 *pcnum = 0;
00213 }
00214 frame_get_location(frame_index, frame_serial_num, &method, &location, &lineno);
00215 if ( plineno != NULL ) {
00216 *plineno = lineno;
00217 }
00218 WITH_LOCAL_REFS(env, 1) {
00219 jclass klass;
00220
00221 getMethodClass(method, &klass);
00222 getClassSignature(klass, pcsig, NULL);
00223 if ( pcnum != NULL ) {
00224 LoaderIndex loader_index;
00225 jobject loader;
00226
00227 loader = getClassLoader(klass);
00228 loader_index = loader_find_or_create(env, loader);
00229 *pcnum = class_find_or_create(*pcsig, loader_index);
00230 (void)class_new_classref(env, *pcnum, klass);
00231 }
00232 if ( psname != NULL ) {
00233 getSourceFileName(klass, psname);
00234 }
00235 } END_WITH_LOCAL_REFS;
00236 getMethodName(method, pmname, pmsig);
00237 }
00238
00239
00240 static void
00241 output_trace(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
00242 {
00243 TraceKey *key;
00244 TraceInfo *info;
00245 SerialNumber serial_num;
00246 SerialNumber thread_serial_num;
00247 jint n_frames;
00248 JNIEnv *env;
00249 int i;
00250 char *phase_str;
00251 struct FrameNames {
00252 SerialNumber serial_num;
00253 char * sname;
00254 char * csig;
00255 char * mname;
00256 int lineno;
00257 } *finfo;
00258
00259 info = (TraceInfo*)info_ptr;
00260 if ( info->status != 0 ) {
00261 return;
00262 }
00263
00264 env = (JNIEnv*)arg;
00265
00266 key = (TraceKey*)key_ptr;
00267 thread_serial_num = key->thread_serial_num;
00268 serial_num = info->serial_num;
00269 info->status = 1;
00270 finfo = NULL;
00271
00272 n_frames = (jint)key->n_frames;
00273 if ( n_frames > 0 ) {
00274 finfo = (struct FrameNames *)HPROF_MALLOC(n_frames*(int)sizeof(struct FrameNames));
00275
00276
00277 for (i = 0; i < n_frames; i++) {
00278 FrameIndex frame_index;
00279 char *msig;
00280 ClassIndex cnum;
00281
00282 frame_index = key->frames[i];
00283 get_frame_details(env, frame_index, &finfo[i].serial_num,
00284 &finfo[i].csig, &cnum,
00285 &finfo[i].mname, &msig, &finfo[i].sname, &finfo[i].lineno);
00286
00287 if (frame_get_status(frame_index) == 0) {
00288 io_write_frame(frame_index, finfo[i].serial_num,
00289 finfo[i].mname, msig,
00290 finfo[i].sname, class_get_serial_number(cnum),
00291 finfo[i].lineno);
00292 frame_set_status(frame_index, 1);
00293 }
00294 jvmtiDeallocate(msig);
00295 }
00296 }
00297
00298
00299 if ( key->phase == JVMTI_PHASE_LIVE ) {
00300 phase_str = NULL;
00301 } else {
00302 phase_str = phaseString(key->phase);
00303 }
00304
00305 io_write_trace_header(serial_num, thread_serial_num, n_frames, phase_str);
00306
00307 for (i = 0; i < n_frames; i++) {
00308 io_write_trace_elem(serial_num, key->frames[i], finfo[i].serial_num,
00309 finfo[i].csig,
00310 finfo[i].mname, finfo[i].sname, finfo[i].lineno);
00311 jvmtiDeallocate(finfo[i].csig);
00312 jvmtiDeallocate(finfo[i].mname);
00313 jvmtiDeallocate(finfo[i].sname);
00314 }
00315
00316 io_write_trace_footer(serial_num, thread_serial_num, n_frames);
00317
00318 if ( finfo != NULL ) {
00319 HPROF_FREE(finfo);
00320 }
00321 }
00322
00323
00324 static void
00325 output_list(JNIEnv *env, TraceIndex *list, jint count)
00326 {
00327 rawMonitorEnter(gdata->data_access_lock); {
00328 int i;
00329
00330 for ( i = 0; i < count ; i++ ) {
00331 TraceIndex index;
00332 TraceInfo *info;
00333 void * pkey;
00334 int key_len;
00335
00336 index = list[i];
00337 table_get_key(gdata->trace_table, index, &pkey, &key_len);
00338 info = get_info(index);
00339 output_trace(index, pkey, key_len, info, (void*)env);
00340 }
00341 } rawMonitorExit(gdata->data_access_lock);
00342 }
00343
00344 static void
00345 collect_iterator(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
00346 {
00347 TraceInfo *info;
00348 IterateInfo *iterate;
00349
00350 HPROF_ASSERT(key_ptr!=NULL);
00351 HPROF_ASSERT(key_len>0);
00352 HPROF_ASSERT(arg!=NULL);
00353 HPROF_ASSERT(info_ptr!=NULL);
00354 iterate = (IterateInfo *)arg;
00355 info = (TraceInfo *)info_ptr;
00356 iterate->traces[iterate->count++] = index;
00357 iterate->grand_total_cost += info->self_cost;
00358 }
00359
00360 static int
00361 qsort_compare_cost(const void *p_trace1, const void *p_trace2)
00362 {
00363 TraceIndex trace1;
00364 TraceIndex trace2;
00365 TraceInfo * info1;
00366 TraceInfo * info2;
00367
00368 HPROF_ASSERT(p_trace1!=NULL);
00369 HPROF_ASSERT(p_trace2!=NULL);
00370 trace1 = *(TraceIndex *)p_trace1;
00371 trace2 = *(TraceIndex *)p_trace2;
00372 info1 = get_info(trace1);
00373 info2 = get_info(trace2);
00374
00375 return (int)(info2->self_cost - info1->self_cost);
00376 }
00377
00378 static int
00379 qsort_compare_num_hits(const void *p_trace1, const void *p_trace2)
00380 {
00381 TraceIndex trace1;
00382 TraceIndex trace2;
00383 TraceInfo * info1;
00384 TraceInfo * info2;
00385
00386 HPROF_ASSERT(p_trace1!=NULL);
00387 HPROF_ASSERT(p_trace2!=NULL);
00388 trace1 = *(TraceIndex *)p_trace1;
00389 trace2 = *(TraceIndex *)p_trace2;
00390 info1 = get_info(trace1);
00391 info2 = get_info(trace2);
00392 return info2->num_hits - info1->num_hits;
00393 }
00394
00395
00396
00397 void
00398 trace_init(void)
00399 {
00400 gdata->trace_table = table_initialize("Trace",
00401 256, 256, 511, (int)sizeof(TraceInfo));
00402 }
00403
00404 void
00405 trace_list(void)
00406 {
00407 debug_message(
00408 "--------------------- Trace Table ------------------------\n");
00409 table_walk_items(gdata->trace_table, &list_item, NULL);
00410 debug_message(
00411 "----------------------------------------------------------\n");
00412 }
00413
00414 void
00415 trace_cleanup(void)
00416 {
00417 table_cleanup(gdata->trace_table, NULL, NULL);
00418 gdata->trace_table = NULL;
00419 }
00420
00421 SerialNumber
00422 trace_get_serial_number(TraceIndex index)
00423 {
00424 TraceInfo *info;
00425
00426 if ( index == 0 ) {
00427 return 0;
00428 }
00429 info = get_info(index);
00430 return info->serial_num;
00431 }
00432
00433 void
00434 trace_increment_cost(TraceIndex index, jint num_hits, jlong self_cost, jlong total_cost)
00435 {
00436 TraceInfo *info;
00437
00438 table_lock_enter(gdata->trace_table); {
00439 info = get_info(index);
00440 info->num_hits += num_hits;
00441 info->self_cost += self_cost;
00442 info->total_cost += total_cost;
00443 } table_lock_exit(gdata->trace_table);
00444 }
00445
00446 TraceIndex
00447 trace_find_or_create(SerialNumber thread_serial_num, jint n_frames, FrameIndex *frames, jvmtiFrameInfo *jframes_buffer)
00448 {
00449 return find_or_create(thread_serial_num, n_frames, frames, getPhase(),
00450 (TraceKey*)jframes_buffer);
00451 }
00452
00453
00454 static int
00455 get_real_depth(int depth, jboolean skip_init)
00456 {
00457 int extra_frames;
00458
00459 extra_frames = 0;
00460
00461 if ( gdata->bci && depth > 0 ) {
00462
00463 extra_frames = 2;
00464 if ( skip_init ) {
00465
00466 extra_frames += 1;
00467 }
00468 }
00469 return depth + extra_frames;
00470 }
00471
00472
00473 static int
00474 fill_frame_buffer(int depth, int real_depth,
00475 int frame_count, jboolean skip_init,
00476 jvmtiFrameInfo *jframes_buffer, FrameIndex *frames_buffer)
00477 {
00478 int n_frames;
00479 jint topframe;
00480
00481
00482 if ( real_depth == 0 ) {
00483 return 0;
00484 }
00485
00486
00487 topframe = 0;
00488
00489
00490 if ( gdata->bci ) {
00491 while ( ( ( frame_count - topframe ) > 0 ) &&
00492 ( topframe < (real_depth-depth) ) &&
00493 ( tracker_method(jframes_buffer[topframe].method) ||
00494 ( skip_init
00495 && jframes_buffer[topframe].method==gdata->object_init_method ) )
00496 ) {
00497 topframe++;
00498 }
00499 }
00500
00501
00502 if ( ( frame_count - topframe ) > depth ) {
00503 frame_count = depth + topframe;
00504 }
00505
00506
00507 n_frames = frame_count - topframe;
00508 if ( n_frames > 0 ) {
00509 int i;
00510
00511 for (i = 0; i < n_frames; i++) {
00512 jmethodID method;
00513 jlocation location;
00514
00515 method = jframes_buffer[i+topframe].method;
00516 location = jframes_buffer[i+topframe].location;
00517 frames_buffer[i] = frame_find_or_create(method, location);
00518 }
00519 }
00520 return n_frames;
00521 }
00522
00523
00524 TraceIndex
00525 trace_get_current(jthread thread, SerialNumber thread_serial_num,
00526 int depth, jboolean skip_init,
00527 FrameIndex *frames_buffer,
00528 jvmtiFrameInfo *jframes_buffer)
00529 {
00530 TraceIndex index;
00531 jint frame_count;
00532 int real_depth;
00533 int n_frames;
00534
00535 HPROF_ASSERT(thread!=NULL);
00536 HPROF_ASSERT(frames_buffer!=NULL);
00537 HPROF_ASSERT(jframes_buffer!=NULL);
00538
00539
00540 real_depth = get_real_depth(depth, skip_init);
00541
00542
00543 frame_count = 0;
00544 if ( real_depth > 0 ) {
00545 getStackTrace(thread, jframes_buffer, real_depth, &frame_count);
00546 }
00547
00548
00549 n_frames = fill_frame_buffer(depth, real_depth, frame_count, skip_init,
00550 jframes_buffer, frames_buffer);
00551
00552
00553 index = find_or_create(thread_serial_num, n_frames, frames_buffer,
00554 getPhase(), (TraceKey*)jframes_buffer);
00555 return index;
00556 }
00557
00558
00559 void
00560 trace_get_all_current(jint thread_count, jthread *threads,
00561 SerialNumber *thread_serial_nums,
00562 int depth, jboolean skip_init,
00563 TraceIndex *traces, jboolean always_care)
00564 {
00565 jvmtiStackInfo *stack_info;
00566 int nbytes;
00567 int real_depth;
00568 int i;
00569 FrameIndex *frames_buffer;
00570 TraceKey *trace_key_buffer;
00571 jvmtiPhase phase;
00572
00573 HPROF_ASSERT(threads!=NULL);
00574 HPROF_ASSERT(thread_serial_nums!=NULL);
00575 HPROF_ASSERT(traces!=NULL);
00576 HPROF_ASSERT(thread_count > 0);
00577
00578
00579 phase = getPhase();
00580
00581
00582 real_depth = get_real_depth(depth, skip_init);
00583
00584
00585 getThreadListStackTraces(thread_count, threads, real_depth, &stack_info);
00586
00587
00588 nbytes = (int)sizeof(FrameIndex)*real_depth;
00589 frames_buffer = (FrameIndex*)HPROF_MALLOC(nbytes);
00590 nbytes += (int)sizeof(TraceKey);
00591 trace_key_buffer = (TraceKey*)HPROF_MALLOC(nbytes);
00592
00593
00594 for ( i = 0 ; i < thread_count ; i++ ) {
00595 int n_frames;
00596
00597
00598 traces[i] = 0;
00599
00600
00601 if ( always_care ||
00602 ( stack_info[i].frame_count > 0
00603 && (stack_info[i].state & JVMTI_THREAD_STATE_RUNNABLE)!=0
00604 && (stack_info[i].state & JVMTI_THREAD_STATE_SUSPENDED)==0
00605 && (stack_info[i].state & JVMTI_THREAD_STATE_INTERRUPTED)==0 )
00606 ) {
00607
00608
00609 n_frames = fill_frame_buffer(depth, real_depth,
00610 stack_info[i].frame_count,
00611 skip_init,
00612 stack_info[i].frame_buffer,
00613 frames_buffer);
00614
00615
00616 traces[i] = find_or_create(thread_serial_nums[i],
00617 n_frames, frames_buffer, phase, trace_key_buffer);
00618 }
00619 }
00620
00621
00622 HPROF_FREE(frames_buffer);
00623 HPROF_FREE(trace_key_buffer);
00624 jvmtiDeallocate(stack_info);
00625 }
00626
00627
00628 void
00629 trace_increment_all_sample_costs(jint thread_count, jthread *threads,
00630 SerialNumber *thread_serial_nums,
00631 int depth, jboolean skip_init)
00632 {
00633 TraceIndex *traces;
00634 int nbytes;
00635
00636 HPROF_ASSERT(threads!=NULL);
00637 HPROF_ASSERT(thread_serial_nums!=NULL);
00638 HPROF_ASSERT(thread_count > 0);
00639 HPROF_ASSERT(depth >= 0);
00640
00641 if ( depth == 0 ) {
00642 return;
00643 }
00644
00645
00646 nbytes = (int)sizeof(TraceIndex)*thread_count;
00647 traces = (TraceIndex*)HPROF_MALLOC(nbytes);
00648
00649
00650 trace_get_all_current(thread_count, threads, thread_serial_nums,
00651 depth, skip_init, traces, JNI_FALSE);
00652
00653
00654 table_lock_enter(gdata->trace_table); {
00655 int i;
00656
00657 for ( i = 0 ; i < thread_count ; i++ ) {
00658
00659 if ( traces[i] != 0 ) {
00660 TraceInfo *info;
00661
00662 info = get_info(traces[i]);
00663 info->num_hits += 1;
00664 info->self_cost += (jlong)1;
00665 info->total_cost += (jlong)1;
00666 }
00667 }
00668 } table_lock_exit(gdata->trace_table);
00669
00670
00671 HPROF_FREE(traces);
00672 }
00673
00674 void
00675 trace_output_unmarked(JNIEnv *env)
00676 {
00677 rawMonitorEnter(gdata->data_access_lock); {
00678 table_walk_items(gdata->trace_table, &output_trace, (void*)env);
00679 } rawMonitorExit(gdata->data_access_lock);
00680 }
00681
00682
00683 void
00684 trace_output_cost(JNIEnv *env, double cutoff)
00685 {
00686 IterateInfo iterate;
00687 int i, trace_table_size, n_items;
00688 double accum;
00689 int n_entries;
00690
00691 rawMonitorEnter(gdata->data_access_lock); {
00692
00693 n_entries = table_element_count(gdata->trace_table);
00694 iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);
00695 iterate.count = 0;
00696 iterate.grand_total_cost = 0;
00697 table_walk_items(gdata->trace_table, &collect_iterator, &iterate);
00698
00699 trace_table_size = iterate.count;
00700
00701
00702 qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),
00703 &qsort_compare_cost);
00704
00705 n_items = 0;
00706 for (i = 0; i < trace_table_size; i++) {
00707 TraceInfo *info;
00708 TraceIndex trace_index;
00709 double percent;
00710
00711 trace_index = iterate.traces[i];
00712 info = get_info(trace_index);
00713
00714 if (info->num_hits == 0 ) {
00715 break;
00716 }
00717 percent = (double)info->self_cost / (double)iterate.grand_total_cost;
00718 if (percent < cutoff) {
00719 break;
00720 }
00721 n_items++;
00722 }
00723
00724
00725 output_list(env, iterate.traces, n_items);
00726
00727 io_write_cpu_samples_header(iterate.grand_total_cost, n_items);
00728
00729 accum = 0;
00730
00731 for (i = 0; i < n_items; i++) {
00732 SerialNumber frame_serial_num;
00733 TraceInfo *info;
00734 TraceKey *key;
00735 TraceIndex trace_index;
00736 double percent;
00737 char *csig;
00738 char *mname;
00739 char *msig;
00740
00741 trace_index = iterate.traces[i];
00742 info = get_info(trace_index);
00743 key = get_pkey(trace_index);
00744 percent = ((double)info->self_cost / (double)iterate.grand_total_cost) * 100.0;
00745 accum += percent;
00746
00747 csig = NULL;
00748 mname = NULL;
00749 msig = NULL;
00750
00751 if (key->n_frames > 0) {
00752 get_frame_details(env, key->frames[0], &frame_serial_num,
00753 &csig, NULL, &mname, &msig, NULL, NULL);
00754 }
00755
00756 io_write_cpu_samples_elem(i+1, percent, accum, info->num_hits,
00757 (jint)info->self_cost, info->serial_num,
00758 key->n_frames, csig, mname);
00759
00760 jvmtiDeallocate(csig);
00761 jvmtiDeallocate(mname);
00762 jvmtiDeallocate(msig);
00763 }
00764
00765 io_write_cpu_samples_footer();
00766
00767 HPROF_FREE(iterate.traces);
00768
00769 } rawMonitorExit(gdata->data_access_lock);
00770
00771 }
00772
00773
00774 void
00775 trace_output_cost_in_prof_format(JNIEnv *env)
00776 {
00777 IterateInfo iterate;
00778 int i, trace_table_size;
00779 int n_entries;
00780
00781 rawMonitorEnter(gdata->data_access_lock); {
00782
00783 n_entries = table_element_count(gdata->trace_table);
00784 iterate.traces = HPROF_MALLOC(n_entries*(int)sizeof(TraceIndex)+1);
00785 iterate.count = 0;
00786 iterate.grand_total_cost = 0;
00787 table_walk_items(gdata->trace_table, &collect_iterator, &iterate);
00788
00789 trace_table_size = iterate.count;
00790
00791
00792 qsort(iterate.traces, trace_table_size, sizeof(TraceIndex),
00793 &qsort_compare_num_hits);
00794
00795 io_write_oldprof_header();
00796
00797 for (i = 0; i < trace_table_size; i++) {
00798 SerialNumber frame_serial_num;
00799 TraceInfo *info;
00800 TraceKey *key;
00801 TraceIndex trace_index;
00802 int num_frames;
00803 int num_hits;
00804 char *csig_callee;
00805 char *mname_callee;
00806 char *msig_callee;
00807 char *csig_caller;
00808 char *mname_caller;
00809 char *msig_caller;
00810
00811 trace_index = iterate.traces[i];
00812 key = get_pkey(trace_index);
00813 info = get_info(trace_index);
00814 num_hits = info->num_hits;
00815
00816 if (num_hits == 0) {
00817 break;
00818 }
00819
00820 csig_callee = NULL;
00821 mname_callee = NULL;
00822 msig_callee = NULL;
00823 csig_caller = NULL;
00824 mname_caller = NULL;
00825 msig_caller = NULL;
00826
00827 num_frames = (int)key->n_frames;
00828
00829 if (num_frames >= 1) {
00830 get_frame_details(env, key->frames[0], &frame_serial_num,
00831 &csig_callee, NULL,
00832 &mname_callee, &msig_callee, NULL, NULL);
00833 }
00834
00835 if (num_frames > 1) {
00836 get_frame_details(env, key->frames[1], &frame_serial_num,
00837 &csig_caller, NULL,
00838 &mname_caller, &msig_caller, NULL, NULL);
00839 }
00840
00841 io_write_oldprof_elem(info->num_hits, num_frames,
00842 csig_callee, mname_callee, msig_callee,
00843 csig_caller, mname_caller, msig_caller,
00844 (int)info->total_cost);
00845
00846 jvmtiDeallocate(csig_callee);
00847 jvmtiDeallocate(mname_callee);
00848 jvmtiDeallocate(msig_callee);
00849 jvmtiDeallocate(csig_caller);
00850 jvmtiDeallocate(mname_caller);
00851 jvmtiDeallocate(msig_caller);
00852 }
00853
00854 io_write_oldprof_footer();
00855
00856 HPROF_FREE(iterate.traces);
00857
00858 } rawMonitorExit(gdata->data_access_lock);
00859 }
00860
00861 void
00862 trace_clear_cost(void)
00863 {
00864 table_walk_items(gdata->trace_table, &clear_cost, NULL);
00865 }
00866