hprof_util.c

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

C
1,736
字号
        *pname = NULL;    }    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get source file name");    }}static void getClassFields(jclass klass, jint* pn_fields, jfieldID** pfields){    jvmtiError error;    jint       status;       HPROF_ASSERT(klass!=NULL);    *pn_fields = 0;    *pfields      = NULL;        /* Get class status */    status = getClassStatus(klass);        /* Arrays have no fields */    if ( status & JVMTI_CLASS_STATUS_ARRAY ) {        return;    }    /* Primitives have no fields */    if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {        return;    }       /* If the class is not prepared, we have a problem? */    if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {        HPROF_ERROR(JNI_FALSE, "Class not prepared when needing fields");        return;    }    /* Now try and get all the fields */    error         = JVMTI_FUNC_PTR(gdata->jvmti,GetClassFields)                        (gdata->jvmti, klass, pn_fields, pfields);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get class field list");    }}static jint getFieldModifiers(jclass klass, jfieldID field){    jvmtiError error;    jint       modifiers;        HPROF_ASSERT(klass!=NULL);    HPROF_ASSERT(field!=NULL);    modifiers = 0;    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)            (gdata->jvmti, klass, field, &modifiers);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get field modifiers");    }    return modifiers;}static void getFieldName(jclass klass, jfieldID field, char** pname, char** psignature,                        char **pgeneric_signature){    jvmtiError error;    char *generic_signature;        generic_signature = NULL;    *pname = NULL;    *psignature = NULL;    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)            (gdata->jvmti, klass, field, pname, psignature, &generic_signature);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get field name");    }    if ( pgeneric_signature != NULL ) {        *pgeneric_signature = generic_signature;    } else {        jvmtiDeallocate(generic_signature);    }}static void      getImplementedInterfaces(jclass klass, jint* pn_interfaces,                        jclass** pinterfaces)/* WARNING: Must be called inside WITH_LOCAL_REFS */{    jvmtiError error;       *pn_interfaces = 0;    *pinterfaces   = NULL;    error          = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)                        (gdata->jvmti, klass, pn_interfaces, pinterfaces);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get class interface list");    }}static ClassIndexget_cnum(JNIEnv *env, jclass klass)/* WARNING: Must be called inside WITH_LOCAL_REFS */{    ClassIndex  cnum;    LoaderIndex loader_index;    char       *sig;    jobject     loader;    loader       = getClassLoader(klass);    loader_index = loader_find_or_create(env, loader);    getClassSignature(klass, &sig, NULL);    cnum = class_find_or_create(sig, loader_index);    jvmtiDeallocate(sig);    (void)class_new_classref(env, cnum, klass);    return cnum;}/* From primitive type, get signature letter */charprimTypeToSigChar(jvmtiPrimitiveType primType){    char sig_ch;    sig_ch = 0;    switch ( primType ) {        case JVMTI_PRIMITIVE_TYPE_BYTE:            sig_ch = JVM_SIGNATURE_BYTE;            break;        case JVMTI_PRIMITIVE_TYPE_CHAR:            sig_ch = JVM_SIGNATURE_CHAR;            break;        case JVMTI_PRIMITIVE_TYPE_FLOAT:            sig_ch = JVM_SIGNATURE_FLOAT;            break;        case JVMTI_PRIMITIVE_TYPE_DOUBLE:            sig_ch = JVM_SIGNATURE_DOUBLE;            break;        case JVMTI_PRIMITIVE_TYPE_INT:            sig_ch = JVM_SIGNATURE_INT;            break;        case JVMTI_PRIMITIVE_TYPE_LONG:            sig_ch = JVM_SIGNATURE_LONG;            break;        case JVMTI_PRIMITIVE_TYPE_SHORT:            sig_ch = JVM_SIGNATURE_SHORT;            break;        case JVMTI_PRIMITIVE_TYPE_BOOLEAN:            sig_ch = JVM_SIGNATURE_BOOLEAN;            break;        default:            sig_ch = 0;            break;    }    return sig_ch;}/* From signature, get primitive type */jvmtiPrimitiveTypesigToPrimType(char *sig){    jvmtiPrimitiveType primType;        primType = 0;    if ( sig == NULL || sig[0] == 0 ) {        return primType;    }    switch ( sig[0] ) {        case JVM_SIGNATURE_BYTE:            primType =  JVMTI_PRIMITIVE_TYPE_BYTE;            break;        case JVM_SIGNATURE_CHAR:            primType =  JVMTI_PRIMITIVE_TYPE_CHAR;            break;        case JVM_SIGNATURE_FLOAT:            primType =  JVMTI_PRIMITIVE_TYPE_FLOAT;            break;        case JVM_SIGNATURE_DOUBLE:            primType =  JVMTI_PRIMITIVE_TYPE_DOUBLE;            break;        case JVM_SIGNATURE_INT:            primType =  JVMTI_PRIMITIVE_TYPE_INT;            break;        case JVM_SIGNATURE_LONG:            primType =  JVMTI_PRIMITIVE_TYPE_LONG;            break;        case JVM_SIGNATURE_SHORT:            primType =  JVMTI_PRIMITIVE_TYPE_SHORT;            break;        case JVM_SIGNATURE_BOOLEAN:            primType =  JVMTI_PRIMITIVE_TYPE_BOOLEAN;            break;    }    return primType;}/* From signature, get primitive size */intsigToPrimSize(char *sig){    unsigned size;        size = 0;    if ( sig == NULL || sig[0] == 0 ) {        return size;    }    switch ( sig[0] ) {        case JVM_SIGNATURE_BYTE:        case JVM_SIGNATURE_BOOLEAN:            size =  1;            break;        case JVM_SIGNATURE_CHAR:        case JVM_SIGNATURE_SHORT:            size =  2;            break;        case JVM_SIGNATURE_FLOAT:        case JVM_SIGNATURE_INT:            size =  4;            break;        case JVM_SIGNATURE_DOUBLE:        case JVM_SIGNATURE_LONG:            size =  8;            break;    }    return size;}static void add_class_fields(JNIEnv *env, ClassIndex top_cnum, ClassIndex cnum,                 jclass klass, Stack *field_list, Stack *class_list)/* WARNING: Must be called inside WITH_LOCAL_REFS */{    jclass     *interfaces;    jint        n_interfaces;    jfieldID   *idlist;    jint        n_fields;    int         i;    int         depth;    int         skip_static_field_names;    jint        status;    HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(klass!=NULL);    HPROF_ASSERT(field_list!=NULL);    HPROF_ASSERT(class_list!=NULL);    /* If not the initial class, we can skip the static fields (perf issue) */    skip_static_field_names = (cnum != top_cnum);    /* Get class status */    status = getClassStatus(klass);        /* Arrays have no fields */    if ( status & JVMTI_CLASS_STATUS_ARRAY ) {        return;    }    /* Primitives have no fields */    if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {        return;    }    /* If the class is not prepared, we have a problem? */    if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {        char *sig;                getClassSignature(klass, &sig, NULL);        debug_message("Class signature is: %s\n", sig);        HPROF_ERROR(JNI_FALSE, "Class not prepared when needing all fields");        jvmtiDeallocate(sig);        return;    }    /* See if class already processed */    depth = stack_depth(class_list);    for ( i = depth-1 ; i >= 0 ; i-- ) {        if ( isSameObject(env, klass, *(jclass*)stack_element(class_list, i)) ) {            return;        }    }        /* Class or Interface, do implemented interfaces recursively */    getImplementedInterfaces(klass, &n_interfaces, &interfaces);    for ( i = 0 ; i < n_interfaces ; i++ ) {        add_class_fields(env, top_cnum,                         get_cnum(env, interfaces[i]), interfaces[i],                          field_list, class_list);    }    jvmtiDeallocate(interfaces);        /* Begin graph traversal, go up super chain recursively */    if ( !isInterface(klass) ) {        jclass super_klass;                super_klass = getSuperclass(env, klass);        if ( super_klass != NULL ) {            add_class_fields(env, top_cnum,                             get_cnum(env, super_klass), super_klass,                              field_list, class_list);        }    }        /* Only now we add klass to list so we don't repeat it later */    stack_push(class_list, &klass);    /* Now actually add the fields for this klass */    getClassFields(klass, &n_fields, &idlist);    for ( i = 0 ; i < n_fields ; i++ ) {        FieldInfo        finfo;        static FieldInfo empty_finfo;        finfo           = empty_finfo;        finfo.cnum      = cnum;        finfo.modifiers = getFieldModifiers(klass, idlist[i]);        if ( ( finfo.modifiers & JVM_ACC_STATIC ) == 0 ||             !skip_static_field_names ) {            char *field_name;            char *field_sig;                        getFieldName(klass, idlist[i], &field_name, &field_sig, NULL);            finfo.name_index = string_find_or_create(field_name);            finfo.sig_index  = string_find_or_create(field_sig);            finfo.primType   = sigToPrimType(field_sig);            finfo.primSize   = sigToPrimSize(field_sig);            jvmtiDeallocate(field_name);            jvmtiDeallocate(field_sig);        }        stack_push(field_list, &finfo);    }    jvmtiDeallocate(idlist);}void getAllClassFieldInfo(JNIEnv *env, jclass klass,                 jint* pn_fields, FieldInfo** pfields){    ClassIndex cnum;        *pfields      = NULL;    *pn_fields    = 0;        WITH_LOCAL_REFS(env, 1) {        Stack *class_list;        Stack *field_list;        int    nbytes;        cnum          = get_cnum(env, klass);        class_list    = stack_init( 16,  16, (int)sizeof(jclass));        field_list    = stack_init(128, 128, (int)sizeof(FieldInfo));        add_class_fields(env, cnum, cnum, klass, field_list, class_list);        *pn_fields    = stack_depth(field_list);        if ( (*pn_fields) > 0 ) {            nbytes        = (*pn_fields) * (int)sizeof(FieldInfo);            *pfields      = (FieldInfo*)HPROF_MALLOC(nbytes);            (void)memcpy(*pfields, stack_element(field_list, 0), nbytes);        }        stack_term(field_list);        stack_term(class_list);    } END_WITH_LOCAL_REFS;}void getMethodClass(jmethodID method, jclass *pclazz)/* WARNING: Must be called inside WITH_LOCAL_REFS */{    jvmtiError error;        HPROF_ASSERT(method!=NULL);    *pclazz = NULL;    error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)                (gdata->jvmti, method, pclazz);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get method class");    }}jboolean isMethodNative(jmethodID method){    jvmtiError error;    jboolean   isNative;        HPROF_ASSERT(method!=NULL);    error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)                (gdata->jvmti, method, &isNative);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot check is method native");    }    return isNative;}void getMethodName(jmethodID method, char** pname, char** psignature){    jvmtiError error;    char *generic_signature;        HPROF_ASSERT(method!=NULL);    generic_signature = NULL;    *pname = NULL;    *psignature = NULL;    error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodName)                (gdata->jvmti, method, pname, psignature, &generic_signature);    if ( error != JVMTI_ERROR_NONE ) {        HPROF_JVMTI_ERROR(error, "Cannot get method name");    }    jvmtiDeallocate(generic_signature);}voidgetPotentialCapabilities(jvmtiCapabilities *pcapabilities){    jvmtiError error;    (void)memset(pcapabilities,0,sizeof(jvmtiCapabilities));    error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)                (gdata->jvmti, pcapabilities);    if (error != JVMTI_ERROR_NONE) {        HPROF_ERROR(JNI_FALSE, "Unable to get potential JVMTI capabilities.");        error_exit_process(1); /* Kill entire process, no core dump wanted */    }}voidaddCapabilities(jvmtiCapabilities *pcapabilities){    jvmtiError error;    error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)                (gdata->jvmti, pcapabilities);    if (error != JVMTI_ERROR_NONE) {        HPROF_ERROR(JNI_FALSE, "Unable to get necessary JVMTI capabilities.");        error_exit_process(1); /* Kill entire process, no core dump wanted */    }

⌨️ 快捷键说明

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