hprof_class.c

来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 674 行 · 第 1/2 页

C
674
字号
/* * @(#)hprof_class.c	1.35 05/11/17 *  * 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. *//* Table of class information.  * *   Each element in this table is identified with a ClassIndex. *   Each element is uniquely identified by it's signature and loader. *   Every class load has a unique class serial number. *   While loaded, each element will have a cache of a global reference *     to it's jclass object, plus jmethodID's as needed. *   Method signatures and names are obtained via BCI. *   Methods can be identified with a ClassIndex and MethodIndex pair, *     where the MethodIndex matches the index of the method name and *     signature arrays obtained from the BCI pass. *   Strings are stored in the string table and a StringIndex is used. *   Class Loaders are stored in the loader table and a LoaderIndex is used. *   Since the jclass object is an object, at some point an object table *      entry may be allocated for the jclass as an ObjectIndex. */#include "hprof.h"/* Effectively represents a jclass object. *//* These table elements are made unique by and sorted by signature name. */typedef struct ClassKey {    StringIndex    sig_string_index;    /* Signature of class */    LoaderIndex    loader_index;	/* Index for class loader */} ClassKey;/* Each class could contain method information, gotten from BCI callback */typedef struct MethodInfo {    StringIndex  name_index;    /* Method name, index into string table */    StringIndex  sig_index;     /* Method signature, index into string table */    jmethodID    method_id;	/* Method ID, possibly NULL at first */} MethodInfo;/* The basic class information we save */typedef struct ClassInfo {    jclass         classref;	        /* Global ref to jclass */    MethodInfo    *method;		/* Array of method data */    int            method_count;	/* Count of methods */    ObjectIndex    object_index;	/* Optional object index for jclass */    SerialNumber   serial_num; 		/* Unique to the actual class load */    ClassStatus    status;		/* Current class status (bit mask) */    ClassIndex     super;		/* Super class in this table */    StringIndex    name;                /* Name of class */    jint           inst_size;           /* #bytes needed for instance fields */    jint           field_count;         /* Number of all fields */    FieldInfo     *field;		/* Pointer to all FieldInfo's */} ClassInfo;/* Private interfaces */static ClassKey*get_pkey(ClassIndex index){    void *key_ptr;    int   key_len;    table_get_key(gdata->class_table, index, (void*)&key_ptr, &key_len);    HPROF_ASSERT(key_len==sizeof(ClassKey));    HPROF_ASSERT(key_ptr!=NULL);    return (ClassKey*)key_ptr;}static voidfillin_pkey(const char *sig, LoaderIndex loader_index, ClassKey *pkey){    static ClassKey empty_key;        HPROF_ASSERT(loader_index!=0);    *pkey                  = empty_key;    pkey->sig_string_index = string_find_or_create(sig);    pkey->loader_index     = loader_index;}static ClassInfo *get_info(ClassIndex index){    ClassInfo *info;    info = (ClassInfo*)table_get_info(gdata->class_table, index);    return info;}static voidfill_info(TableIndex index, ClassKey *pkey){    ClassInfo *info;    char      *sig;        info = get_info(index);    info->serial_num = gdata->class_serial_number_counter++;    info->method_count = 0;    info->inst_size = -1;    info->field_count = -1;    info->field = NULL;    sig = string_get(pkey->sig_string_index);    if ( sig[0] != JVM_SIGNATURE_CLASS ) {	info->name = pkey->sig_string_index;    } else {	int        len;	len = string_get_len(pkey->sig_string_index);	if ( len > 2  ) {	    char      *name;	    	    /* Class signature looks like "Lname;", we want "name" here. */	    name = HPROF_MALLOC(len-1);	    (void)memcpy(name, sig+1, len-2);	    name[len-2] = 0;	    info->name = string_find_or_create(name);	    HPROF_FREE(name);	} else {	    /* This would be strange, a class signature not in "Lname;" form? */	    info->name = pkey->sig_string_index;	}   }}static ClassIndexfind_entry(ClassKey *pkey){    ClassIndex index;        index = table_find_entry(gdata->class_table, 				(void*)pkey, (int)sizeof(ClassKey));    return index;}static ClassIndexcreate_entry(ClassKey *pkey){    ClassIndex index;        index = table_create_entry(gdata->class_table, 				(void*)pkey, (int)sizeof(ClassKey), NULL);    fill_info(index, pkey);    return index;}static ClassIndexfind_or_create_entry(ClassKey *pkey){    ClassIndex      index;        HPROF_ASSERT(pkey!=NULL);    HPROF_ASSERT(pkey->loader_index!=0);    index = find_entry(pkey);    if ( index == 0 ) {	index = create_entry(pkey);    }    return index;}static voiddelete_classref(JNIEnv *env, ClassInfo *info, jclass klass){    jclass ref;    int    i;        HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(info!=NULL);        for ( i = 0 ; i < info->method_count ; i++ ) {	info->method[i].method_id  = NULL;    }    ref = info->classref;    if ( klass != NULL ) {        info->classref = newGlobalReference(env, klass);    } else {        info->classref = NULL;    }    if ( ref != NULL ) {        deleteGlobalReference(env, ref);    }}static voidcleanup_item(TableIndex index, void *key_ptr, int key_len, 				void *info_ptr, void *arg){    ClassInfo *info;    /* Cleanup any information in this ClassInfo structure. */    HPROF_ASSERT(key_ptr!=NULL);    HPROF_ASSERT(key_len==sizeof(ClassKey));    HPROF_ASSERT(info_ptr!=NULL);    info = (ClassInfo *)info_ptr;    if ( info->method_count > 0 ) {        HPROF_FREE((void*)info->method);	info->method_count = 0;        info->method       = NULL;    }    if ( info->field != NULL ) {        HPROF_FREE((void*)info->field);	info->field_count = 0;        info->field      = NULL;    }}static voiddelete_ref_item(TableIndex index, void *key_ptr, int key_len, 				void *info_ptr, void *arg){    delete_classref((JNIEnv*)arg, (ClassInfo*)info_ptr, NULL);}static voidlist_item(TableIndex index, void *key_ptr, int key_len, 				void *info_ptr, void *arg){    ClassInfo *info;    ClassKey   key;    char      *sig;    int        i;    HPROF_ASSERT(key_ptr!=NULL);    HPROF_ASSERT(key_len==sizeof(ClassKey));    HPROF_ASSERT(info_ptr!=NULL);    key = *((ClassKey*)key_ptr);    sig = string_get(key.sig_string_index);    info = (ClassInfo *)info_ptr;    debug_message( 	     "0x%08x: Class %s, SN=%u, status=0x%08x, ref=%p,"	     " method_count=%d\n",             index,              (const char *)sig, 	     info->serial_num,             info->status, 	     (void*)info->classref,	     info->method_count);    if ( info->method_count > 0 ) {	for ( i = 0 ; i < info->method_count ; i++ ) {            debug_message( 		"    Method %d: \"%s\", sig=\"%s\", method=%p\n",		i,		string_get(info->method[i].name_index),		string_get(info->method[i].sig_index),		(void*)info->method[i].method_id);	}    }}static voidall_status_remove(TableIndex index, void *key_ptr, int key_len, 				void *info_ptr, void *arg){    ClassInfo   *info;    ClassStatus  status;    HPROF_ASSERT(info_ptr!=NULL);    /*LINTED*/    status = (ClassStatus)(long)(ptrdiff_t)arg;    info = (ClassInfo *)info_ptr;    info->status &= (~status);}static voidunload_walker(TableIndex index, void *key_ptr, int key_len, 				void *info_ptr, void *arg){    ClassInfo        *info;    HPROF_ASSERT(info_ptr!=NULL);    info = (ClassInfo *)info_ptr;    if ( ! ( info->status & CLASS_IN_LOAD_LIST ) ) {	if ( ! (info->status & (CLASS_SPECIAL|CLASS_SYSTEM|CLASS_UNLOADED)) ) {            io_write_class_unload(info->serial_num, info->object_index);            info->status |= CLASS_UNLOADED;            delete_classref((JNIEnv*)arg, info, NULL);	}    }}/* External interfaces */voidclass_init(void){    HPROF_ASSERT(gdata->class_table==NULL);    gdata->class_table = table_initialize("Class", 512, 512, 511,                                    (int)sizeof(ClassInfo));}ClassIndexclass_find_or_create(const char *sig, LoaderIndex loader_index){    ClassKey key;        fillin_pkey(sig, loader_index, &key);    return find_or_create_entry(&key);}ClassIndexclass_create(const char *sig, LoaderIndex loader_index){    ClassKey key;        fillin_pkey(sig, loader_index, &key);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?