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