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 + -
显示快捷键?