hprof_io.c
来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 1,979 行 · 第 1/4 页
C
1,979 行
heap_u4(thread_serial_num); heap_u4(frame_depth); } else { heap_printf("ROOT %x (kind=<Java stack>, " "thread=%u, frame=%d)\n", obj_id, thread_serial_num, frame_depth); }}voidio_heap_root_native_stack(ObjectIndex obj_id, SerialNumber thread_serial_num){ CHECK_THREAD_SERIAL_NO(thread_serial_num); if (gdata->output_format == 'b') { heap_tag(HPROF_GC_ROOT_NATIVE_STACK); heap_id(obj_id); heap_u4(thread_serial_num); } else { heap_printf("ROOT %x (kind=<native stack>, thread=%u)\n", obj_id, thread_serial_num); }}static jbooleanis_static_field(jint modifiers){ if ( modifiers & JVM_ACC_STATIC ) { return JNI_TRUE; } return JNI_FALSE;}static jbooleanis_inst_field(jint modifiers){ if ( modifiers & JVM_ACC_STATIC ) { return JNI_FALSE; } return JNI_TRUE;}voidio_heap_class_dump(ClassIndex cnum, char *sig, ObjectIndex class_id, SerialNumber trace_serial_num, ObjectIndex super_id, ObjectIndex loader_id, ObjectIndex signers_id, ObjectIndex domain_id, jint size, jint n_cpool, ConstantPoolValue *cpool, jint n_fields, FieldInfo *fields, jvalue *fvalues){ CHECK_TRACE_SERIAL_NO(trace_serial_num); if (gdata->output_format == 'b') { int i; jint n_static_fields; jint n_inst_fields; jint inst_size; jint saved_inst_size; n_static_fields = 0; n_inst_fields = 0; inst_size = 0; /* These do NOT go into the heap output */ for ( i = 0 ; i < n_fields ; i++ ) { if ( fields[i].cnum == cnum && is_static_field(fields[i].modifiers) ) { char *field_name; field_name = string_get(fields[i].name_index); (void)write_name_first(field_name); n_static_fields++; } if ( is_inst_field(fields[i].modifiers) ) { inst_size += size_from_field_info(fields[i].primSize); if ( fields[i].cnum == cnum ) { char *field_name; field_name = string_get(fields[i].name_index); (void)write_name_first(field_name); n_inst_fields++; } } } /* Verify that the instance size we have calculated as we went * through the fields, matches what is saved away with this * class. */ if ( size >= 0 ) { saved_inst_size = class_get_inst_size(cnum); if ( saved_inst_size == -1 ) { class_set_inst_size(cnum, inst_size); } else if ( saved_inst_size != inst_size ) { HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in class dump"); } } heap_tag(HPROF_GC_CLASS_DUMP); heap_id(class_id); heap_u4(trace_serial_num); heap_id(super_id); heap_id(loader_id); heap_id(signers_id); heap_id(domain_id); heap_id(0); heap_id(0); heap_u4(inst_size); /* Must match inst_size in instance dump */ heap_u2((unsigned short)n_cpool); for ( i = 0 ; i < n_cpool ; i++ ) { HprofType kind; jint size; type_from_signature(string_get(cpool[i].sig_index), &kind, &size); heap_u2((unsigned short)(cpool[i].constant_pool_index)); heap_u1(kind); HPROF_ASSERT(!HPROF_TYPE_IS_PRIMITIVE(kind)); heap_element(kind, size, cpool[i].value); } heap_u2((unsigned short)n_static_fields); for ( i = 0 ; i < n_fields ; i++ ) { if ( fields[i].cnum == cnum && is_static_field(fields[i].modifiers) ) { char *field_name; HprofType kind; jint size; type_from_signature(string_get(fields[i].sig_index), &kind, &size); field_name = string_get(fields[i].name_index); heap_name(field_name); heap_u1(kind); heap_element(kind, size, fvalues[i]); } } heap_u2((unsigned short)n_inst_fields); /* Does not include super class */ for ( i = 0 ; i < n_fields ; i++ ) { if ( fields[i].cnum == cnum && is_inst_field(fields[i].modifiers) ) { HprofType kind; jint size; char *field_name; field_name = string_get(fields[i].name_index); type_from_signature(string_get(fields[i].sig_index), &kind, &size); heap_name(field_name); heap_u1(kind); } } } else { char * class_name; int i; class_name = signature_to_name(sig); heap_printf("CLS %x (name=%s, trace=%u)\n", class_id, class_name, trace_serial_num); HPROF_FREE(class_name); if (super_id) { heap_printf("\tsuper\t\t%x\n", super_id); } if (loader_id) { heap_printf("\tloader\t\t%x\n", loader_id); } if (signers_id) { heap_printf("\tsigners\t\t%x\n", signers_id); } if (domain_id) { heap_printf("\tdomain\t\t%x\n", domain_id); } for ( i = 0 ; i < n_fields ; i++ ) { if ( fields[i].cnum == cnum && is_static_field(fields[i].modifiers) ) { HprofType kind; jint size; type_from_signature(string_get(fields[i].sig_index), &kind, &size); if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) { if (fvalues[i].i != 0 ) { char *field_name; field_name = string_get(fields[i].name_index); heap_printf("\tstatic %s\t%x\n", field_name, fvalues[i].i); } } } } for ( i = 0 ; i < n_cpool ; i++ ) { HprofType kind; jint size; type_from_signature(string_get(cpool[i].sig_index), &kind, &size); if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) { if (cpool[i].value.i != 0 ) { heap_printf("\tconstant pool entry %d\t%x\n", cpool[i].constant_pool_index, cpool[i].value.i); } } } }}/* Dump the instance fields in the right order. */static intdump_instance_fields(ClassIndex cnum, FieldInfo *fields, jvalue *fvalues, jint n_fields){ ClassIndex super_cnum; int i; int nbytes; HPROF_ASSERT(cnum!=0); nbytes = 0; for (i = 0; i < n_fields; i++) { if ( fields[i].cnum == cnum && is_inst_field(fields[i].modifiers) ) { HprofType kind; int size; type_from_signature(string_get(fields[i].sig_index), &kind, &size); heap_element(kind, size, fvalues[i]); nbytes += size; } } super_cnum = class_get_super(cnum); if ( super_cnum != 0 ) { nbytes += dump_instance_fields(super_cnum, fields, fvalues, n_fields); } return nbytes;}voidio_heap_instance_dump(ClassIndex cnum, ObjectIndex obj_id, SerialNumber trace_serial_num, ObjectIndex class_id, jint size, char *sig, FieldInfo *fields, jvalue *fvalues, jint n_fields){ CHECK_TRACE_SERIAL_NO(trace_serial_num); if (gdata->output_format == 'b') { jint inst_size; jint saved_inst_size; int i; int nbytes; inst_size = 0; for (i = 0; i < n_fields; i++) { if ( is_inst_field(fields[i].modifiers) ) { inst_size += size_from_field_info(fields[i].primSize); } } /* Verify that the instance size we have calculated as we went * through the fields, matches what is saved away with this * class. */ saved_inst_size = class_get_inst_size(cnum); if ( saved_inst_size == -1 ) { class_set_inst_size(cnum, inst_size); } else if ( saved_inst_size != inst_size ) { HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in instance dump"); } heap_tag(HPROF_GC_INSTANCE_DUMP); heap_id(obj_id); heap_u4(trace_serial_num); heap_id(class_id); heap_u4(inst_size); /* Must match inst_size in class dump */ /* Order must be class, super, super's super, ... */ nbytes = dump_instance_fields(cnum, fields, fvalues, n_fields); HPROF_ASSERT(nbytes==inst_size); } else { char * class_name; int i; class_name = signature_to_name(sig); heap_printf("OBJ %x (sz=%u, trace=%u, class=%s@%x)\n", obj_id, size, trace_serial_num, class_name, class_id); HPROF_FREE(class_name); for (i = 0; i < n_fields; i++) { if ( is_inst_field(fields[i].modifiers) ) { HprofType kind; int size; type_from_signature(string_get(fields[i].sig_index), &kind, &size); if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) { if (fvalues[i].i != 0 ) { char *sep; ObjectIndex val_id; char *field_name; field_name = string_get(fields[i].name_index); val_id = (ObjectIndex)(fvalues[i].i); sep = (int)strlen(field_name) < 8 ? "\t" : ""; heap_printf("\t%s\t%s%x\n", field_name, sep, val_id); } } } } }}voidio_heap_object_array(ObjectIndex obj_id, SerialNumber trace_serial_num, jint size, jint num_elements, char *sig, ObjectIndex *values, ObjectIndex class_id){ CHECK_TRACE_SERIAL_NO(trace_serial_num); if (gdata->output_format == 'b') { heap_tag(HPROF_GC_OBJ_ARRAY_DUMP); heap_id(obj_id); heap_u4(trace_serial_num); heap_u4(num_elements); heap_id(class_id); heap_elements(HPROF_NORMAL_OBJECT, num_elements, (jint)sizeof(HprofId), (void*)values); } else { char *name; int i; name = signature_to_name(sig); heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s@%x)\n", obj_id, size, trace_serial_num, num_elements, name, class_id); for (i = 0; i < num_elements; i++) { ObjectIndex id; id = values[i]; if (id != 0) { heap_printf("\t[%u]\t\t%x\n", i, id); } } HPROF_FREE(name); }}voidio_heap_prim_array(ObjectIndex obj_id, SerialNumber trace_serial_num, jint size, jint num_elements, char *sig, void *elements){ CHECK_TRACE_SERIAL_NO(trace_serial_num); if (gdata->output_format == 'b') { HprofType kind; jint esize; type_array(sig, &kind, &esize); HPROF_ASSERT(HPROF_TYPE_IS_PRIMITIVE(kind)); heap_tag(HPROF_GC_PRIM_ARRAY_DUMP); heap_id(obj_id); heap_u4(trace_serial_num); heap_u4(num_elements); heap_u1(kind); heap_elements(kind, num_elements, esize, elements); } else { char *name; name = signature_to_name(sig); heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s)\n", obj_id, size, trace_serial_num, num_elements, name); HPROF_FREE(name); }}/* Move file bytes into supplied raw interface */static voidwrite_raw_from_file(int fd, jlong byteCount, void (*raw_interface)(void *,int)){ char *buf; int buf_len; int left; int nbytes; HPROF_ASSERT(fd >= 0); /* Move contents of this file into output file. */ buf_len = FILE_IO_BUFFER_SIZE*2; /* Twice as big! */ buf = HPROF_MALLOC(buf_len); HPROF_ASSERT(buf!=NULL); /* Keep track of how many we have left */ left = (int)byteCount; do { int count; count = buf_len; if ( count > left ) count = left; nbytes = md_read(fd, buf, count); if (nbytes < 0) { system_error("read", nbytes, errno); break; } if (nbytes == 0) { break; } if ( nbytes > 0 ) { (*raw_interface)(buf, nbytes); left -= nbytes; } } while ( left > 0 ); if (left > 0 && nbytes == 0) { HPROF_ERROR(JNI_TRUE, "File size is smaller than bytes written"); } HPROF_FREE(buf);}/* Write out a heap segment, and copy remainder to top of file. */static voiddump_heap_segment_and_reset(jlong segment_size){ int fd; char *last_chunk; jlong last_chunk_len; HPROF_ASSERT(gdata->heap_fd >= 0); /* Flush all bytes to the heap dump file */ heap_flush(); /* Last segment? */ last_chunk_len = gdata->heap_write_count - segment_size; HPROF_ASSERT(last_chunk_len>=0); /* Re-open in proper way, binary vs. ascii is important */ if (gdata->output_format == 'b') { int tag; if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */ tag = HPROF_HEAP_DUMP_SEGMENT; /* 1.0.2 */ } else { tag = HPROF_HEAP_DUMP; /* Just one segment */ HPROF_ASSERT(last_chunk_len==0); } /* Write header for binary heap dump (don't know size until now) */ write_header(tag, (jint)segment_size); fd = md_open_binary(gdata->heapfilename); } else { fd = md_open(gdata->heapfilename); } /* Move file bytes into hprof dump file */ write_raw_from_file(fd, segment_size, &write_raw); /* Clear the byte count and reset the heap file. */ if ( md_seek(gdata->heap_fd, (jlong)0) != (jlong)0 ) { HPROF_ERROR(JNI_TRUE, "Cannot seek to beginning of heap info file"); } gdata->heap_write_count = (jlong)0; gdata->heap_last_tag_position = (jlong)0; /* Move trailing bytes from heap dump file to beginning of file */ if ( last_chunk_len > 0 ) { write_raw_from_file(fd, last_chunk_len, &heap_raw); } /* Close the temp file handle */ md_close(fd);}voidio_heap_footer(void){ HPROF_ASSERT(gdata->heap_fd >= 0); /* Flush all bytes to the heap dump file */ heap_flush(); /* Send out the last (or maybe only) segment */ dump_heap_segment_and_reset(gdata->heap_write_count); /* Write out the last tag */ if (gdata->output_format != 'b') { write_printf("HEAP DUMP END\n"); } else { if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */ write_header(HPROF_HEAP_DUMP_END, 0); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?