hprof_io.c
来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 1,979 行 · 第 1/4 页
C
1,979 行
/* * @(#)hprof_io.c 1.56 05/12/06 * * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. *//* All I/O functionality for hprof. *//* * The hprof agent has many forms of output: * * format=b gdata->output_format=='b' * Binary format. Defined below. This is used by HAT. * This is NOT the same format as emitted by JVMPI. * * format=a gdata->output_format=='a' * Ascii format. Not exactly an ascii representation of the binary format. * * And many forms of dumps: * * heap=dump * A large dump that in this implementation is written to a separate * file first before being placed in the output file. Several reasons, * the binary form needs a byte count of the length in the header, and * references in this dump to other items need to be emitted first. * So it's two pass, or use a temp file and copy. * heap=sites * Dumps the sites in the order of most allocations. * cpu=samples * Dumps the traces in order of most hits * cpu=times * Dumps the traces in the order of most time spent there. * cpu=old (format=a only) * Dumps out an older form of cpu output (old -prof format) * monitor=y (format=a only) * Dumps out a list of monitors in order of most contended. * * This file also includes a binary format check function that will read * back in the hprof binary format and verify the syntax looks correct. * * WARNING: Besides the comments below, there is little format spec on this, * however see: * http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html#hprof */#include "hprof.h"typedef TableIndex HprofId;#include "hprof_ioname.h"#include "hprof_b_spec.h"static int type_size[ /*HprofType*/ ] = HPROF_TYPE_SIZES;static void dump_heap_segment_and_reset(jlong segment_size);static voidnot_implemented(void){}static IoNameIndexget_name_index(char *name){ if (name != NULL && gdata->output_format == 'b') { return ioname_find_or_create(name, NULL); } return 0;}static char *signature_to_name(char *sig){ char *ptr; char *basename; char *name; int i; int len; int name_len; if ( sig != NULL ) { switch ( sig[0] ) { case JVM_SIGNATURE_CLASS: ptr = strchr(sig+1, JVM_SIGNATURE_ENDCLASS); if ( ptr == NULL ) { basename = "Unknown_class"; break; } /*LINTED*/ name_len = (jint)(ptr - (sig+1)); name = HPROF_MALLOC(name_len+1); (void)memcpy(name, sig+1, name_len); name[name_len] = 0; for ( i = 0 ; i < name_len ; i++ ) { if ( name[i] == '/' ) name[i] = '.'; } return name; case JVM_SIGNATURE_ARRAY: basename = signature_to_name(sig+1); len = (int)strlen(basename); name_len = len+2; name = HPROF_MALLOC(name_len+1); (void)memcpy(name, basename, len); (void)memcpy(name+len, "[]", 2); name[name_len] = 0; HPROF_FREE(basename); return name; case JVM_SIGNATURE_FUNC: ptr = strchr(sig+1, JVM_SIGNATURE_ENDFUNC); if ( ptr == NULL ) { basename = "Unknown_method"; break; } basename = "()"; /* Someday deal with method signatures */ break; case JVM_SIGNATURE_BYTE: basename = "byte"; break; case JVM_SIGNATURE_CHAR: basename = "char"; break; case JVM_SIGNATURE_ENUM: basename = "enum"; break; case JVM_SIGNATURE_FLOAT: basename = "float"; break; case JVM_SIGNATURE_DOUBLE: basename = "double"; break; case JVM_SIGNATURE_INT: basename = "int"; break; case JVM_SIGNATURE_LONG: basename = "long"; break; case JVM_SIGNATURE_SHORT: basename = "short"; break; case JVM_SIGNATURE_VOID: basename = "void"; break; case JVM_SIGNATURE_BOOLEAN: basename = "boolean"; break; default: basename = "Unknown_class"; break; } } else { basename = "Unknown_class"; } /* Simple basename */ name_len = (int)strlen(basename); name = HPROF_MALLOC(name_len+1); (void)strcpy(name, basename); return name;}static intsize_from_field_info(int size){ if ( size == 0 ) { size = (int)sizeof(HprofId); } return size;}static voidtype_from_signature(const char *sig, HprofType *kind, jint *size){ *kind = HPROF_NORMAL_OBJECT; *size = 0; switch ( sig[0] ) { case JVM_SIGNATURE_ENUM: case JVM_SIGNATURE_CLASS: case JVM_SIGNATURE_ARRAY: *kind = HPROF_NORMAL_OBJECT; break; case JVM_SIGNATURE_BOOLEAN: *kind = HPROF_BOOLEAN; break; case JVM_SIGNATURE_CHAR: *kind = HPROF_CHAR; break; case JVM_SIGNATURE_FLOAT: *kind = HPROF_FLOAT; break; case JVM_SIGNATURE_DOUBLE: *kind = HPROF_DOUBLE; break; case JVM_SIGNATURE_BYTE: *kind = HPROF_BYTE; break; case JVM_SIGNATURE_SHORT: *kind = HPROF_SHORT; break; case JVM_SIGNATURE_INT: *kind = HPROF_INT; break; case JVM_SIGNATURE_LONG: *kind = HPROF_LONG; break; default: HPROF_ASSERT(0); break; } *size = type_size[*kind];}static voidtype_array(const char *sig, HprofType *kind, jint *elem_size){ *kind = 0; *elem_size = 0; switch ( sig[0] ) { case JVM_SIGNATURE_ARRAY: type_from_signature(sig+1, kind, elem_size); break; }}static voidsystem_error(const char *system_call, int rc, int errnum){ char buf[256]; char details[256]; details[0] = 0; if ( errnum != 0 ) { md_system_error(details, (int)sizeof(details)); } else if ( rc >= 0 ) { (void)strcpy(details,"Only part of buffer processed"); } if ( details[0] == 0 ) { (void)strcpy(details,"Unknown system error condition"); } (void)md_snprintf(buf, sizeof(buf), "System %s failed: %s\n", system_call, details); HPROF_ERROR(JNI_TRUE, buf);}static void system_write(int fd, void *buf, int len, jboolean socket){ int res; HPROF_ASSERT(fd>=0); if (socket) { res = md_send(fd, buf, len, 0); if (res < 0 || res!=len) { system_error("send", res, errno); } } else { res = md_write(fd, buf, len); if (res < 0 || res!=len) { system_error("write", res, errno); } }}static voidwrite_flush(void){ HPROF_ASSERT(gdata->fd >= 0); if (gdata->write_buffer_index) { system_write(gdata->fd, gdata->write_buffer, gdata->write_buffer_index, gdata->socket); gdata->write_buffer_index = 0; }}static voidheap_flush(void){ HPROF_ASSERT(gdata->heap_fd >= 0); if (gdata->heap_buffer_index) { gdata->heap_write_count += (jlong)gdata->heap_buffer_index; system_write(gdata->heap_fd, gdata->heap_buffer, gdata->heap_buffer_index, JNI_FALSE); gdata->heap_buffer_index = 0; }}static void write_raw(void *buf, int len){ HPROF_ASSERT(gdata->fd >= 0); if (gdata->write_buffer_index + len > gdata->write_buffer_size) { write_flush(); if (len > gdata->write_buffer_size) { system_write(gdata->fd, buf, len, gdata->socket); return; } } (void)memcpy(gdata->write_buffer + gdata->write_buffer_index, buf, len); gdata->write_buffer_index += len;}static voidwrite_u4(unsigned i){ i = md_htonl(i); write_raw(&i, (jint)sizeof(unsigned));}static voidwrite_u8(jlong t){ write_u4((jint)jlong_high(t)); write_u4((jint)jlong_low(t));}static voidwrite_u2(unsigned short i){ i = md_htons(i); write_raw(&i, (jint)sizeof(unsigned short));}static voidwrite_u1(unsigned char i){ write_raw(&i, (jint)sizeof(unsigned char));}static voidwrite_id(HprofId i){ write_u4(i);}static void write_current_ticks(void){ write_u4((jint)(md_get_microsecs() - gdata->micro_sec_ticks));}static void write_header(unsigned char type, jint length){ write_u1(type); write_current_ticks(); write_u4(length);}static voidwrite_index_id(HprofId index){ write_id(index);}static IoNameIndexwrite_name_first(char *name){ if ( name == NULL ) { return 0; } if (gdata->output_format == 'b') { IoNameIndex name_index; jboolean new_one; new_one = JNI_FALSE; name_index = ioname_find_or_create(name, &new_one); if ( new_one ) { int len; len = (int)strlen(name); write_header(HPROF_UTF8, len + (jint)sizeof(HprofId)); write_index_id(name_index); write_raw(name, len); } return name_index; } return 0;}static void write_printf(char *fmt, ...){ char buf[1024]; va_list args; va_start(args, fmt); (void)md_vsnprintf(buf, sizeof(buf), fmt, args); buf[sizeof(buf)-1] = 0; write_raw(buf, (int)strlen(buf)); va_end(args);}static voidwrite_thread_serial_number(SerialNumber thread_serial_num, int with_comma){ if ( thread_serial_num != 0 ) { CHECK_THREAD_SERIAL_NO(thread_serial_num); if ( with_comma ) { write_printf(" thread %d,", thread_serial_num); } else { write_printf(" thread %d", thread_serial_num); } } else { if ( with_comma ) { write_printf(" <unknown thread>,"); } else { write_printf(" <unknown thread>"); } }}static void heap_raw(void *buf, int len){ HPROF_ASSERT(gdata->heap_fd >= 0); if (gdata->heap_buffer_index + len > gdata->heap_buffer_size) { heap_flush(); if (len > gdata->heap_buffer_size) { gdata->heap_write_count += (jlong)len; system_write(gdata->heap_fd, buf, len, JNI_FALSE); return; } } (void)memcpy(gdata->heap_buffer + gdata->heap_buffer_index, buf, len); gdata->heap_buffer_index += len;}static voidheap_u4(unsigned i){ i = md_htonl(i); heap_raw(&i, (jint)sizeof(unsigned));}static voidheap_u8(jlong i){ heap_u4((jint)jlong_high(i)); heap_u4((jint)jlong_low(i));}static voidheap_u2(unsigned short i){ i = md_htons(i); heap_raw(&i, (jint)sizeof(unsigned short));}static voidheap_u1(unsigned char i){ heap_raw(&i, (jint)sizeof(unsigned char));}/* Write out the first byte of a heap tag */static voidheap_tag(unsigned char tag){ jlong pos; /* Current position in virtual heap dump file */ pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index; if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */ if ( pos >= gdata->maxHeapSegment ) { /* Flush all bytes to the heap dump file */ heap_flush();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?