hprof_reference.c
来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 812 行 · 第 1/2 页
C
812 行
case INFO_OBJECT_REF_DATA: switch ( info->refKind ) { case JVMTI_HEAP_REFERENCE_FIELD: case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: /* Should never be seen on a class dump */ HPROF_ASSERT(0); break; case JVMTI_HEAP_REFERENCE_STATIC_FIELD: if ( skip_fields == JNI_TRUE ) { break; } ovalue = empty_value; ovalue.i = info->object_index; fill_in_field_value(list, fields, fvalues, n_fields, info->index, ovalue, 0); n_fields_set++; HPROF_ASSERT(n_fields_set <= n_fields); break; case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: { ConstantPoolValue cpv; ObjectIndex cp_object_index; SiteIndex cp_site_index; ClassIndex cp_cnum; cp_object_index = info->object_index; HPROF_ASSERT(cp_object_index!=0); cp_site_index = object_get_site(cp_object_index); HPROF_ASSERT(cp_site_index!=0); cp_cnum = site_get_class_index(cp_site_index); cpv.constant_pool_index = info->index; cpv.sig_index = class_get_signature(cp_cnum); cpv.value.i = cp_object_index; stack_push(cpool_values, (void*)&cpv); cpool_count++; break; } case JVMTI_HEAP_REFERENCE_SIGNERS: signers_index = info->object_index; break; case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN: domain_index = info->object_index; break; case JVMTI_HEAP_REFERENCE_CLASS_LOADER: case JVMTI_HEAP_REFERENCE_INTERFACE: default: /* Ignore, not needed */ break; } break; case INFO_PRIM_FIELD_DATA: if ( skip_fields == JNI_TRUE ) { break; } HPROF_ASSERT(info->primType!=0); HPROF_ASSERT(info->length==-1); HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_STATIC_FIELD); ovalue = get_key_value(index); fill_in_field_value(list, fields, fvalues, n_fields, info->index, ovalue, info->primType); n_fields_set++; HPROF_ASSERT(n_fields_set <= n_fields); break; case INFO_PRIM_ARRAY_DATA: default: /* Should never see these */ HPROF_ASSERT(0); break; } index = info->next; } /* Get constant pool data if we have any */ HPROF_ASSERT(cpool_count==stack_depth(cpool_values)); if ( cpool_count > 0 ) { cpool = (ConstantPoolValue*)stack_element(cpool_values, 0); } io_heap_class_dump(cnum, sig, object_index, trace_serial_num, super_index, loader_object_index(env, loader_index), signers_index, domain_index, (jint)size, cpool_count, cpool, n_fields, fields, fvalues); stack_term(cpool_values); if ( fvalues != NULL ) { HPROF_FREE(fvalues); }}/* Walk all references for an ObjectIndex and construct the hprof INST dump. */static voiddump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list){ jvmtiPrimitiveType primType; SiteIndex site_index; SerialNumber trace_serial_num; RefIndex index; ObjectIndex class_index; jlong size; ClassIndex cnum; char *sig; void *elements; jint num_elements; jint num_bytes; ObjectIndex *values; FieldInfo *fields; jvalue *fvalues; jint n_fields; jboolean skip_fields; jint n_fields_set; ObjectKind kind; TraceIndex trace_index; jboolean is_array; jboolean is_prim_array; HPROF_ASSERT(object_index!=0); kind = object_get_kind(object_index); if ( kind == OBJECT_CLASS ) { return; } site_index = object_get_site(object_index); HPROF_ASSERT(site_index!=0); cnum = site_get_class_index(site_index); HPROF_ASSERT(cnum!=0); size = (jlong)object_get_size(object_index); trace_index = site_get_trace_index(site_index); HPROF_ASSERT(trace_index!=0); trace_serial_num = trace_get_serial_number(trace_index); sig = string_get(class_get_signature(cnum)); class_index = class_get_object_index(cnum); values = NULL; elements = NULL; num_elements = 0; num_bytes = 0; n_fields = 0; skip_fields = JNI_FALSE; n_fields_set = 0; fields = NULL; fvalues = NULL; index = list; is_array = JNI_FALSE; is_prim_array = JNI_FALSE; if ( sig[0] != JVM_SIGNATURE_ARRAY ) { if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) { /* Trouble getting all the fields, can't trust field index values */ skip_fields = JNI_TRUE; /* It is assumed that the reason why we didn't get the fields * was because the class is not prepared. */ if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) { if ( list != 0 ) { dump_ref_list(list); debug_message("Instance of unprepared class with refs: %s\n", sig); } else { debug_message("Instance of unprepared class without refs: %s\n", sig); } HPROF_ERROR(JNI_FALSE, "Big Trouble with unprepared class instances"); } } if ( n_fields > 0 ) { fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue)); (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue)); } } else { is_array = JNI_TRUE; if ( sig[0] != 0 && sigToPrimSize(sig+1) != 0 ) { is_prim_array = JNI_TRUE; } } while ( index != 0 ) { RefInfo *info; jvalue ovalue; static jvalue empty_value; info = get_info(index); /* Process reference objects, many not used right now. */ switch ( info->flavor ) { case INFO_OBJECT_REF_DATA: switch ( info->refKind ) { case JVMTI_HEAP_REFERENCE_SIGNERS: case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN: case JVMTI_HEAP_REFERENCE_CLASS_LOADER: case JVMTI_HEAP_REFERENCE_INTERFACE: case JVMTI_HEAP_REFERENCE_STATIC_FIELD: case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: /* Should never be seen on an instance dump */ HPROF_ASSERT(0); break; case JVMTI_HEAP_REFERENCE_FIELD: if ( skip_fields == JNI_TRUE ) { break; } HPROF_ASSERT(is_array!=JNI_TRUE); ovalue = empty_value; ovalue.i = info->object_index; fill_in_field_value(list, fields, fvalues, n_fields, info->index, ovalue, 0); n_fields_set++; HPROF_ASSERT(n_fields_set <= n_fields); break; case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: /* We get each object element one at a time. */ HPROF_ASSERT(is_array==JNI_TRUE); HPROF_ASSERT(is_prim_array!=JNI_TRUE); if ( num_elements <= info->index ) { int nbytes; if ( values == NULL ) { num_elements = info->index + 1; nbytes = num_elements*(int)sizeof(ObjectIndex); values = (ObjectIndex*)HPROF_MALLOC(nbytes); (void)memset(values, 0, nbytes); } else { void *new_values; int new_size; int obytes; obytes = num_elements*(int)sizeof(ObjectIndex); new_size = info->index + 1; nbytes = new_size*(int)sizeof(ObjectIndex); new_values = (void*)HPROF_MALLOC(nbytes); (void)memcpy(new_values, values, obytes); (void)memset(((char*)new_values)+obytes, 0, nbytes-obytes); HPROF_FREE(values); num_elements = new_size; values = new_values; } } HPROF_ASSERT(values[info->index]==0); values[info->index] = info->object_index; break; default: /* Ignore, not needed */ break; } break; case INFO_PRIM_FIELD_DATA: if ( skip_fields == JNI_TRUE ) { break; } HPROF_ASSERT(info->primType!=0); HPROF_ASSERT(info->length==-1); HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_FIELD); HPROF_ASSERT(is_array!=JNI_TRUE); ovalue = get_key_value(index); fill_in_field_value(list, fields, fvalues, n_fields, info->index, ovalue, info->primType); n_fields_set++; HPROF_ASSERT(n_fields_set <= n_fields); break; case INFO_PRIM_ARRAY_DATA: /* Should only be one, and it's handled below */ HPROF_ASSERT(info->refKind==0); /* We assert that nothing else was saved with this array */ HPROF_ASSERT(index==list&&info->next==0); HPROF_ASSERT(is_array==JNI_TRUE); HPROF_ASSERT(is_prim_array==JNI_TRUE); primType = info->primType; elements = get_key_elements(index, primType, &num_elements, &num_bytes); HPROF_ASSERT(info->length==num_elements); size = num_bytes; break; default: HPROF_ASSERT(0); break; } index = info->next; } if ( is_array == JNI_TRUE ) { if ( is_prim_array == JNI_TRUE ) { HPROF_ASSERT(values==NULL); io_heap_prim_array(object_index, trace_serial_num, (jint)size, num_elements, sig, elements); } else { HPROF_ASSERT(elements==NULL); io_heap_object_array(object_index, trace_serial_num, (jint)size, num_elements, sig, values, class_index); } } else { io_heap_instance_dump(cnum, object_index, trace_serial_num, class_index, (jint)size, sig, fields, fvalues, n_fields); } if ( values != NULL ) { HPROF_FREE(values); } if ( fvalues != NULL ) { HPROF_FREE(fvalues); } if ( elements != NULL ) { /* Do NOT free elements, it's a key in the table, leave it be */ }}/* External interfaces. */voidreference_init(void){ HPROF_ASSERT(gdata->reference_table==NULL); gdata->reference_table = table_initialize("Ref", 2048, 4096, 0, (int)sizeof(RefInfo));}/* Save away a reference to an object */RefIndexreference_obj(RefIndex next, jvmtiHeapReferenceKind refKind, ObjectIndex object_index, jint index, jint length){ static RefInfo empty_info; RefIndex entry; RefInfo info; info = empty_info; info.flavor = INFO_OBJECT_REF_DATA; info.refKind = refKind; info.object_index = object_index; info.index = index; info.length = length; info.next = next; entry = table_create_entry(gdata->reference_table, NULL, 0, (void*)&info); return entry;}/* Save away some primitive field data */RefIndexreference_prim_field(RefIndex next, jvmtiHeapReferenceKind refKind, jvmtiPrimitiveType primType, jvalue field_value, jint field_index){ static RefInfo empty_info; RefIndex entry; RefInfo info; HPROF_ASSERT(primType==JVMTI_PRIMITIVE_TYPE_BOOLEAN?(field_value.b==1||field_value.b==0):1); info = empty_info; info.flavor = INFO_PRIM_FIELD_DATA; info.refKind = refKind; info.primType = primType; info.index = field_index; info.length = -1; info.next = next; entry = table_create_entry(gdata->reference_table, (void*)&field_value, (int)sizeof(jvalue), (void*)&info); return entry;}/* Save away some primitive array data */RefIndexreference_prim_array(RefIndex next, jvmtiPrimitiveType primType, const void *elements, jint elementCount){ static RefInfo empty_info; RefIndex entry; RefInfo info; HPROF_ASSERT(next == 0); HPROF_ASSERT(elementCount >= 0); HPROF_ASSERT(elements != NULL); info = empty_info; info.flavor = INFO_PRIM_ARRAY_DATA; info.refKind = 0; info.primType = primType; info.index = 0; info.length = elementCount; info.next = next; entry = table_create_entry(gdata->reference_table, (void*)elements, elementCount * get_prim_size(primType), (void*)&info); return entry;}voidreference_cleanup(void){ if ( gdata->reference_table == NULL ) { return; } table_cleanup(gdata->reference_table, NULL, NULL); gdata->reference_table = NULL;}void reference_dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list){ dump_instance(env, object_index, list);}void reference_dump_class(JNIEnv *env, ObjectIndex object_index, RefIndex list){ dump_class_and_supers(env, object_index, list);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?