00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "hprof.h"
00064
00065
00066 enum {
00067 INFO_OBJECT_REF_DATA = 1,
00068 INFO_PRIM_FIELD_DATA = 2,
00069 INFO_PRIM_ARRAY_DATA = 3
00070 };
00071
00072
00073 typedef struct RefInfo {
00074 ObjectIndex object_index;
00075 jint index;
00076 jint length;
00077 RefIndex next;
00078 unsigned flavor : 8;
00079 unsigned refKind : 8;
00080 unsigned primType : 8;
00081 } RefInfo;
00082
00083
00084
00085
00086 static RefInfo *
00087 get_info(RefIndex index)
00088 {
00089 RefInfo *info;
00090
00091 info = (RefInfo*)table_get_info(gdata->reference_table, index);
00092 return info;
00093 }
00094
00095
00096 static jvalue
00097 get_key_value(RefIndex index)
00098 {
00099 void *key;
00100 int len;
00101 jvalue value;
00102 static jvalue empty_value;
00103
00104 key = NULL;
00105 table_get_key(gdata->reference_table, index, &key, &len);
00106 HPROF_ASSERT(key!=NULL);
00107 HPROF_ASSERT(len==(int)sizeof(jvalue));
00108 if ( key != NULL ) {
00109 (void)memcpy(&value, key, (int)sizeof(jvalue));
00110 } else {
00111 value = empty_value;
00112 }
00113 return value;
00114 }
00115
00116
00117 static jint
00118 get_prim_size(jvmtiPrimitiveType primType)
00119 {
00120 jint size;
00121
00122 switch ( primType ) {
00123 case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
00124 size = (jint)sizeof(jboolean);
00125 break;
00126 case JVMTI_PRIMITIVE_TYPE_BYTE:
00127 size = (jint)sizeof(jbyte);
00128 break;
00129 case JVMTI_PRIMITIVE_TYPE_CHAR:
00130 size = (jint)sizeof(jchar);
00131 break;
00132 case JVMTI_PRIMITIVE_TYPE_SHORT:
00133 size = (jint)sizeof(jshort);
00134 break;
00135 case JVMTI_PRIMITIVE_TYPE_INT:
00136 size = (jint)sizeof(jint);
00137 break;
00138 case JVMTI_PRIMITIVE_TYPE_FLOAT:
00139 size = (jint)sizeof(jfloat);
00140 break;
00141 case JVMTI_PRIMITIVE_TYPE_LONG:
00142 size = (jint)sizeof(jlong);
00143 break;
00144 case JVMTI_PRIMITIVE_TYPE_DOUBLE:
00145 size = (jint)sizeof(jdouble);
00146 break;
00147 default:
00148 HPROF_ASSERT(0);
00149 size = 1;
00150 break;
00151 }
00152 return size;
00153 }
00154
00155
00156 static void *
00157 get_key_elements(RefIndex index, jvmtiPrimitiveType primType,
00158 jint *nelements, jint *nbytes)
00159 {
00160 void *key;
00161 jint byteLen;
00162
00163 HPROF_ASSERT(nelements!=NULL);
00164 HPROF_ASSERT(nbytes!=NULL);
00165
00166 table_get_key(gdata->reference_table, index, &key, &byteLen);
00167 HPROF_ASSERT(byteLen>=0);
00168 HPROF_ASSERT(byteLen!=0?key!=NULL:key==NULL);
00169 *nbytes = byteLen;
00170 *nelements = byteLen / get_prim_size(primType);
00171 return key;
00172 }
00173
00174
00175 static void
00176 dump_ref_info(RefInfo *info)
00177 {
00178 debug_message("[%d]: flavor=%d"
00179 ", refKind=%d"
00180 ", primType=%d"
00181 ", object_index=0x%x"
00182 ", length=%d"
00183 ", next=0x%x"
00184 "\n",
00185 info->index,
00186 info->flavor,
00187 info->refKind,
00188 info->primType,
00189 info->object_index,
00190 info->length,
00191 info->next);
00192 }
00193
00194
00195 static void
00196 dump_ref_list(RefIndex list)
00197 {
00198 RefInfo *info;
00199 RefIndex index;
00200
00201 debug_message("\nFOLLOW REFERENCES RETURNED:\n");
00202 index = list;
00203 while ( index != 0 ) {
00204 info = get_info(index);
00205 dump_ref_info(info);
00206 index = info->next;
00207 }
00208 }
00209
00210
00211 static void
00212 dump_field(FieldInfo *fields, jvalue *fvalues, int n_fields,
00213 jint index, jvalue value, jvmtiPrimitiveType primType)
00214 {
00215 ClassIndex cnum;
00216 StringIndex name;
00217 StringIndex sig;
00218
00219 cnum = fields[index].cnum;
00220 name = fields[index].name_index;
00221 sig = fields[index].sig_index;
00222 debug_message("[%d] %s \"%s\" \"%s\"",
00223 index,
00224 cnum!=0?string_get(class_get_signature(cnum)):"?",
00225 name!=0?string_get(name):"?",
00226 sig!=0?string_get(sig):"?");
00227 if ( fields[index].primType!=0 || fields[index].primType!=primType ) {
00228 debug_message(" (primType=%d(%c)",
00229 fields[index].primType,
00230 primTypeToSigChar(fields[index].primType));
00231 if ( primType != fields[index].primType ) {
00232 debug_message(", got %d(%c)",
00233 primType,
00234 primTypeToSigChar(primType));
00235 }
00236 debug_message(")");
00237 } else {
00238 debug_message("(ty=OBJ)");
00239 }
00240 if ( value.j != (jlong)0 || fvalues[index].j != (jlong)0 ) {
00241 debug_message(" val=[0x%08x,0x%08x] or [0x%08x,0x%08x]",
00242 jlong_high(value.j), jlong_low(value.j),
00243 jlong_high(fvalues[index].j), jlong_low(fvalues[index].j));
00244 }
00245 debug_message("\n");
00246 }
00247
00248
00249 static void
00250 dump_fields(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields)
00251 {
00252 int i;
00253
00254 debug_message("\nHPROF LIST OF ALL FIELDS:\n");
00255 for ( i = 0 ; i < n_fields ; i++ ) {
00256 if ( fields[i].name_index != 0 ) {
00257 dump_field(fields, fvalues, n_fields, i, fvalues[i], fields[i].primType);
00258 }
00259 }
00260 dump_ref_list(list);
00261 }
00262
00263
00264 static void
00265 verify_field(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields,
00266 jint index, jvalue value, jvmtiPrimitiveType primType)
00267 {
00268 HPROF_ASSERT(fvalues != NULL);
00269 HPROF_ASSERT(n_fields > 0);
00270 HPROF_ASSERT(index < n_fields);
00271 HPROF_ASSERT(index >= 0 );
00272 if ( primType!=fields[index].primType ) {
00273 dump_fields(list, fields, fvalues, n_fields);
00274 debug_message("\nPROBLEM WITH:\n");
00275 dump_field(fields, fvalues, n_fields, index, value, primType);
00276 debug_message("\n");
00277 HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
00278 }
00279 if ( primType == JVMTI_PRIMITIVE_TYPE_BOOLEAN &&
00280 ( value.b != 1 && value.b != 0 ) ) {
00281 dump_fields(list, fields, fvalues, n_fields);
00282 debug_message("\nPROBLEM WITH:\n");
00283 dump_field(fields, fvalues, n_fields, index, value, primType);
00284 debug_message("\n");
00285 HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
00286 }
00287 }
00288
00289
00290 static void
00291 fill_in_field_value(RefIndex list, FieldInfo *fields, jvalue *fvalues,
00292 int n_fields, jint index, jvalue value,
00293 jvmtiPrimitiveType primType)
00294 {
00295 HPROF_ASSERT(fvalues != NULL);
00296 HPROF_ASSERT(n_fields > 0);
00297 HPROF_ASSERT(index < n_fields);
00298 HPROF_ASSERT(index >= 0 );
00299 HPROF_ASSERT(fvalues[index].j==(jlong)0);
00300 verify_field(list, fields, fvalues, n_fields, index, value, primType);
00301 if (index >= 0 && index < n_fields) {
00302 fvalues[index] = value;
00303 }
00304 }
00305
00306
00307 static void
00308 dump_class_and_supers(JNIEnv *env, ObjectIndex object_index, RefIndex list)
00309 {
00310 SiteIndex site_index;
00311 SerialNumber trace_serial_num;
00312 RefIndex index;
00313 ClassIndex super_cnum;
00314 ObjectIndex super_index;
00315 LoaderIndex loader_index;
00316 ObjectIndex signers_index;
00317 ObjectIndex domain_index;
00318 FieldInfo *fields;
00319 jvalue *fvalues;
00320 jint n_fields;
00321 jboolean skip_fields;
00322 jint n_fields_set;
00323 jlong size;
00324 ClassIndex cnum;
00325 char *sig;
00326 ObjectKind kind;
00327 TraceIndex trace_index;
00328 Stack *cpool_values;
00329 ConstantPoolValue *cpool;
00330 jint cpool_count;
00331
00332 HPROF_ASSERT(object_index!=0);
00333 kind = object_get_kind(object_index);
00334 if ( kind != OBJECT_CLASS ) {
00335 return;
00336 }
00337 site_index = object_get_site(object_index);
00338 HPROF_ASSERT(site_index!=0);
00339 cnum = site_get_class_index(site_index);
00340 HPROF_ASSERT(cnum!=0);
00341 if ( class_get_status(cnum) & CLASS_DUMPED ) {
00342 return;
00343 }
00344 class_add_status(cnum, CLASS_DUMPED);
00345 size = (jlong)object_get_size(object_index);
00346
00347 super_index = 0;
00348 super_cnum = class_get_super(cnum);
00349 if ( super_cnum != 0 ) {
00350 super_index = class_get_object_index(super_cnum);
00351 if ( super_index != 0 ) {
00352 dump_class_and_supers(env, super_index,
00353 object_get_references(super_index));
00354 }
00355 }
00356
00357 trace_index = site_get_trace_index(site_index);
00358 HPROF_ASSERT(trace_index!=0);
00359 trace_serial_num = trace_get_serial_number(trace_index);
00360 sig = string_get(class_get_signature(cnum));
00361 loader_index = class_get_loader(cnum);
00362 signers_index = 0;
00363 domain_index = 0;
00364
00365
00366 n_fields = 0;
00367 skip_fields = JNI_FALSE;
00368 n_fields_set = 0;
00369 fields = NULL;
00370 fvalues = NULL;
00371 if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {
00372
00373 skip_fields = JNI_TRUE;
00374
00375 if ( list != 0 ) {
00376
00377
00378
00379 if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {
00380 dump_ref_list(list);
00381 debug_message("Unprepared class with references: %s\n",
00382 sig);
00383 }
00384 HPROF_ERROR(JNI_FALSE, "Trouble with unprepared classes");
00385 }
00386
00387 }
00388 if ( n_fields > 0 ) {
00389 fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
00390 (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
00391 }
00392
00393
00394 cpool_values = stack_init(16, 16, sizeof(ConstantPoolValue));
00395 cpool = NULL;
00396 cpool_count = 0;
00397
00398 index = list;
00399 while ( index != 0 ) {
00400 RefInfo *info;
00401 jvalue ovalue;
00402 static jvalue empty_value;
00403
00404 info = get_info(index);
00405
00406 switch ( info->flavor ) {
00407 case INFO_OBJECT_REF_DATA:
00408 switch ( info->refKind ) {
00409 case JVMTI_HEAP_REFERENCE_FIELD:
00410 case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
00411
00412 HPROF_ASSERT(0);
00413 break;
00414 case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
00415 if ( skip_fields == JNI_TRUE ) {
00416 break;
00417 }
00418 ovalue = empty_value;
00419 ovalue.i = info->object_index;
00420 fill_in_field_value(list, fields, fvalues, n_fields,
00421 info->index, ovalue, 0);
00422 n_fields_set++;
00423 HPROF_ASSERT(n_fields_set <= n_fields);
00424 break;
00425 case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: {
00426 ConstantPoolValue cpv;
00427 ObjectIndex cp_object_index;
00428 SiteIndex cp_site_index;
00429 ClassIndex cp_cnum;
00430
00431 cp_object_index = info->object_index;
00432 HPROF_ASSERT(cp_object_index!=0);
00433 cp_site_index = object_get_site(cp_object_index);
00434 HPROF_ASSERT(cp_site_index!=0);
00435 cp_cnum = site_get_class_index(cp_site_index);
00436 cpv.constant_pool_index = info->index;
00437 cpv.sig_index = class_get_signature(cp_cnum);
00438 cpv.value.i = cp_object_index;
00439 stack_push(cpool_values, (void*)&cpv);
00440 cpool_count++;
00441 break;
00442 }
00443 case JVMTI_HEAP_REFERENCE_SIGNERS:
00444 signers_index = info->object_index;
00445 break;
00446 case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
00447 domain_index = info->object_index;
00448 break;
00449 case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
00450 case JVMTI_HEAP_REFERENCE_INTERFACE:
00451 default:
00452
00453 break;
00454 }
00455 break;
00456 case INFO_PRIM_FIELD_DATA:
00457 if ( skip_fields == JNI_TRUE ) {
00458 break;
00459 }
00460 HPROF_ASSERT(info->primType!=0);
00461 HPROF_ASSERT(info->length==-1);
00462 HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_STATIC_FIELD);
00463 ovalue = get_key_value(index);
00464 fill_in_field_value(list, fields, fvalues, n_fields,
00465 info->index, ovalue, info->primType);
00466 n_fields_set++;
00467 HPROF_ASSERT(n_fields_set <= n_fields);
00468 break;
00469 case INFO_PRIM_ARRAY_DATA:
00470 default:
00471
00472 HPROF_ASSERT(0);
00473 break;
00474 }
00475
00476 index = info->next;
00477 }
00478
00479
00480 HPROF_ASSERT(cpool_count==stack_depth(cpool_values));
00481 if ( cpool_count > 0 ) {
00482 cpool = (ConstantPoolValue*)stack_element(cpool_values, 0);
00483 }
00484 io_heap_class_dump(cnum, sig, object_index, trace_serial_num,
00485 super_index,
00486 loader_object_index(env, loader_index),
00487 signers_index, domain_index,
00488 (jint)size, cpool_count, cpool, n_fields, fields, fvalues);
00489
00490 stack_term(cpool_values);
00491 if ( fvalues != NULL ) {
00492 HPROF_FREE(fvalues);
00493 }
00494 }
00495
00496
00497 static void
00498 dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)
00499 {
00500 jvmtiPrimitiveType primType;
00501 SiteIndex site_index;
00502 SerialNumber trace_serial_num;
00503 RefIndex index;
00504 ObjectIndex class_index;
00505 jlong size;
00506 ClassIndex cnum;
00507 char *sig;
00508 void *elements;
00509 jint num_elements;
00510 jint num_bytes;
00511 ObjectIndex *values;
00512 FieldInfo *fields;
00513 jvalue *fvalues;
00514 jint n_fields;
00515 jboolean skip_fields;
00516 jint n_fields_set;
00517 ObjectKind kind;
00518 TraceIndex trace_index;
00519 jboolean is_array;
00520 jboolean is_prim_array;
00521
00522 HPROF_ASSERT(object_index!=0);
00523 kind = object_get_kind(object_index);
00524 if ( kind == OBJECT_CLASS ) {
00525 return;
00526 }
00527 site_index = object_get_site(object_index);
00528 HPROF_ASSERT(site_index!=0);
00529 cnum = site_get_class_index(site_index);
00530 HPROF_ASSERT(cnum!=0);
00531 size = (jlong)object_get_size(object_index);
00532 trace_index = site_get_trace_index(site_index);
00533 HPROF_ASSERT(trace_index!=0);
00534 trace_serial_num = trace_get_serial_number(trace_index);
00535 sig = string_get(class_get_signature(cnum));
00536 class_index = class_get_object_index(cnum);
00537
00538 values = NULL;
00539 elements = NULL;
00540 num_elements = 0;
00541 num_bytes = 0;
00542
00543 n_fields = 0;
00544 skip_fields = JNI_FALSE;
00545 n_fields_set = 0;
00546 fields = NULL;
00547 fvalues = NULL;
00548
00549 index = list;
00550
00551 is_array = JNI_FALSE;
00552 is_prim_array = JNI_FALSE;
00553
00554 if ( sig[0] != JVM_SIGNATURE_ARRAY ) {
00555 if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {
00556
00557 skip_fields = JNI_TRUE;
00558
00559
00560
00561 if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {
00562 if ( list != 0 ) {
00563 dump_ref_list(list);
00564 debug_message("Instance of unprepared class with refs: %s\n",
00565 sig);
00566 } else {
00567 debug_message("Instance of unprepared class without refs: %s\n",
00568 sig);
00569 }
00570 HPROF_ERROR(JNI_FALSE, "Big Trouble with unprepared class instances");
00571 }
00572 }
00573 if ( n_fields > 0 ) {
00574 fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
00575 (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
00576 }
00577 } else {
00578 is_array = JNI_TRUE;
00579 if ( sig[0] != 0 && sigToPrimSize(sig+1) != 0 ) {
00580 is_prim_array = JNI_TRUE;
00581 }
00582 }
00583
00584 while ( index != 0 ) {
00585 RefInfo *info;
00586 jvalue ovalue;
00587 static jvalue empty_value;
00588
00589 info = get_info(index);
00590
00591
00592 switch ( info->flavor ) {
00593 case INFO_OBJECT_REF_DATA:
00594 switch ( info->refKind ) {
00595 case JVMTI_HEAP_REFERENCE_SIGNERS:
00596 case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
00597 case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
00598 case JVMTI_HEAP_REFERENCE_INTERFACE:
00599 case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
00600 case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:
00601
00602 HPROF_ASSERT(0);
00603 break;
00604 case JVMTI_HEAP_REFERENCE_FIELD:
00605 if ( skip_fields == JNI_TRUE ) {
00606 break;
00607 }
00608 HPROF_ASSERT(is_array!=JNI_TRUE);
00609 ovalue = empty_value;
00610 ovalue.i = info->object_index;
00611 fill_in_field_value(list, fields, fvalues, n_fields,
00612 info->index, ovalue, 0);
00613 n_fields_set++;
00614 HPROF_ASSERT(n_fields_set <= n_fields);
00615 break;
00616 case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
00617
00618 HPROF_ASSERT(is_array==JNI_TRUE);
00619 HPROF_ASSERT(is_prim_array!=JNI_TRUE);
00620 if ( num_elements <= info->index ) {
00621 int nbytes;
00622
00623 if ( values == NULL ) {
00624 num_elements = info->index + 1;
00625 nbytes = num_elements*(int)sizeof(ObjectIndex);
00626 values = (ObjectIndex*)HPROF_MALLOC(nbytes);
00627 (void)memset(values, 0, nbytes);
00628 } else {
00629 void *new_values;
00630 int new_size;
00631 int obytes;
00632
00633 obytes = num_elements*(int)sizeof(ObjectIndex);
00634 new_size = info->index + 1;
00635 nbytes = new_size*(int)sizeof(ObjectIndex);
00636 new_values = (void*)HPROF_MALLOC(nbytes);
00637 (void)memcpy(new_values, values, obytes);
00638 (void)memset(((char*)new_values)+obytes, 0,
00639 nbytes-obytes);
00640 HPROF_FREE(values);
00641 num_elements = new_size;
00642 values = new_values;
00643 }
00644 }
00645 HPROF_ASSERT(values[info->index]==0);
00646 values[info->index] = info->object_index;
00647 break;
00648 default:
00649
00650 break;
00651 }
00652 break;
00653 case INFO_PRIM_FIELD_DATA:
00654 if ( skip_fields == JNI_TRUE ) {
00655 break;
00656 }
00657 HPROF_ASSERT(info->primType!=0);
00658 HPROF_ASSERT(info->length==-1);
00659 HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_FIELD);
00660 HPROF_ASSERT(is_array!=JNI_TRUE);
00661 ovalue = get_key_value(index);
00662 fill_in_field_value(list, fields, fvalues, n_fields,
00663 info->index, ovalue, info->primType);
00664 n_fields_set++;
00665 HPROF_ASSERT(n_fields_set <= n_fields);
00666 break;
00667 case INFO_PRIM_ARRAY_DATA:
00668
00669 HPROF_ASSERT(info->refKind==0);
00670
00671 HPROF_ASSERT(index==list&&info->next==0);
00672 HPROF_ASSERT(is_array==JNI_TRUE);
00673 HPROF_ASSERT(is_prim_array==JNI_TRUE);
00674 primType = info->primType;
00675 elements = get_key_elements(index, primType,
00676 &num_elements, &num_bytes);
00677 HPROF_ASSERT(info->length==num_elements);
00678 size = num_bytes;
00679 break;
00680 default:
00681 HPROF_ASSERT(0);
00682 break;
00683 }
00684 index = info->next;
00685 }
00686
00687 if ( is_array == JNI_TRUE ) {
00688 if ( is_prim_array == JNI_TRUE ) {
00689 HPROF_ASSERT(values==NULL);
00690 io_heap_prim_array(object_index, trace_serial_num,
00691 (jint)size, num_elements, sig, elements);
00692 } else {
00693 HPROF_ASSERT(elements==NULL);
00694 io_heap_object_array(object_index, trace_serial_num,
00695 (jint)size, num_elements, sig, values, class_index);
00696 }
00697 } else {
00698 io_heap_instance_dump(cnum, object_index, trace_serial_num,
00699 class_index, (jint)size, sig, fields, fvalues, n_fields);
00700 }
00701 if ( values != NULL ) {
00702 HPROF_FREE(values);
00703 }
00704 if ( fvalues != NULL ) {
00705 HPROF_FREE(fvalues);
00706 }
00707 if ( elements != NULL ) {
00708
00709 }
00710 }
00711
00712
00713
00714 void
00715 reference_init(void)
00716 {
00717 HPROF_ASSERT(gdata->reference_table==NULL);
00718 gdata->reference_table = table_initialize("Ref", 2048, 4096, 0,
00719 (int)sizeof(RefInfo));
00720 }
00721
00722
00723 RefIndex
00724 reference_obj(RefIndex next, jvmtiHeapReferenceKind refKind,
00725 ObjectIndex object_index, jint index, jint length)
00726 {
00727 static RefInfo empty_info;
00728 RefIndex entry;
00729 RefInfo info;
00730
00731 info = empty_info;
00732 info.flavor = INFO_OBJECT_REF_DATA;
00733 info.refKind = refKind;
00734 info.object_index = object_index;
00735 info.index = index;
00736 info.length = length;
00737 info.next = next;
00738 entry = table_create_entry(gdata->reference_table, NULL, 0, (void*)&info);
00739 return entry;
00740 }
00741
00742
00743 RefIndex
00744 reference_prim_field(RefIndex next, jvmtiHeapReferenceKind refKind,
00745 jvmtiPrimitiveType primType, jvalue field_value, jint field_index)
00746 {
00747 static RefInfo empty_info;
00748 RefIndex entry;
00749 RefInfo info;
00750
00751 HPROF_ASSERT(primType==JVMTI_PRIMITIVE_TYPE_BOOLEAN?(field_value.b==1||field_value.b==0):1);
00752
00753 info = empty_info;
00754 info.flavor = INFO_PRIM_FIELD_DATA;
00755 info.refKind = refKind;
00756 info.primType = primType;
00757 info.index = field_index;
00758 info.length = -1;
00759 info.next = next;
00760 entry = table_create_entry(gdata->reference_table,
00761 (void*)&field_value, (int)sizeof(jvalue), (void*)&info);
00762 return entry;
00763 }
00764
00765
00766 RefIndex
00767 reference_prim_array(RefIndex next, jvmtiPrimitiveType primType,
00768 const void *elements, jint elementCount)
00769 {
00770 static RefInfo empty_info;
00771 RefIndex entry;
00772 RefInfo info;
00773
00774 HPROF_ASSERT(next == 0);
00775 HPROF_ASSERT(elementCount >= 0);
00776 HPROF_ASSERT(elements != NULL);
00777
00778 info = empty_info;
00779 info.flavor = INFO_PRIM_ARRAY_DATA;
00780 info.refKind = 0;
00781 info.primType = primType;
00782 info.index = 0;
00783 info.length = elementCount;
00784 info.next = next;
00785 entry = table_create_entry(gdata->reference_table, (void*)elements,
00786 elementCount * get_prim_size(primType), (void*)&info);
00787 return entry;
00788 }
00789
00790 void
00791 reference_cleanup(void)
00792 {
00793 if ( gdata->reference_table == NULL ) {
00794 return;
00795 }
00796 table_cleanup(gdata->reference_table, NULL, NULL);
00797 gdata->reference_table = NULL;
00798 }
00799
00800 void
00801 reference_dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)
00802 {
00803 dump_instance(env, object_index, list);
00804 }
00805
00806 void
00807 reference_dump_class(JNIEnv *env, ObjectIndex object_index, RefIndex list)
00808 {
00809 dump_class_and_supers(env, object_index, list);
00810 }
00811