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
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include "hprof.h"
00077
00078 typedef TableIndex HprofId;
00079
00080 #include "hprof_ioname.h"
00081 #include "hprof_b_spec.h"
00082
00083 static int type_size[ ] = HPROF_TYPE_SIZES;
00084
00085 static void dump_heap_segment_and_reset(jlong segment_size);
00086
00087 static void
00088 not_implemented(void)
00089 {
00090 }
00091
00092 static IoNameIndex
00093 get_name_index(char *name)
00094 {
00095 if (name != NULL && gdata->output_format == 'b') {
00096 return ioname_find_or_create(name, NULL);
00097 }
00098 return 0;
00099 }
00100
00101 static char *
00102 signature_to_name(char *sig)
00103 {
00104 char *ptr;
00105 char *basename;
00106 char *name;
00107 int i;
00108 int len;
00109 int name_len;
00110
00111 if ( sig != NULL ) {
00112 switch ( sig[0] ) {
00113 case JVM_SIGNATURE_CLASS:
00114 ptr = strchr(sig+1, JVM_SIGNATURE_ENDCLASS);
00115 if ( ptr == NULL ) {
00116 basename = "Unknown_class";
00117 break;
00118 }
00119
00120 name_len = (jint)(ptr - (sig+1));
00121 name = HPROF_MALLOC(name_len+1);
00122 (void)memcpy(name, sig+1, name_len);
00123 name[name_len] = 0;
00124 for ( i = 0 ; i < name_len ; i++ ) {
00125 if ( name[i] == '/' ) name[i] = '.';
00126 }
00127 return name;
00128 case JVM_SIGNATURE_ARRAY:
00129 basename = signature_to_name(sig+1);
00130 len = (int)strlen(basename);
00131 name_len = len+2;
00132 name = HPROF_MALLOC(name_len+1);
00133 (void)memcpy(name, basename, len);
00134 (void)memcpy(name+len, "[]", 2);
00135 name[name_len] = 0;
00136 HPROF_FREE(basename);
00137 return name;
00138 case JVM_SIGNATURE_FUNC:
00139 ptr = strchr(sig+1, JVM_SIGNATURE_ENDFUNC);
00140 if ( ptr == NULL ) {
00141 basename = "Unknown_method";
00142 break;
00143 }
00144 basename = "()";
00145 break;
00146 case JVM_SIGNATURE_BYTE:
00147 basename = "byte";
00148 break;
00149 case JVM_SIGNATURE_CHAR:
00150 basename = "char";
00151 break;
00152 case JVM_SIGNATURE_ENUM:
00153 basename = "enum";
00154 break;
00155 case JVM_SIGNATURE_FLOAT:
00156 basename = "float";
00157 break;
00158 case JVM_SIGNATURE_DOUBLE:
00159 basename = "double";
00160 break;
00161 case JVM_SIGNATURE_INT:
00162 basename = "int";
00163 break;
00164 case JVM_SIGNATURE_LONG:
00165 basename = "long";
00166 break;
00167 case JVM_SIGNATURE_SHORT:
00168 basename = "short";
00169 break;
00170 case JVM_SIGNATURE_VOID:
00171 basename = "void";
00172 break;
00173 case JVM_SIGNATURE_BOOLEAN:
00174 basename = "boolean";
00175 break;
00176 default:
00177 basename = "Unknown_class";
00178 break;
00179 }
00180 } else {
00181 basename = "Unknown_class";
00182 }
00183
00184
00185 name_len = (int)strlen(basename);
00186 name = HPROF_MALLOC(name_len+1);
00187 (void)strcpy(name, basename);
00188 return name;
00189 }
00190
00191 static int
00192 size_from_field_info(int size)
00193 {
00194 if ( size == 0 ) {
00195 size = (int)sizeof(HprofId);
00196 }
00197 return size;
00198 }
00199
00200 static void
00201 type_from_signature(const char *sig, HprofType *kind, jint *size)
00202 {
00203 *kind = HPROF_NORMAL_OBJECT;
00204 *size = 0;
00205 switch ( sig[0] ) {
00206 case JVM_SIGNATURE_ENUM:
00207 case JVM_SIGNATURE_CLASS:
00208 case JVM_SIGNATURE_ARRAY:
00209 *kind = HPROF_NORMAL_OBJECT;
00210 break;
00211 case JVM_SIGNATURE_BOOLEAN:
00212 *kind = HPROF_BOOLEAN;
00213 break;
00214 case JVM_SIGNATURE_CHAR:
00215 *kind = HPROF_CHAR;
00216 break;
00217 case JVM_SIGNATURE_FLOAT:
00218 *kind = HPROF_FLOAT;
00219 break;
00220 case JVM_SIGNATURE_DOUBLE:
00221 *kind = HPROF_DOUBLE;
00222 break;
00223 case JVM_SIGNATURE_BYTE:
00224 *kind = HPROF_BYTE;
00225 break;
00226 case JVM_SIGNATURE_SHORT:
00227 *kind = HPROF_SHORT;
00228 break;
00229 case JVM_SIGNATURE_INT:
00230 *kind = HPROF_INT;
00231 break;
00232 case JVM_SIGNATURE_LONG:
00233 *kind = HPROF_LONG;
00234 break;
00235 default:
00236 HPROF_ASSERT(0);
00237 break;
00238 }
00239 *size = type_size[*kind];
00240 }
00241
00242 static void
00243 type_array(const char *sig, HprofType *kind, jint *elem_size)
00244 {
00245 *kind = 0;
00246 *elem_size = 0;
00247 switch ( sig[0] ) {
00248 case JVM_SIGNATURE_ARRAY:
00249 type_from_signature(sig+1, kind, elem_size);
00250 break;
00251 }
00252 }
00253
00254 static void
00255 system_error(const char *system_call, int rc, int errnum)
00256 {
00257 char buf[256];
00258 char details[256];
00259
00260 details[0] = 0;
00261 if ( errnum != 0 ) {
00262 md_system_error(details, (int)sizeof(details));
00263 } else if ( rc >= 0 ) {
00264 (void)strcpy(details,"Only part of buffer processed");
00265 }
00266 if ( details[0] == 0 ) {
00267 (void)strcpy(details,"Unknown system error condition");
00268 }
00269 (void)md_snprintf(buf, sizeof(buf), "System %s failed: %s\n",
00270 system_call, details);
00271 HPROF_ERROR(JNI_TRUE, buf);
00272 }
00273
00274 static void
00275 system_write(int fd, void *buf, int len, jboolean socket)
00276 {
00277 int res;
00278
00279 HPROF_ASSERT(fd>=0);
00280 if (socket) {
00281 res = md_send(fd, buf, len, 0);
00282 if (res < 0 || res!=len) {
00283 system_error("send", res, errno);
00284 }
00285 } else {
00286 res = md_write(fd, buf, len);
00287 if (res < 0 || res!=len) {
00288 system_error("write", res, errno);
00289 }
00290 }
00291 }
00292
00293 static void
00294 write_flush(void)
00295 {
00296 HPROF_ASSERT(gdata->fd >= 0);
00297 if (gdata->write_buffer_index) {
00298 system_write(gdata->fd, gdata->write_buffer, gdata->write_buffer_index,
00299 gdata->socket);
00300 gdata->write_buffer_index = 0;
00301 }
00302 }
00303
00304 static void
00305 heap_flush(void)
00306 {
00307 HPROF_ASSERT(gdata->heap_fd >= 0);
00308 if (gdata->heap_buffer_index) {
00309 gdata->heap_write_count += (jlong)gdata->heap_buffer_index;
00310 system_write(gdata->heap_fd, gdata->heap_buffer, gdata->heap_buffer_index,
00311 JNI_FALSE);
00312 gdata->heap_buffer_index = 0;
00313 }
00314 }
00315
00316 static void
00317 write_raw(void *buf, int len)
00318 {
00319 HPROF_ASSERT(gdata->fd >= 0);
00320 if (gdata->write_buffer_index + len > gdata->write_buffer_size) {
00321 write_flush();
00322 if (len > gdata->write_buffer_size) {
00323 system_write(gdata->fd, buf, len, gdata->socket);
00324 return;
00325 }
00326 }
00327 (void)memcpy(gdata->write_buffer + gdata->write_buffer_index, buf, len);
00328 gdata->write_buffer_index += len;
00329 }
00330
00331 static void
00332 write_u4(unsigned i)
00333 {
00334 i = md_htonl(i);
00335 write_raw(&i, (jint)sizeof(unsigned));
00336 }
00337
00338 static void
00339 write_u8(jlong t)
00340 {
00341 write_u4((jint)jlong_high(t));
00342 write_u4((jint)jlong_low(t));
00343 }
00344
00345 static void
00346 write_u2(unsigned short i)
00347 {
00348 i = md_htons(i);
00349 write_raw(&i, (jint)sizeof(unsigned short));
00350 }
00351
00352 static void
00353 write_u1(unsigned char i)
00354 {
00355 write_raw(&i, (jint)sizeof(unsigned char));
00356 }
00357
00358 static void
00359 write_id(HprofId i)
00360 {
00361 write_u4(i);
00362 }
00363
00364 static void
00365 write_current_ticks(void)
00366 {
00367 write_u4((jint)(md_get_microsecs() - gdata->micro_sec_ticks));
00368 }
00369
00370 static void
00371 write_header(unsigned char type, jint length)
00372 {
00373 write_u1(type);
00374 write_current_ticks();
00375 write_u4(length);
00376 }
00377
00378 static void
00379 write_index_id(HprofId index)
00380 {
00381 write_id(index);
00382 }
00383
00384 static IoNameIndex
00385 write_name_first(char *name)
00386 {
00387 if ( name == NULL ) {
00388 return 0;
00389 }
00390 if (gdata->output_format == 'b') {
00391 IoNameIndex name_index;
00392 jboolean new_one;
00393
00394 new_one = JNI_FALSE;
00395 name_index = ioname_find_or_create(name, &new_one);
00396 if ( new_one ) {
00397 int len;
00398
00399 len = (int)strlen(name);
00400 write_header(HPROF_UTF8, len + (jint)sizeof(HprofId));
00401 write_index_id(name_index);
00402 write_raw(name, len);
00403
00404 }
00405 return name_index;
00406 }
00407 return 0;
00408 }
00409
00410 static void
00411 write_printf(char *fmt, ...)
00412 {
00413 char buf[1024];
00414 va_list args;
00415 va_start(args, fmt);
00416 (void)md_vsnprintf(buf, sizeof(buf), fmt, args);
00417 buf[sizeof(buf)-1] = 0;
00418 write_raw(buf, (int)strlen(buf));
00419 va_end(args);
00420 }
00421
00422 static void
00423 write_thread_serial_number(SerialNumber thread_serial_num, int with_comma)
00424 {
00425 if ( thread_serial_num != 0 ) {
00426 CHECK_THREAD_SERIAL_NO(thread_serial_num);
00427 if ( with_comma ) {
00428 write_printf(" thread %d,", thread_serial_num);
00429 } else {
00430 write_printf(" thread %d", thread_serial_num);
00431 }
00432 } else {
00433 if ( with_comma ) {
00434 write_printf(" <unknown thread>,");
00435 } else {
00436 write_printf(" <unknown thread>");
00437 }
00438 }
00439 }
00440
00441 static void
00442 heap_raw(void *buf, int len)
00443 {
00444 HPROF_ASSERT(gdata->heap_fd >= 0);
00445 if (gdata->heap_buffer_index + len > gdata->heap_buffer_size) {
00446 heap_flush();
00447 if (len > gdata->heap_buffer_size) {
00448 gdata->heap_write_count += (jlong)len;
00449 system_write(gdata->heap_fd, buf, len, JNI_FALSE);
00450 return;
00451 }
00452 }
00453 (void)memcpy(gdata->heap_buffer + gdata->heap_buffer_index, buf, len);
00454 gdata->heap_buffer_index += len;
00455 }
00456
00457 static void
00458 heap_u4(unsigned i)
00459 {
00460 i = md_htonl(i);
00461 heap_raw(&i, (jint)sizeof(unsigned));
00462 }
00463
00464 static void
00465 heap_u8(jlong i)
00466 {
00467 heap_u4((jint)jlong_high(i));
00468 heap_u4((jint)jlong_low(i));
00469 }
00470
00471 static void
00472 heap_u2(unsigned short i)
00473 {
00474 i = md_htons(i);
00475 heap_raw(&i, (jint)sizeof(unsigned short));
00476 }
00477
00478 static void
00479 heap_u1(unsigned char i)
00480 {
00481 heap_raw(&i, (jint)sizeof(unsigned char));
00482 }
00483
00484
00485 static void
00486 heap_tag(unsigned char tag)
00487 {
00488 jlong pos;
00489
00490
00491 pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
00492 if ( gdata->segmented == JNI_TRUE ) {
00493 if ( pos >= gdata->maxHeapSegment ) {
00494
00495 heap_flush();
00496
00497
00498 dump_heap_segment_and_reset(gdata->heap_last_tag_position);
00499
00500
00501 pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
00502 }
00503 }
00504
00505 gdata->heap_last_tag_position = pos;
00506
00507 heap_u1(tag);
00508 }
00509
00510 static void
00511 heap_id(HprofId i)
00512 {
00513 heap_u4(i);
00514 }
00515
00516 static void
00517 heap_index_id(HprofId index)
00518 {
00519 heap_id(index);
00520 }
00521
00522 static void
00523 heap_name(char *name)
00524 {
00525 heap_index_id(get_name_index(name));
00526 }
00527
00528 static void
00529 heap_printf(char *fmt, ...)
00530 {
00531 char buf[1024];
00532 va_list args;
00533 va_start(args, fmt);
00534 (void)md_vsnprintf(buf, sizeof(buf), fmt, args);
00535 buf[sizeof(buf)-1] = 0;
00536 heap_raw(buf, (int)strlen(buf));
00537 va_end(args);
00538 }
00539
00540 static void
00541 heap_element(HprofType kind, jint size, jvalue value)
00542 {
00543 if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
00544 HPROF_ASSERT(size==4);
00545 heap_id((HprofId)value.i);
00546 } else {
00547 switch ( size ) {
00548 case 8:
00549 HPROF_ASSERT(size==8);
00550 HPROF_ASSERT(kind==HPROF_LONG || kind==HPROF_DOUBLE);
00551 heap_u8(value.j);
00552 break;
00553 case 4:
00554 HPROF_ASSERT(size==4);
00555 HPROF_ASSERT(kind==HPROF_INT || kind==HPROF_FLOAT);
00556 heap_u4(value.i);
00557 break;
00558 case 2:
00559 HPROF_ASSERT(size==2);
00560 HPROF_ASSERT(kind==HPROF_SHORT || kind==HPROF_CHAR);
00561 heap_u2(value.s);
00562 break;
00563 case 1:
00564 HPROF_ASSERT(size==1);
00565 HPROF_ASSERT(kind==HPROF_BOOLEAN || kind==HPROF_BYTE);
00566 HPROF_ASSERT(kind==HPROF_BOOLEAN?(value.b==0 || value.b==1):1);
00567 heap_u1(value.b);
00568 break;
00569 default:
00570 HPROF_ASSERT(0);
00571 break;
00572 }
00573 }
00574 }
00575
00576
00577 static void
00578 heap_elements(HprofType kind, jint num_elements, jint elem_size, void *elements)
00579 {
00580 int i;
00581 jvalue val;
00582 static jvalue empty_val;
00583
00584 if ( num_elements == 0 ) {
00585 return;
00586 }
00587
00588 switch ( kind ) {
00589 case 0:
00590 case HPROF_ARRAY_OBJECT:
00591 case HPROF_NORMAL_OBJECT:
00592 for (i = 0; i < num_elements; i++) {
00593 val = empty_val;
00594 val.i = ((ObjectIndex*)elements)[i];
00595 heap_element(kind, elem_size, val);
00596 }
00597 break;
00598 case HPROF_BYTE:
00599 case HPROF_BOOLEAN:
00600 HPROF_ASSERT(elem_size==1);
00601 for (i = 0; i < num_elements; i++) {
00602 val = empty_val;
00603 val.b = ((jboolean*)elements)[i];
00604 heap_element(kind, elem_size, val);
00605 }
00606 break;
00607 case HPROF_CHAR:
00608 case HPROF_SHORT:
00609 HPROF_ASSERT(elem_size==2);
00610 for (i = 0; i < num_elements; i++) {
00611 val = empty_val;
00612 val.s = ((jshort*)elements)[i];
00613 heap_element(kind, elem_size, val);
00614 }
00615 break;
00616 case HPROF_FLOAT:
00617 case HPROF_INT:
00618 HPROF_ASSERT(elem_size==4);
00619 for (i = 0; i < num_elements; i++) {
00620 val = empty_val;
00621 val.i = ((jint*)elements)[i];
00622 heap_element(kind, elem_size, val);
00623 }
00624 break;
00625 case HPROF_DOUBLE:
00626 case HPROF_LONG:
00627 HPROF_ASSERT(elem_size==8);
00628 for (i = 0; i < num_elements; i++) {
00629 val = empty_val;
00630 val.j = ((jlong*)elements)[i];
00631 heap_element(kind, elem_size, val);
00632 }
00633 break;
00634 }
00635 }
00636
00637
00638
00639 void
00640 io_flush(void)
00641 {
00642 HPROF_ASSERT(gdata->header!=NULL);
00643 write_flush();
00644 }
00645
00646 void
00647 io_setup(void)
00648 {
00649 gdata->write_buffer_size = FILE_IO_BUFFER_SIZE;
00650 gdata->write_buffer = HPROF_MALLOC(gdata->write_buffer_size);
00651 gdata->write_buffer_index = 0;
00652
00653 gdata->heap_write_count = (jlong)0;
00654 gdata->heap_last_tag_position = (jlong)0;
00655 gdata->heap_buffer_size = FILE_IO_BUFFER_SIZE;
00656 gdata->heap_buffer = HPROF_MALLOC(gdata->heap_buffer_size);
00657 gdata->heap_buffer_index = 0;
00658
00659 if ( gdata->logflags & LOG_CHECK_BINARY ) {
00660 gdata->check_buffer_size = FILE_IO_BUFFER_SIZE;
00661 gdata->check_buffer = HPROF_MALLOC(gdata->check_buffer_size);
00662 gdata->check_buffer_index = 0;
00663 }
00664
00665 ioname_init();
00666 }
00667
00668 void
00669 io_cleanup(void)
00670 {
00671 if ( gdata->write_buffer != NULL ) {
00672 HPROF_FREE(gdata->write_buffer);
00673 }
00674 gdata->write_buffer_size = 0;
00675 gdata->write_buffer = NULL;
00676 gdata->write_buffer_index = 0;
00677
00678 if ( gdata->heap_buffer != NULL ) {
00679 HPROF_FREE(gdata->heap_buffer);
00680 }
00681 gdata->heap_write_count = (jlong)0;
00682 gdata->heap_last_tag_position = (jlong)0;
00683 gdata->heap_buffer_size = 0;
00684 gdata->heap_buffer = NULL;
00685 gdata->heap_buffer_index = 0;
00686
00687 if ( gdata->logflags & LOG_CHECK_BINARY ) {
00688 if ( gdata->check_buffer != NULL ) {
00689 HPROF_FREE(gdata->check_buffer);
00690 }
00691 gdata->check_buffer_size = 0;
00692 gdata->check_buffer = NULL;
00693 gdata->check_buffer_index = 0;
00694 }
00695
00696 ioname_cleanup();
00697 }
00698
00699 void
00700 io_write_file_header(void)
00701 {
00702 HPROF_ASSERT(gdata->header!=NULL);
00703 if (gdata->output_format == 'b') {
00704 jint settings;
00705 jlong t;
00706
00707 settings = 0;
00708 if (gdata->heap_dump || gdata->alloc_sites) {
00709 settings |= 1;
00710 }
00711 if (gdata->cpu_sampling) {
00712 settings |= 2;
00713 }
00714 t = md_get_timemillis();
00715
00716 write_raw(gdata->header, (int)strlen(gdata->header) + 1);
00717 write_u4((jint)sizeof(HprofId));
00718 write_u8(t);
00719
00720 write_header(HPROF_CONTROL_SETTINGS, 4 + 2);
00721 write_u4(settings);
00722 write_u2((unsigned short)gdata->max_trace_depth);
00723
00724 } else if ((!gdata->cpu_timing) || (!gdata->old_timing_format)) {
00725
00726 time_t t;
00727 char prelude_file[FILENAME_MAX];
00728 int prelude_fd;
00729 int nbytes;
00730
00731 t = time(0);
00732
00733 md_get_prelude_path(prelude_file, sizeof(prelude_file), PRELUDE_FILE);
00734
00735 prelude_fd = md_open(prelude_file);
00736 if (prelude_fd < 0) {
00737 char buf[FILENAME_MAX+80];
00738
00739 (void)md_snprintf(buf, sizeof(buf), "Can't open %s", prelude_file);
00740 buf[sizeof(buf)-1] = 0;
00741 HPROF_ERROR(JNI_TRUE, buf);
00742 }
00743
00744 write_printf("%s, created %s\n", gdata->header, ctime(&t));
00745
00746 do {
00747 char buf[1024];
00748
00749 nbytes = md_read(prelude_fd, buf, sizeof(buf));
00750 if ( nbytes < 0 ) {
00751 system_error("read", nbytes, errno);
00752 break;
00753 }
00754 if (nbytes == 0) {
00755 break;
00756 }
00757 write_raw(buf, nbytes);
00758 } while ( nbytes > 0 );
00759
00760 md_close(prelude_fd);
00761
00762 write_printf("\n--------\n\n");
00763
00764 write_flush();
00765 }
00766 }
00767
00768 void
00769 io_write_file_footer(void)
00770 {
00771 HPROF_ASSERT(gdata->header!=NULL);
00772 }
00773
00774 void
00775 io_write_class_load(SerialNumber class_serial_num, ObjectIndex index,
00776 SerialNumber trace_serial_num, char *sig)
00777 {
00778 CHECK_CLASS_SERIAL_NO(class_serial_num);
00779 CHECK_TRACE_SERIAL_NO(trace_serial_num);
00780 if (gdata->output_format == 'b') {
00781 IoNameIndex name_index;
00782 char *class_name;
00783
00784 class_name = signature_to_name(sig);
00785 name_index = write_name_first(class_name);
00786 write_header(HPROF_LOAD_CLASS, (2 * (jint)sizeof(HprofId)) + (4 * 2));
00787 write_u4(class_serial_num);
00788 write_index_id(index);
00789 write_u4(trace_serial_num);
00790 write_index_id(name_index);
00791 HPROF_FREE(class_name);
00792 }
00793 }
00794
00795 void
00796 io_write_class_unload(SerialNumber class_serial_num, ObjectIndex index)
00797 {
00798 CHECK_CLASS_SERIAL_NO(class_serial_num);
00799 if (gdata->output_format == 'b') {
00800 write_header(HPROF_UNLOAD_CLASS, 4);
00801 write_u4(class_serial_num);
00802 }
00803 }
00804
00805 void
00806 io_write_sites_header(const char * comment_str, jint flags, double cutoff,
00807 jint total_live_bytes, jint total_live_instances,
00808 jlong total_alloced_bytes, jlong total_alloced_instances,
00809 jint count)
00810 {
00811 if ( gdata->output_format == 'b') {
00812 write_header(HPROF_ALLOC_SITES, 2 + (8 * 4) + (count * (4 * 6 + 1)));
00813 write_u2((unsigned short)flags);
00814 write_u4(*(int *)(&cutoff));
00815 write_u4(total_live_bytes);
00816 write_u4(total_live_instances);
00817 write_u8(total_alloced_bytes);
00818 write_u8(total_alloced_instances);
00819 write_u4(count);
00820 } else {
00821 time_t t;
00822
00823 t = time(0);
00824 write_printf("SITES BEGIN (ordered by %s) %s", comment_str, ctime(&t));
00825 write_printf(
00826 " percent live alloc'ed stack class\n");
00827 write_printf(
00828 " rank self accum bytes objs bytes objs trace name\n");
00829 }
00830 }
00831
00832 void
00833 io_write_sites_elem(jint index, double ratio, double accum_percent,
00834 char *sig, SerialNumber class_serial_num,
00835 SerialNumber trace_serial_num, jint n_live_bytes,
00836 jint n_live_instances, jint n_alloced_bytes,
00837 jint n_alloced_instances)
00838 {
00839 CHECK_CLASS_SERIAL_NO(class_serial_num);
00840 CHECK_TRACE_SERIAL_NO(trace_serial_num);
00841 if ( gdata->output_format == 'b') {
00842 HprofType kind;
00843 jint size;
00844
00845 type_array(sig, &kind, &size);
00846 write_u1(kind);
00847 write_u4(class_serial_num);
00848 write_u4(trace_serial_num);
00849 write_u4(n_live_bytes);
00850 write_u4(n_live_instances);
00851 write_u4(n_alloced_bytes);
00852 write_u4(n_alloced_instances);
00853 } else {
00854 char *class_name;
00855
00856 class_name = signature_to_name(sig);
00857 write_printf("%5u %5.2f%% %5.2f%% %9u %4u %9u %5u %5u %s\n",
00858 index,
00859 ratio * 100.0,
00860 accum_percent * 100.0,
00861 n_live_bytes,
00862 n_live_instances,
00863 n_alloced_bytes,
00864 n_alloced_instances,
00865 trace_serial_num,
00866 class_name);
00867 HPROF_FREE(class_name);
00868 }
00869 }
00870
00871 void
00872 io_write_sites_footer(void)
00873 {
00874 if (gdata->output_format == 'b') {
00875 not_implemented();
00876 } else {
00877 write_printf("SITES END\n");
00878 }
00879 }
00880
00881 void
00882 io_write_thread_start(SerialNumber thread_serial_num,
00883 ObjectIndex thread_obj_id,
00884 SerialNumber trace_serial_num, char *thread_name,
00885 char *thread_group_name, char *thread_parent_name)
00886 {
00887 CHECK_THREAD_SERIAL_NO(thread_serial_num);
00888 CHECK_TRACE_SERIAL_NO(trace_serial_num);
00889 if (gdata->output_format == 'b') {
00890 IoNameIndex tname_index;
00891 IoNameIndex gname_index;
00892 IoNameIndex pname_index;
00893
00894 tname_index = write_name_first(thread_name);
00895 gname_index = write_name_first(thread_group_name);
00896 pname_index = write_name_first(thread_parent_name);
00897 write_header(HPROF_START_THREAD, ((jint)sizeof(HprofId) * 4) + (4 * 2));
00898 write_u4(thread_serial_num);
00899 write_index_id(thread_obj_id);
00900 write_u4(trace_serial_num);
00901 write_index_id(tname_index);
00902 write_index_id(gname_index);
00903 write_index_id(pname_index);
00904
00905 } else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
00906
00907 write_printf("THREAD START "
00908 "(obj=%x, id = %d, name=\"%s\", group=\"%s\")\n",
00909 thread_obj_id, thread_serial_num,
00910 (thread_name==NULL?"":thread_name),
00911 (thread_group_name==NULL?"":thread_group_name));
00912 }
00913 }
00914
00915 void
00916 io_write_thread_end(SerialNumber thread_serial_num)
00917 {
00918 CHECK_THREAD_SERIAL_NO(thread_serial_num);
00919 if (gdata->output_format == 'b') {
00920 write_header(HPROF_END_THREAD, 4);
00921 write_u4(thread_serial_num);
00922
00923 } else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
00924
00925 write_printf("THREAD END (id = %d)\n", thread_serial_num);
00926 }
00927 }
00928
00929 void
00930 io_write_frame(FrameIndex index, SerialNumber frame_serial_num,
00931 char *mname, char *msig, char *sname,
00932 SerialNumber class_serial_num, jint lineno)
00933 {
00934 CHECK_CLASS_SERIAL_NO(class_serial_num);
00935 if (gdata->output_format == 'b') {
00936 IoNameIndex mname_index;
00937 IoNameIndex msig_index;
00938 IoNameIndex sname_index;
00939
00940 mname_index = write_name_first(mname);
00941 msig_index = write_name_first(msig);
00942 sname_index = write_name_first(sname);
00943
00944 write_header(HPROF_FRAME, ((jint)sizeof(HprofId) * 4) + (4 * 2));
00945 write_index_id(index);
00946 write_index_id(mname_index);
00947 write_index_id(msig_index);
00948 write_index_id(sname_index);
00949 write_u4(class_serial_num);
00950 write_u4(lineno);
00951 }
00952 }
00953
00954 void
00955 io_write_trace_header(SerialNumber trace_serial_num,
00956 SerialNumber thread_serial_num, jint n_frames, char *phase_str)
00957 {
00958 CHECK_TRACE_SERIAL_NO(trace_serial_num);
00959 if (gdata->output_format == 'b') {
00960 write_header(HPROF_TRACE, ((jint)sizeof(HprofId) * n_frames) + (4 * 3));
00961 write_u4(trace_serial_num);
00962 write_u4(thread_serial_num);
00963 write_u4(n_frames);
00964 } else {
00965 write_printf("TRACE %u:", trace_serial_num);
00966 if (thread_serial_num) {
00967 write_printf(" (thread=%d)", thread_serial_num);
00968 }
00969 if ( phase_str != NULL ) {
00970 write_printf(" (from %s phase of JVM)", phase_str);
00971 }
00972 write_printf("\n");
00973 if (n_frames == 0) {
00974 write_printf("\t<empty>\n");
00975 }
00976 }
00977 }
00978
00979 void
00980 io_write_trace_elem(SerialNumber trace_serial_num, FrameIndex frame_index,
00981 SerialNumber frame_serial_num,
00982 char *csig, char *mname, char *sname, jint lineno)
00983 {
00984 if (gdata->output_format == 'b') {
00985 write_index_id(frame_index);
00986 } else {
00987 char *class_name;
00988 char linebuf[32];
00989
00990 if (lineno == -2) {
00991 (void)md_snprintf(linebuf, sizeof(linebuf), "Compiled method");
00992 } else if (lineno == -3) {
00993 (void)md_snprintf(linebuf, sizeof(linebuf), "Native method");
00994 } else if (lineno == -1) {
00995 (void)md_snprintf(linebuf, sizeof(linebuf), "Unknown line");
00996 } else {
00997 (void)md_snprintf(linebuf, sizeof(linebuf), "%d", lineno);
00998 }
00999 linebuf[sizeof(linebuf)-1] = 0;
01000 class_name = signature_to_name(csig);
01001 if ( mname == NULL ) {
01002 mname = "<Unknown Method>";
01003 }
01004 if ( sname == NULL ) {
01005 sname = "<Unknown Source>";
01006 }
01007 write_printf("\t%s.%s(%s:%s)\n", class_name, mname, sname, linebuf);
01008 HPROF_FREE(class_name);
01009 }
01010 }
01011
01012 void
01013 io_write_trace_footer(SerialNumber trace_serial_num,
01014 SerialNumber thread_serial_num, jint n_frames)
01015 {
01016 }
01017
01018 #define CPU_SAMPLES_RECORD_NAME ("CPU SAMPLES")
01019 #define CPU_TIMES_RECORD_NAME ("CPU TIME (ms)")
01020
01021 void
01022 io_write_cpu_samples_header(jlong total_cost, jint n_items)
01023 {
01024
01025 if (gdata->output_format == 'b') {
01026 write_header(HPROF_CPU_SAMPLES, (n_items * (4 * 2)) + (4 * 2));
01027 write_u4((jint)total_cost);
01028 write_u4(n_items);
01029 } else {
01030 time_t t;
01031 char *record_name;
01032
01033 if ( gdata->cpu_sampling ) {
01034 record_name = CPU_SAMPLES_RECORD_NAME;
01035 } else {
01036 record_name = CPU_TIMES_RECORD_NAME;
01037 }
01038 t = time(0);
01039 write_printf("%s BEGIN (total = %d) %s", record_name,
01040 (int)total_cost, ctime(&t));
01041 if ( n_items > 0 ) {
01042 write_printf("rank self accum count trace method\n");
01043 }
01044 }
01045 }
01046
01047 void
01048 io_write_cpu_samples_elem(jint index, double percent, double accum,
01049 jint num_hits, jlong cost, SerialNumber trace_serial_num,
01050 jint n_frames, char *csig, char *mname)
01051 {
01052 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01053 if (gdata->output_format == 'b') {
01054 write_u4((jint)cost);
01055 write_u4(trace_serial_num);
01056 } else {
01057 write_printf("%4u %5.2f%% %5.2f%% %7u %5u",
01058 index, percent, accum, num_hits,
01059 trace_serial_num);
01060 if (n_frames > 0) {
01061 char * class_name;
01062
01063 class_name = signature_to_name(csig);
01064 write_printf(" %s.%s\n", class_name, mname);
01065 HPROF_FREE(class_name);
01066 } else {
01067 write_printf(" <empty trace>\n");
01068 }
01069 }
01070 }
01071
01072 void
01073 io_write_cpu_samples_footer(void)
01074 {
01075 if (gdata->output_format == 'b') {
01076 not_implemented();
01077 } else {
01078 char *record_name;
01079
01080 if ( gdata->cpu_sampling ) {
01081 record_name = CPU_SAMPLES_RECORD_NAME;
01082 } else {
01083 record_name = CPU_TIMES_RECORD_NAME;
01084 }
01085 write_printf("%s END\n", record_name);
01086 }
01087 }
01088
01089 void
01090 io_write_heap_summary(jlong total_live_bytes, jlong total_live_instances,
01091 jlong total_alloced_bytes, jlong total_alloced_instances)
01092 {
01093 if (gdata->output_format == 'b') {
01094 write_header(HPROF_HEAP_SUMMARY, 4 * 6);
01095 write_u4((jint)total_live_bytes);
01096 write_u4((jint)total_live_instances);
01097 write_u8(total_alloced_bytes);
01098 write_u8(total_alloced_instances);
01099 }
01100 }
01101
01102 void
01103 io_write_oldprof_header(void)
01104 {
01105 if ( gdata->old_timing_format ) {
01106 write_printf("count callee caller time\n");
01107 }
01108 }
01109
01110 void
01111 io_write_oldprof_elem(jint num_hits, jint num_frames, char *csig_callee,
01112 char *mname_callee, char *msig_callee, char *csig_caller,
01113 char *mname_caller, char *msig_caller, jlong cost)
01114 {
01115 if ( gdata->old_timing_format ) {
01116 char * class_name_callee;
01117 char * class_name_caller;
01118
01119 class_name_callee = signature_to_name(csig_callee);
01120 class_name_caller = signature_to_name(csig_caller);
01121 write_printf("%d ", num_hits);
01122 if (num_frames >= 1) {
01123 write_printf("%s.%s%s ", class_name_callee,
01124 mname_callee, msig_callee);
01125 } else {
01126 write_printf("%s ", "<unknown callee>");
01127 }
01128 if (num_frames > 1) {
01129 write_printf("%s.%s%s ", class_name_caller,
01130 mname_caller, msig_caller);
01131 } else {
01132 write_printf("%s ", "<unknown caller>");
01133 }
01134 write_printf("%d\n", (int)cost);
01135 HPROF_FREE(class_name_callee);
01136 HPROF_FREE(class_name_caller);
01137 }
01138 }
01139
01140 void
01141 io_write_oldprof_footer(void)
01142 {
01143 }
01144
01145 void
01146 io_write_monitor_header(jlong total_time)
01147 {
01148 if (gdata->output_format == 'b') {
01149 not_implemented();
01150 } else {
01151 time_t t = time(0);
01152
01153 t = time(0);
01154 write_printf("MONITOR TIME BEGIN (total = %u ms) %s",
01155 (int)total_time, ctime(&t));
01156 if (total_time > 0) {
01157 write_printf("rank self accum count trace monitor\n");
01158 }
01159 }
01160 }
01161
01162 void
01163 io_write_monitor_elem(jint index, double percent, double accum,
01164 jint num_hits, SerialNumber trace_serial_num, char *sig)
01165 {
01166 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01167 if (gdata->output_format == 'b') {
01168 not_implemented();
01169 } else {
01170 char *class_name;
01171
01172 class_name = signature_to_name(sig);
01173 write_printf("%4u %5.2f%% %5.2f%% %7u %5u %s (Java)\n",
01174 index, percent, accum, num_hits,
01175 trace_serial_num, class_name);
01176 HPROF_FREE(class_name);
01177 }
01178 }
01179
01180 void
01181 io_write_monitor_footer(void)
01182 {
01183 if (gdata->output_format == 'b') {
01184 not_implemented();
01185 } else {
01186 write_printf("MONITOR TIME END\n");
01187 }
01188 }
01189
01190 void
01191 io_write_monitor_sleep(jlong timeout, SerialNumber thread_serial_num)
01192 {
01193 if (gdata->output_format == 'b') {
01194 not_implemented();
01195 } else {
01196 if ( thread_serial_num == 0 ) {
01197 write_printf("SLEEP: timeout=%d, <unknown thread>\n",
01198 (int)timeout);
01199 } else {
01200 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01201 write_printf("SLEEP: timeout=%d, thread %d\n",
01202 (int)timeout, thread_serial_num);
01203 }
01204 }
01205 }
01206
01207 void
01208 io_write_monitor_wait(char *sig, jlong timeout,
01209 SerialNumber thread_serial_num)
01210 {
01211 if (gdata->output_format == 'b') {
01212 not_implemented();
01213 } else {
01214 if ( thread_serial_num == 0 ) {
01215 write_printf("WAIT: MONITOR %s, timeout=%d, <unknown thread>\n",
01216 sig, (int)timeout);
01217 } else {
01218 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01219 write_printf("WAIT: MONITOR %s, timeout=%d, thread %d\n",
01220 sig, (int)timeout, thread_serial_num);
01221 }
01222 }
01223 }
01224
01225 void
01226 io_write_monitor_waited(char *sig, jlong time_waited,
01227 SerialNumber thread_serial_num)
01228 {
01229 if (gdata->output_format == 'b') {
01230 not_implemented();
01231 } else {
01232 if ( thread_serial_num == 0 ) {
01233 write_printf("WAITED: MONITOR %s, time_waited=%d, <unknown thread>\n",
01234 sig, (int)time_waited);
01235 } else {
01236 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01237 write_printf("WAITED: MONITOR %s, time_waited=%d, thread %d\n",
01238 sig, (int)time_waited, thread_serial_num);
01239 }
01240 }
01241 }
01242
01243 void
01244 io_write_monitor_exit(char *sig, SerialNumber thread_serial_num)
01245 {
01246 if (gdata->output_format == 'b') {
01247 not_implemented();
01248 } else {
01249 if ( thread_serial_num == 0 ) {
01250 write_printf("EXIT: MONITOR %s, <unknown thread>\n", sig);
01251 } else {
01252 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01253 write_printf("EXIT: MONITOR %s, thread %d\n",
01254 sig, thread_serial_num);
01255 }
01256 }
01257 }
01258
01259 void
01260 io_write_monitor_dump_header(void)
01261 {
01262 if (gdata->output_format == 'b') {
01263 not_implemented();
01264 } else {
01265 write_printf("MONITOR DUMP BEGIN\n");
01266 }
01267 }
01268
01269 void
01270 io_write_monitor_dump_thread_state(SerialNumber thread_serial_num,
01271 SerialNumber trace_serial_num,
01272 jint threadState)
01273 {
01274 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01275 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01276 if (gdata->output_format == 'b') {
01277 not_implemented();
01278 } else {
01279 char tstate[20];
01280
01281 tstate[0] = 0;
01282
01283 if (threadState & JVMTI_THREAD_STATE_SUSPENDED) {
01284 (void)strcat(tstate,"S|");
01285 }
01286 if (threadState & JVMTI_THREAD_STATE_INTERRUPTED) {
01287 (void)strcat(tstate,"intr|");
01288 }
01289 if (threadState & JVMTI_THREAD_STATE_IN_NATIVE) {
01290 (void)strcat(tstate,"native|");
01291 }
01292 if ( ! ( threadState & JVMTI_THREAD_STATE_ALIVE ) ) {
01293 if ( threadState & JVMTI_THREAD_STATE_TERMINATED ) {
01294 (void)strcat(tstate,"ZO");
01295 } else {
01296 (void)strcat(tstate,"NS");
01297 }
01298 } else {
01299 if ( threadState & JVMTI_THREAD_STATE_SLEEPING ) {
01300 (void)strcat(tstate,"SL");
01301 } else if ( threadState & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
01302 (void)strcat(tstate,"MW");
01303 } else if ( threadState & JVMTI_THREAD_STATE_WAITING ) {
01304 (void)strcat(tstate,"CW");
01305 } else if ( threadState & JVMTI_THREAD_STATE_RUNNABLE ) {
01306 (void)strcat(tstate,"R");
01307 } else {
01308 (void)strcat(tstate,"UN");
01309 }
01310 }
01311 write_printf(" THREAD %d, trace %d, status: %s\n",
01312 thread_serial_num, trace_serial_num, tstate);
01313 }
01314 }
01315
01316 void
01317 io_write_monitor_dump_state(char *sig, SerialNumber thread_serial_num,
01318 jint entry_count,
01319 SerialNumber *waiters, jint waiter_count,
01320 SerialNumber *notify_waiters, jint notify_waiter_count)
01321 {
01322 if (gdata->output_format == 'b') {
01323 not_implemented();
01324 } else {
01325 int i;
01326
01327 if ( thread_serial_num != 0 ) {
01328 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01329 write_printf(" MONITOR %s\n", sig);
01330 write_printf("\towner: thread %d, entry count: %d\n",
01331 thread_serial_num, entry_count);
01332 } else {
01333 write_printf(" MONITOR %s unowned\n", sig);
01334 }
01335 write_printf("\twaiting to enter:");
01336 for (i = 0; i < waiter_count; i++) {
01337 write_thread_serial_number(waiters[i],
01338 (i != (waiter_count-1)));
01339 }
01340 write_printf("\n");
01341 write_printf("\twaiting to be notified:");
01342 for (i = 0; i < notify_waiter_count; i++) {
01343 write_thread_serial_number(notify_waiters[i],
01344 (i != (notify_waiter_count-1)));
01345 }
01346 write_printf("\n");
01347 }
01348 }
01349
01350 void
01351 io_write_monitor_dump_footer(void)
01352 {
01353 if (gdata->output_format == 'b') {
01354 not_implemented();
01355 } else {
01356 write_printf("MONITOR DUMP END\n");
01357 }
01358 }
01359
01360
01361
01362
01363 void
01364 io_heap_header(jlong total_live_instances, jlong total_live_bytes)
01365 {
01366 if (gdata->output_format != 'b') {
01367 time_t t;
01368
01369 t = time(0);
01370 heap_printf("HEAP DUMP BEGIN (%u objects, %u bytes) %s",
01371 (int)total_live_instances,
01372 (int)total_live_bytes, ctime(&t));
01373 }
01374 }
01375
01376 void
01377 io_heap_root_thread_object(ObjectIndex thread_obj_id,
01378 SerialNumber thread_serial_num, SerialNumber trace_serial_num)
01379 {
01380 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01381 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01382 if (gdata->output_format == 'b') {
01383 heap_tag(HPROF_GC_ROOT_THREAD_OBJ);
01384 heap_id(thread_obj_id);
01385 heap_u4(thread_serial_num);
01386 heap_u4(trace_serial_num);
01387 } else {
01388 heap_printf("ROOT %x (kind=<thread>, id=%u, trace=%u)\n",
01389 thread_obj_id, thread_serial_num, trace_serial_num);
01390 }
01391 }
01392
01393 void
01394 io_heap_root_unknown(ObjectIndex obj_id)
01395 {
01396 if (gdata->output_format == 'b') {
01397 heap_tag(HPROF_GC_ROOT_UNKNOWN);
01398 heap_id(obj_id);
01399 } else {
01400 heap_printf("ROOT %x (kind=<unknown>)\n", obj_id);
01401 }
01402 }
01403
01404 void
01405 io_heap_root_jni_global(ObjectIndex obj_id, SerialNumber gref_serial_num,
01406 SerialNumber trace_serial_num)
01407 {
01408 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01409 if (gdata->output_format == 'b') {
01410 heap_tag(HPROF_GC_ROOT_JNI_GLOBAL);
01411 heap_id(obj_id);
01412 heap_id(gref_serial_num);
01413 } else {
01414 heap_printf("ROOT %x (kind=<JNI global ref>, "
01415 "id=%x, trace=%u)\n",
01416 obj_id, gref_serial_num, trace_serial_num);
01417 }
01418 }
01419
01420 void
01421 io_heap_root_jni_local(ObjectIndex obj_id, SerialNumber thread_serial_num,
01422 jint frame_depth)
01423 {
01424 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01425 if (gdata->output_format == 'b') {
01426 heap_tag(HPROF_GC_ROOT_JNI_LOCAL);
01427 heap_id(obj_id);
01428 heap_u4(thread_serial_num);
01429 heap_u4(frame_depth);
01430 } else {
01431 heap_printf("ROOT %x (kind=<JNI local ref>, "
01432 "thread=%u, frame=%d)\n",
01433 obj_id, thread_serial_num, frame_depth);
01434 }
01435 }
01436
01437 void
01438 io_heap_root_system_class(ObjectIndex obj_id, char *sig, SerialNumber class_serial_num)
01439 {
01440 if (gdata->output_format == 'b') {
01441 heap_tag(HPROF_GC_ROOT_STICKY_CLASS);
01442 heap_id(obj_id);
01443 } else {
01444 char *class_name;
01445
01446 class_name = signature_to_name(sig);
01447 heap_printf("ROOT %x (kind=<system class>, name=%s)\n",
01448 obj_id, class_name);
01449 HPROF_FREE(class_name);
01450 }
01451 }
01452
01453 void
01454 io_heap_root_monitor(ObjectIndex obj_id)
01455 {
01456 if (gdata->output_format == 'b') {
01457 heap_tag(HPROF_GC_ROOT_MONITOR_USED);
01458 heap_id(obj_id);
01459 } else {
01460 heap_printf("ROOT %x (kind=<busy monitor>)\n", obj_id);
01461 }
01462 }
01463
01464 void
01465 io_heap_root_thread(ObjectIndex obj_id, SerialNumber thread_serial_num)
01466 {
01467 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01468 if (gdata->output_format == 'b') {
01469 heap_tag(HPROF_GC_ROOT_THREAD_BLOCK);
01470 heap_id(obj_id);
01471 heap_u4(thread_serial_num);
01472 } else {
01473 heap_printf("ROOT %x (kind=<thread block>, thread=%u)\n",
01474 obj_id, thread_serial_num);
01475 }
01476 }
01477
01478 void
01479 io_heap_root_java_frame(ObjectIndex obj_id, SerialNumber thread_serial_num,
01480 jint frame_depth)
01481 {
01482 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01483 if (gdata->output_format == 'b') {
01484 heap_tag(HPROF_GC_ROOT_JAVA_FRAME);
01485 heap_id(obj_id);
01486 heap_u4(thread_serial_num);
01487 heap_u4(frame_depth);
01488 } else {
01489 heap_printf("ROOT %x (kind=<Java stack>, "
01490 "thread=%u, frame=%d)\n",
01491 obj_id, thread_serial_num, frame_depth);
01492 }
01493 }
01494
01495 void
01496 io_heap_root_native_stack(ObjectIndex obj_id, SerialNumber thread_serial_num)
01497 {
01498 CHECK_THREAD_SERIAL_NO(thread_serial_num);
01499 if (gdata->output_format == 'b') {
01500 heap_tag(HPROF_GC_ROOT_NATIVE_STACK);
01501 heap_id(obj_id);
01502 heap_u4(thread_serial_num);
01503 } else {
01504 heap_printf("ROOT %x (kind=<native stack>, thread=%u)\n",
01505 obj_id, thread_serial_num);
01506 }
01507 }
01508
01509 static jboolean
01510 is_static_field(jint modifiers)
01511 {
01512 if ( modifiers & JVM_ACC_STATIC ) {
01513 return JNI_TRUE;
01514 }
01515 return JNI_FALSE;
01516 }
01517
01518 static jboolean
01519 is_inst_field(jint modifiers)
01520 {
01521 if ( modifiers & JVM_ACC_STATIC ) {
01522 return JNI_FALSE;
01523 }
01524 return JNI_TRUE;
01525 }
01526
01527 void
01528 io_heap_class_dump(ClassIndex cnum, char *sig, ObjectIndex class_id,
01529 SerialNumber trace_serial_num,
01530 ObjectIndex super_id, ObjectIndex loader_id,
01531 ObjectIndex signers_id, ObjectIndex domain_id,
01532 jint size,
01533 jint n_cpool, ConstantPoolValue *cpool,
01534 jint n_fields, FieldInfo *fields, jvalue *fvalues)
01535 {
01536 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01537 if (gdata->output_format == 'b') {
01538 int i;
01539 jint n_static_fields;
01540 jint n_inst_fields;
01541 jint inst_size;
01542 jint saved_inst_size;
01543
01544 n_static_fields = 0;
01545 n_inst_fields = 0;
01546 inst_size = 0;
01547
01548
01549 for ( i = 0 ; i < n_fields ; i++ ) {
01550 if ( fields[i].cnum == cnum &&
01551 is_static_field(fields[i].modifiers) ) {
01552 char *field_name;
01553
01554 field_name = string_get(fields[i].name_index);
01555 (void)write_name_first(field_name);
01556 n_static_fields++;
01557 }
01558 if ( is_inst_field(fields[i].modifiers) ) {
01559 inst_size += size_from_field_info(fields[i].primSize);
01560 if ( fields[i].cnum == cnum ) {
01561 char *field_name;
01562
01563 field_name = string_get(fields[i].name_index);
01564 (void)write_name_first(field_name);
01565 n_inst_fields++;
01566 }
01567 }
01568 }
01569
01570
01571
01572
01573
01574 if ( size >= 0 ) {
01575 saved_inst_size = class_get_inst_size(cnum);
01576 if ( saved_inst_size == -1 ) {
01577 class_set_inst_size(cnum, inst_size);
01578 } else if ( saved_inst_size != inst_size ) {
01579 HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in class dump");
01580 }
01581 }
01582
01583 heap_tag(HPROF_GC_CLASS_DUMP);
01584 heap_id(class_id);
01585 heap_u4(trace_serial_num);
01586 heap_id(super_id);
01587 heap_id(loader_id);
01588 heap_id(signers_id);
01589 heap_id(domain_id);
01590 heap_id(0);
01591 heap_id(0);
01592 heap_u4(inst_size);
01593
01594 heap_u2((unsigned short)n_cpool);
01595 for ( i = 0 ; i < n_cpool ; i++ ) {
01596 HprofType kind;
01597 jint size;
01598
01599 type_from_signature(string_get(cpool[i].sig_index),
01600 &kind, &size);
01601 heap_u2((unsigned short)(cpool[i].constant_pool_index));
01602 heap_u1(kind);
01603 HPROF_ASSERT(!HPROF_TYPE_IS_PRIMITIVE(kind));
01604 heap_element(kind, size, cpool[i].value);
01605 }
01606
01607 heap_u2((unsigned short)n_static_fields);
01608 for ( i = 0 ; i < n_fields ; i++ ) {
01609 if ( fields[i].cnum == cnum &&
01610 is_static_field(fields[i].modifiers) ) {
01611 char *field_name;
01612 HprofType kind;
01613 jint size;
01614
01615 type_from_signature(string_get(fields[i].sig_index),
01616 &kind, &size);
01617 field_name = string_get(fields[i].name_index);
01618 heap_name(field_name);
01619 heap_u1(kind);
01620 heap_element(kind, size, fvalues[i]);
01621 }
01622 }
01623
01624 heap_u2((unsigned short)n_inst_fields);
01625 for ( i = 0 ; i < n_fields ; i++ ) {
01626 if ( fields[i].cnum == cnum &&
01627 is_inst_field(fields[i].modifiers) ) {
01628 HprofType kind;
01629 jint size;
01630 char *field_name;
01631
01632 field_name = string_get(fields[i].name_index);
01633 type_from_signature(string_get(fields[i].sig_index),
01634 &kind, &size);
01635 heap_name(field_name);
01636 heap_u1(kind);
01637 }
01638 }
01639 } else {
01640 char * class_name;
01641 int i;
01642
01643 class_name = signature_to_name(sig);
01644 heap_printf("CLS %x (name=%s, trace=%u)\n",
01645 class_id, class_name, trace_serial_num);
01646 HPROF_FREE(class_name);
01647 if (super_id) {
01648 heap_printf("\tsuper\t\t%x\n", super_id);
01649 }
01650 if (loader_id) {
01651 heap_printf("\tloader\t\t%x\n", loader_id);
01652 }
01653 if (signers_id) {
01654 heap_printf("\tsigners\t\t%x\n", signers_id);
01655 }
01656 if (domain_id) {
01657 heap_printf("\tdomain\t\t%x\n", domain_id);
01658 }
01659 for ( i = 0 ; i < n_fields ; i++ ) {
01660 if ( fields[i].cnum == cnum &&
01661 is_static_field(fields[i].modifiers) ) {
01662 HprofType kind;
01663 jint size;
01664
01665 type_from_signature(string_get(fields[i].sig_index),
01666 &kind, &size);
01667 if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
01668 if (fvalues[i].i != 0 ) {
01669 char *field_name;
01670
01671 field_name = string_get(fields[i].name_index);
01672 heap_printf("\tstatic %s\t%x\n", field_name,
01673 fvalues[i].i);
01674 }
01675 }
01676 }
01677 }
01678 for ( i = 0 ; i < n_cpool ; i++ ) {
01679 HprofType kind;
01680 jint size;
01681
01682 type_from_signature(string_get(cpool[i].sig_index), &kind, &size);
01683 if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
01684 if (cpool[i].value.i != 0 ) {
01685 heap_printf("\tconstant pool entry %d\t%x\n",
01686 cpool[i].constant_pool_index, cpool[i].value.i);
01687 }
01688 }
01689 }
01690 }
01691 }
01692
01693
01694 static int
01695 dump_instance_fields(ClassIndex cnum,
01696 FieldInfo *fields, jvalue *fvalues, jint n_fields)
01697 {
01698 ClassIndex super_cnum;
01699 int i;
01700 int nbytes;
01701
01702 HPROF_ASSERT(cnum!=0);
01703
01704 nbytes = 0;
01705 for (i = 0; i < n_fields; i++) {
01706 if ( fields[i].cnum == cnum &&
01707 is_inst_field(fields[i].modifiers) ) {
01708 HprofType kind;
01709 int size;
01710
01711 type_from_signature(string_get(fields[i].sig_index),
01712 &kind, &size);
01713 heap_element(kind, size, fvalues[i]);
01714 nbytes += size;
01715 }
01716 }
01717
01718 super_cnum = class_get_super(cnum);
01719 if ( super_cnum != 0 ) {
01720 nbytes += dump_instance_fields(super_cnum, fields, fvalues, n_fields);
01721 }
01722 return nbytes;
01723 }
01724
01725 void
01726 io_heap_instance_dump(ClassIndex cnum, ObjectIndex obj_id,
01727 SerialNumber trace_serial_num,
01728 ObjectIndex class_id, jint size, char *sig,
01729 FieldInfo *fields, jvalue *fvalues, jint n_fields)
01730 {
01731 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01732 if (gdata->output_format == 'b') {
01733 jint inst_size;
01734 jint saved_inst_size;
01735 int i;
01736 int nbytes;
01737
01738 inst_size = 0;
01739 for (i = 0; i < n_fields; i++) {
01740 if ( is_inst_field(fields[i].modifiers) ) {
01741 inst_size += size_from_field_info(fields[i].primSize);
01742 }
01743 }
01744
01745
01746
01747
01748
01749 saved_inst_size = class_get_inst_size(cnum);
01750 if ( saved_inst_size == -1 ) {
01751 class_set_inst_size(cnum, inst_size);
01752 } else if ( saved_inst_size != inst_size ) {
01753 HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in instance dump");
01754 }
01755
01756 heap_tag(HPROF_GC_INSTANCE_DUMP);
01757 heap_id(obj_id);
01758 heap_u4(trace_serial_num);
01759 heap_id(class_id);
01760 heap_u4(inst_size);
01761
01762
01763 nbytes = dump_instance_fields(cnum, fields, fvalues, n_fields);
01764 HPROF_ASSERT(nbytes==inst_size);
01765 } else {
01766 char * class_name;
01767 int i;
01768
01769 class_name = signature_to_name(sig);
01770 heap_printf("OBJ %x (sz=%u, trace=%u, class=%s@%x)\n",
01771 obj_id, size, trace_serial_num, class_name, class_id);
01772 HPROF_FREE(class_name);
01773
01774 for (i = 0; i < n_fields; i++) {
01775 if ( is_inst_field(fields[i].modifiers) ) {
01776 HprofType kind;
01777 int size;
01778
01779 type_from_signature(string_get(fields[i].sig_index),
01780 &kind, &size);
01781 if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
01782 if (fvalues[i].i != 0 ) {
01783 char *sep;
01784 ObjectIndex val_id;
01785 char *field_name;
01786
01787 field_name = string_get(fields[i].name_index);
01788 val_id = (ObjectIndex)(fvalues[i].i);
01789 sep = (int)strlen(field_name) < 8 ? "\t" : "";
01790 heap_printf("\t%s\t%s%x\n", field_name, sep, val_id);
01791 }
01792 }
01793 }
01794 }
01795 }
01796 }
01797
01798 void
01799 io_heap_object_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
01800 jint size, jint num_elements, char *sig, ObjectIndex *values,
01801 ObjectIndex class_id)
01802 {
01803 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01804 if (gdata->output_format == 'b') {
01805
01806 heap_tag(HPROF_GC_OBJ_ARRAY_DUMP);
01807 heap_id(obj_id);
01808 heap_u4(trace_serial_num);
01809 heap_u4(num_elements);
01810 heap_id(class_id);
01811 heap_elements(HPROF_NORMAL_OBJECT, num_elements,
01812 (jint)sizeof(HprofId), (void*)values);
01813 } else {
01814 char *name;
01815 int i;
01816
01817 name = signature_to_name(sig);
01818 heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s@%x)\n",
01819 obj_id, size, trace_serial_num, num_elements,
01820 name, class_id);
01821 for (i = 0; i < num_elements; i++) {
01822 ObjectIndex id;
01823
01824 id = values[i];
01825 if (id != 0) {
01826 heap_printf("\t[%u]\t\t%x\n", i, id);
01827 }
01828 }
01829 HPROF_FREE(name);
01830 }
01831 }
01832
01833 void
01834 io_heap_prim_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
01835 jint size, jint num_elements, char *sig, void *elements)
01836 {
01837 CHECK_TRACE_SERIAL_NO(trace_serial_num);
01838 if (gdata->output_format == 'b') {
01839 HprofType kind;
01840 jint esize;
01841
01842 type_array(sig, &kind, &esize);
01843 HPROF_ASSERT(HPROF_TYPE_IS_PRIMITIVE(kind));
01844 heap_tag(HPROF_GC_PRIM_ARRAY_DUMP);
01845 heap_id(obj_id);
01846 heap_u4(trace_serial_num);
01847 heap_u4(num_elements);
01848 heap_u1(kind);
01849 heap_elements(kind, num_elements, esize, elements);
01850 } else {
01851 char *name;
01852
01853 name = signature_to_name(sig);
01854 heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s)\n",
01855 obj_id, size, trace_serial_num, num_elements, name);
01856 HPROF_FREE(name);
01857 }
01858 }
01859
01860
01861 static void
01862 write_raw_from_file(int fd, jlong byteCount, void (*raw_interface)(void *,int))
01863 {
01864 char *buf;
01865 int buf_len;
01866 int left;
01867 int nbytes;
01868
01869 HPROF_ASSERT(fd >= 0);
01870
01871
01872 buf_len = FILE_IO_BUFFER_SIZE*2;
01873 buf = HPROF_MALLOC(buf_len);
01874 HPROF_ASSERT(buf!=NULL);
01875
01876
01877 left = (int)byteCount;
01878 do {
01879 int count;
01880
01881 count = buf_len;
01882 if ( count > left ) count = left;
01883 nbytes = md_read(fd, buf, count);
01884 if (nbytes < 0) {
01885 system_error("read", nbytes, errno);
01886 break;
01887 }
01888 if (nbytes == 0) {
01889 break;
01890 }
01891 if ( nbytes > 0 ) {
01892 (*raw_interface)(buf, nbytes);
01893 left -= nbytes;
01894 }
01895 } while ( left > 0 );
01896
01897 if (left > 0 && nbytes == 0) {
01898 HPROF_ERROR(JNI_TRUE, "File size is smaller than bytes written");
01899 }
01900 HPROF_FREE(buf);
01901 }
01902
01903
01904 static void
01905 dump_heap_segment_and_reset(jlong segment_size)
01906 {
01907 int fd;
01908 char *last_chunk;
01909 jlong last_chunk_len;
01910
01911 HPROF_ASSERT(gdata->heap_fd >= 0);
01912
01913
01914 heap_flush();
01915
01916
01917 last_chunk_len = gdata->heap_write_count - segment_size;
01918 HPROF_ASSERT(last_chunk_len>=0);
01919
01920
01921 if (gdata->output_format == 'b') {
01922 int tag;
01923
01924 if ( gdata->segmented == JNI_TRUE ) {
01925 tag = HPROF_HEAP_DUMP_SEGMENT;
01926 } else {
01927 tag = HPROF_HEAP_DUMP;
01928 HPROF_ASSERT(last_chunk_len==0);
01929 }
01930
01931
01932 write_header(tag, (jint)segment_size);
01933
01934 fd = md_open_binary(gdata->heapfilename);
01935 } else {
01936 fd = md_open(gdata->heapfilename);
01937 }
01938
01939
01940 write_raw_from_file(fd, segment_size, &write_raw);
01941
01942
01943 if ( md_seek(gdata->heap_fd, (jlong)0) != (jlong)0 ) {
01944 HPROF_ERROR(JNI_TRUE, "Cannot seek to beginning of heap info file");
01945 }
01946 gdata->heap_write_count = (jlong)0;
01947 gdata->heap_last_tag_position = (jlong)0;
01948
01949
01950 if ( last_chunk_len > 0 ) {
01951 write_raw_from_file(fd, last_chunk_len, &heap_raw);
01952 }
01953
01954
01955 md_close(fd);
01956 }
01957
01958 void
01959 io_heap_footer(void)
01960 {
01961 HPROF_ASSERT(gdata->heap_fd >= 0);
01962
01963
01964 heap_flush();
01965
01966
01967 dump_heap_segment_and_reset(gdata->heap_write_count);
01968
01969
01970 if (gdata->output_format != 'b') {
01971 write_printf("HEAP DUMP END\n");
01972 } else {
01973 if ( gdata->segmented == JNI_TRUE ) {
01974 write_header(HPROF_HEAP_DUMP_END, 0);
01975 }
01976 }
01977 }
01978