Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/jvmti/hprof/hprof_reference.c
38829 views
/*1* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6*7* - Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its15* contributors may be used to endorse or promote products derived16* from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS19* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,20* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR21* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR22* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,23* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,24* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR25* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF26* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING27* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS28* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* This source code is provided to illustrate the usage of a given feature33* or technique and has been deliberately simplified. Additional steps34* required for a production-quality application, such as security checks,35* input validation and proper error handling, might not be present in36* this sample code.37*/383940/* Object references table (used in hprof_object.c). */4142/*43* This table is used by the object table to store object reference44* and primitive data information obtained from iterations over the45* heap (see hprof_site.c).46*47* Most of these table entries have no Key, but the key is used to store48* the primitive array and primitive field jvalue. None of these entries49* are ever looked up, there will be no hash table, use of the50* LookupTable was just an easy way to handle a unbounded table of51* entries. The object table (see hprof_object.c) will completely52* free this reference table after each heap dump or after processing the53* references and primitive data.54*55* The hprof format required this accumulation of all heap iteration56* references and primitive data from objects in order to compose an57* hprof records for it.58*59* This file contains detailed understandings of how an hprof CLASS60* and INSTANCE dump is constructed, most of this is derived from the61* original hprof code, but some has been derived by reading the HAT62* code that accepts this format.63*64*/6566#include "hprof.h"6768/* The flavor of data being saved in the RefInfo */69enum {70INFO_OBJECT_REF_DATA = 1,71INFO_PRIM_FIELD_DATA = 2,72INFO_PRIM_ARRAY_DATA = 373};7475/* Reference information, object reference or primitive data information */76typedef struct RefInfo {77ObjectIndex object_index; /* If an object reference, the referree index */78jint index; /* If array or field, array or field index */79jint length; /* If array the element count, if not -1 */80RefIndex next; /* The next table element */81unsigned flavor : 8; /* INFO_*, flavor of RefInfo */82unsigned refKind : 8; /* The kind of reference */83unsigned primType : 8; /* If primitive data involved, it's type */84} RefInfo;8586/* Private internal functions. */8788/* Get the RefInfo structure from an entry */89static RefInfo *90get_info(RefIndex index)91{92RefInfo *info;9394info = (RefInfo*)table_get_info(gdata->reference_table, index);95return info;96}9798/* Get a jvalue that was stored as the key. */99static jvalue100get_key_value(RefIndex index)101{102void *key;103int len;104jvalue value;105static jvalue empty_value;106107key = NULL;108table_get_key(gdata->reference_table, index, &key, &len);109HPROF_ASSERT(key!=NULL);110HPROF_ASSERT(len==(int)sizeof(jvalue));111if ( key != NULL ) {112(void)memcpy(&value, key, (int)sizeof(jvalue));113} else {114value = empty_value;115}116return value;117}118119/* Get size of a primitive type */120static jint121get_prim_size(jvmtiPrimitiveType primType)122{123jint size;124125switch ( primType ) {126case JVMTI_PRIMITIVE_TYPE_BOOLEAN:127size = (jint)sizeof(jboolean);128break;129case JVMTI_PRIMITIVE_TYPE_BYTE:130size = (jint)sizeof(jbyte);131break;132case JVMTI_PRIMITIVE_TYPE_CHAR:133size = (jint)sizeof(jchar);134break;135case JVMTI_PRIMITIVE_TYPE_SHORT:136size = (jint)sizeof(jshort);137break;138case JVMTI_PRIMITIVE_TYPE_INT:139size = (jint)sizeof(jint);140break;141case JVMTI_PRIMITIVE_TYPE_FLOAT:142size = (jint)sizeof(jfloat);143break;144case JVMTI_PRIMITIVE_TYPE_LONG:145size = (jint)sizeof(jlong);146break;147case JVMTI_PRIMITIVE_TYPE_DOUBLE:148size = (jint)sizeof(jdouble);149break;150default:151HPROF_ASSERT(0);152size = 1;153break;154}155return size;156}157158/* Get a void* elements array that was stored as the key. */159static void *160get_key_elements(RefIndex index, jvmtiPrimitiveType primType,161jint *nelements, jint *nbytes)162{163void *key;164jint byteLen;165166HPROF_ASSERT(nelements!=NULL);167HPROF_ASSERT(nbytes!=NULL);168169table_get_key(gdata->reference_table, index, &key, &byteLen);170HPROF_ASSERT(byteLen>=0);171HPROF_ASSERT(byteLen!=0?key!=NULL:key==NULL);172*nbytes = byteLen;173*nelements = byteLen / get_prim_size(primType);174return key;175}176177/* Dump a RefInfo* structure */178static void179dump_ref_info(RefInfo *info)180{181debug_message("[%d]: flavor=%d"182", refKind=%d"183", primType=%d"184", object_index=0x%x"185", length=%d"186", next=0x%x"187"\n",188info->index,189info->flavor,190info->refKind,191info->primType,192info->object_index,193info->length,194info->next);195}196197/* Dump a RefIndex list */198static void199dump_ref_list(RefIndex list)200{201RefInfo *info;202RefIndex index;203204debug_message("\nFOLLOW REFERENCES RETURNED:\n");205index = list;206while ( index != 0 ) {207info = get_info(index);208dump_ref_info(info);209index = info->next;210}211}212213/* Dump information about a field and what ref data we had on it */214static void215dump_field(FieldInfo *fields, jvalue *fvalues, int n_fields,216jint index, jvalue value, jvmtiPrimitiveType primType)217{218ClassIndex cnum;219StringIndex name;220StringIndex sig;221222cnum = fields[index].cnum;223name = fields[index].name_index;224sig = fields[index].sig_index;225debug_message("[%d] %s \"%s\" \"%s\"",226index,227cnum!=0?string_get(class_get_signature(cnum)):"?",228name!=0?string_get(name):"?",229sig!=0?string_get(sig):"?");230if ( fields[index].primType!=0 || fields[index].primType!=primType ) {231debug_message(" (primType=%d(%c)",232fields[index].primType,233primTypeToSigChar(fields[index].primType));234if ( primType != fields[index].primType ) {235debug_message(", got %d(%c)",236primType,237primTypeToSigChar(primType));238}239debug_message(")");240} else {241debug_message("(ty=OBJ)");242}243if ( value.j != (jlong)0 || fvalues[index].j != (jlong)0 ) {244debug_message(" val=[0x%08x,0x%08x] or [0x%08x,0x%08x]",245jlong_high(value.j), jlong_low(value.j),246jlong_high(fvalues[index].j), jlong_low(fvalues[index].j));247}248debug_message("\n");249}250251/* Dump all the fields of interest */252static void253dump_fields(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields)254{255int i;256257debug_message("\nHPROF LIST OF ALL FIELDS:\n");258for ( i = 0 ; i < n_fields ; i++ ) {259if ( fields[i].name_index != 0 ) {260dump_field(fields, fvalues, n_fields, i, fvalues[i], fields[i].primType);261}262}263dump_ref_list(list);264}265266/* Verify field data */267static void268verify_field(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields,269jint index, jvalue value, jvmtiPrimitiveType primType)270{271HPROF_ASSERT(fvalues != NULL);272HPROF_ASSERT(n_fields > 0);273HPROF_ASSERT(index < n_fields);274HPROF_ASSERT(index >= 0 );275if ( primType!=fields[index].primType ) {276dump_fields(list, fields, fvalues, n_fields);277debug_message("\nPROBLEM WITH:\n");278dump_field(fields, fvalues, n_fields, index, value, primType);279debug_message("\n");280HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");281}282if ( primType == JVMTI_PRIMITIVE_TYPE_BOOLEAN &&283( value.b != 1 && value.b != 0 ) ) {284dump_fields(list, fields, fvalues, n_fields);285debug_message("\nPROBLEM WITH:\n");286dump_field(fields, fvalues, n_fields, index, value, primType);287debug_message("\n");288HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");289}290}291292/* Fill in a field value, making sure the index is safe */293static void294fill_in_field_value(RefIndex list, FieldInfo *fields, jvalue *fvalues,295int n_fields, jint index, jvalue value,296jvmtiPrimitiveType primType)297{298HPROF_ASSERT(fvalues != NULL);299HPROF_ASSERT(n_fields > 0);300HPROF_ASSERT(index < n_fields);301HPROF_ASSERT(index >= 0 );302HPROF_ASSERT(fvalues[index].j==(jlong)0);303verify_field(list, fields, fvalues, n_fields, index, value, primType);304if (index >= 0 && index < n_fields) {305fvalues[index] = value;306}307}308309/* Walk all references for an ObjectIndex and construct the hprof CLASS dump. */310static void311dump_class_and_supers(JNIEnv *env, ObjectIndex object_index, RefIndex list)312{313SiteIndex site_index;314SerialNumber trace_serial_num;315RefIndex index;316ClassIndex super_cnum;317ObjectIndex super_index;318LoaderIndex loader_index;319ObjectIndex signers_index;320ObjectIndex domain_index;321FieldInfo *fields;322jvalue *fvalues;323jint n_fields;324jboolean skip_fields;325jint n_fields_set;326jlong size;327ClassIndex cnum;328char *sig;329ObjectKind kind;330TraceIndex trace_index;331Stack *cpool_values;332ConstantPoolValue *cpool;333jint cpool_count;334335HPROF_ASSERT(object_index!=0);336kind = object_get_kind(object_index);337if ( kind != OBJECT_CLASS ) {338return;339}340site_index = object_get_site(object_index);341HPROF_ASSERT(site_index!=0);342cnum = site_get_class_index(site_index);343HPROF_ASSERT(cnum!=0);344if ( class_get_status(cnum) & CLASS_DUMPED ) {345return;346}347class_add_status(cnum, CLASS_DUMPED);348size = (jlong)object_get_size(object_index);349350super_index = 0;351super_cnum = class_get_super(cnum);352if ( super_cnum != 0 ) {353super_index = class_get_object_index(super_cnum);354if ( super_index != 0 ) {355dump_class_and_supers(env, super_index,356object_get_references(super_index));357}358}359360trace_index = site_get_trace_index(site_index);361HPROF_ASSERT(trace_index!=0);362trace_serial_num = trace_get_serial_number(trace_index);363sig = string_get(class_get_signature(cnum));364loader_index = class_get_loader(cnum);365signers_index = 0;366domain_index = 0;367368/* Get field information */369n_fields = 0;370skip_fields = JNI_FALSE;371n_fields_set = 0;372fields = NULL;373fvalues = NULL;374if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {375/* Problems getting all the fields, can't trust field index values */376skip_fields = JNI_TRUE;377/* Class with no references at all? (ok to be unprepared if list==0?) */378if ( list != 0 ) {379/* It is assumed that the reason why we didn't get the fields380* was because the class is not prepared.381*/382if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {383dump_ref_list(list);384debug_message("Unprepared class with references: %s\n",385sig);386}387HPROF_ERROR(JNI_FALSE, "Trouble with unprepared classes");388}389/* Why would an unprepared class contain references? */390}391if ( n_fields > 0 ) {392fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));393(void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));394}395396/* We use a Stack just because it will automatically expand as needed */397cpool_values = stack_init(16, 16, sizeof(ConstantPoolValue));398cpool = NULL;399cpool_count = 0;400401index = list;402while ( index != 0 ) {403RefInfo *info;404jvalue ovalue;405static jvalue empty_value;406407info = get_info(index);408409switch ( info->flavor ) {410case INFO_OBJECT_REF_DATA:411switch ( info->refKind ) {412case JVMTI_HEAP_REFERENCE_FIELD:413case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:414/* Should never be seen on a class dump */415HPROF_ASSERT(0);416break;417case JVMTI_HEAP_REFERENCE_STATIC_FIELD:418if ( skip_fields == JNI_TRUE ) {419break;420}421ovalue = empty_value;422ovalue.i = info->object_index;423fill_in_field_value(list, fields, fvalues, n_fields,424info->index, ovalue, 0);425n_fields_set++;426HPROF_ASSERT(n_fields_set <= n_fields);427break;428case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: {429ConstantPoolValue cpv;430ObjectIndex cp_object_index;431SiteIndex cp_site_index;432ClassIndex cp_cnum;433434cp_object_index = info->object_index;435HPROF_ASSERT(cp_object_index!=0);436cp_site_index = object_get_site(cp_object_index);437HPROF_ASSERT(cp_site_index!=0);438cp_cnum = site_get_class_index(cp_site_index);439cpv.constant_pool_index = info->index;440cpv.sig_index = class_get_signature(cp_cnum);441cpv.value.i = cp_object_index;442stack_push(cpool_values, (void*)&cpv);443cpool_count++;444break;445}446case JVMTI_HEAP_REFERENCE_SIGNERS:447signers_index = info->object_index;448break;449case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:450domain_index = info->object_index;451break;452case JVMTI_HEAP_REFERENCE_CLASS_LOADER:453case JVMTI_HEAP_REFERENCE_INTERFACE:454default:455/* Ignore, not needed */456break;457}458break;459case INFO_PRIM_FIELD_DATA:460if ( skip_fields == JNI_TRUE ) {461break;462}463HPROF_ASSERT(info->primType!=0);464HPROF_ASSERT(info->length==-1);465HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_STATIC_FIELD);466ovalue = get_key_value(index);467fill_in_field_value(list, fields, fvalues, n_fields,468info->index, ovalue, info->primType);469n_fields_set++;470HPROF_ASSERT(n_fields_set <= n_fields);471break;472case INFO_PRIM_ARRAY_DATA:473default:474/* Should never see these */475HPROF_ASSERT(0);476break;477}478479index = info->next;480}481482/* Get constant pool data if we have any */483HPROF_ASSERT(cpool_count==stack_depth(cpool_values));484if ( cpool_count > 0 ) {485cpool = (ConstantPoolValue*)stack_element(cpool_values, 0);486}487io_heap_class_dump(cnum, sig, object_index, trace_serial_num,488super_index,489loader_object_index(env, loader_index),490signers_index, domain_index,491(jint)size, cpool_count, cpool, n_fields, fields, fvalues);492493stack_term(cpool_values);494if ( fvalues != NULL ) {495HPROF_FREE(fvalues);496}497}498499/* Walk all references for an ObjectIndex and construct the hprof INST dump. */500static void501dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)502{503jvmtiPrimitiveType primType;504SiteIndex site_index;505SerialNumber trace_serial_num;506RefIndex index;507ObjectIndex class_index;508jlong size;509ClassIndex cnum;510char *sig;511void *elements;512jint num_elements;513jint num_bytes;514ObjectIndex *values;515FieldInfo *fields;516jvalue *fvalues;517jint n_fields;518jboolean skip_fields;519jint n_fields_set;520ObjectKind kind;521TraceIndex trace_index;522jboolean is_array;523jboolean is_prim_array;524525HPROF_ASSERT(object_index!=0);526kind = object_get_kind(object_index);527if ( kind == OBJECT_CLASS ) {528return;529}530site_index = object_get_site(object_index);531HPROF_ASSERT(site_index!=0);532cnum = site_get_class_index(site_index);533HPROF_ASSERT(cnum!=0);534size = (jlong)object_get_size(object_index);535trace_index = site_get_trace_index(site_index);536HPROF_ASSERT(trace_index!=0);537trace_serial_num = trace_get_serial_number(trace_index);538sig = string_get(class_get_signature(cnum));539class_index = class_get_object_index(cnum);540541values = NULL;542elements = NULL;543num_elements = 0;544num_bytes = 0;545546n_fields = 0;547skip_fields = JNI_FALSE;548n_fields_set = 0;549fields = NULL;550fvalues = NULL;551552index = list;553554is_array = JNI_FALSE;555is_prim_array = JNI_FALSE;556557if ( sig[0] != JVM_SIGNATURE_ARRAY ) {558if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {559/* Trouble getting all the fields, can't trust field index values */560skip_fields = JNI_TRUE;561/* It is assumed that the reason why we didn't get the fields562* was because the class is not prepared.563*/564if ( gdata->debugflags & DEBUGFLAG_UNPREPARED_CLASSES ) {565if ( list != 0 ) {566dump_ref_list(list);567debug_message("Instance of unprepared class with refs: %s\n",568sig);569} else {570debug_message("Instance of unprepared class without refs: %s\n",571sig);572}573HPROF_ERROR(JNI_FALSE, "Big Trouble with unprepared class instances");574}575}576if ( n_fields > 0 ) {577fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));578(void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));579}580} else {581is_array = JNI_TRUE;582if ( sig[0] != 0 && sigToPrimSize(sig+1) != 0 ) {583is_prim_array = JNI_TRUE;584}585}586587while ( index != 0 ) {588RefInfo *info;589jvalue ovalue;590static jvalue empty_value;591592info = get_info(index);593594/* Process reference objects, many not used right now. */595switch ( info->flavor ) {596case INFO_OBJECT_REF_DATA:597switch ( info->refKind ) {598case JVMTI_HEAP_REFERENCE_SIGNERS:599case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:600case JVMTI_HEAP_REFERENCE_CLASS_LOADER:601case JVMTI_HEAP_REFERENCE_INTERFACE:602case JVMTI_HEAP_REFERENCE_STATIC_FIELD:603case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:604/* Should never be seen on an instance dump */605HPROF_ASSERT(0);606break;607case JVMTI_HEAP_REFERENCE_FIELD:608if ( skip_fields == JNI_TRUE ) {609break;610}611HPROF_ASSERT(is_array!=JNI_TRUE);612ovalue = empty_value;613ovalue.i = info->object_index;614fill_in_field_value(list, fields, fvalues, n_fields,615info->index, ovalue, 0);616n_fields_set++;617HPROF_ASSERT(n_fields_set <= n_fields);618break;619case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:620/* We get each object element one at a time. */621HPROF_ASSERT(is_array==JNI_TRUE);622HPROF_ASSERT(is_prim_array!=JNI_TRUE);623if ( num_elements <= info->index ) {624int nbytes;625626if ( values == NULL ) {627num_elements = info->index + 1;628nbytes = num_elements*(int)sizeof(ObjectIndex);629values = (ObjectIndex*)HPROF_MALLOC(nbytes);630(void)memset(values, 0, nbytes);631} else {632void *new_values;633int new_size;634int obytes;635636obytes = num_elements*(int)sizeof(ObjectIndex);637new_size = info->index + 1;638nbytes = new_size*(int)sizeof(ObjectIndex);639new_values = (void*)HPROF_MALLOC(nbytes);640(void)memcpy(new_values, values, obytes);641(void)memset(((char*)new_values)+obytes, 0,642nbytes-obytes);643HPROF_FREE(values);644num_elements = new_size;645values = new_values;646}647}648HPROF_ASSERT(values[info->index]==0);649values[info->index] = info->object_index;650break;651default:652/* Ignore, not needed */653break;654}655break;656case INFO_PRIM_FIELD_DATA:657if ( skip_fields == JNI_TRUE ) {658break;659}660HPROF_ASSERT(info->primType!=0);661HPROF_ASSERT(info->length==-1);662HPROF_ASSERT(info->refKind==JVMTI_HEAP_REFERENCE_FIELD);663HPROF_ASSERT(is_array!=JNI_TRUE);664ovalue = get_key_value(index);665fill_in_field_value(list, fields, fvalues, n_fields,666info->index, ovalue, info->primType);667n_fields_set++;668HPROF_ASSERT(n_fields_set <= n_fields);669break;670case INFO_PRIM_ARRAY_DATA:671/* Should only be one, and it's handled below */672HPROF_ASSERT(info->refKind==0);673/* We assert that nothing else was saved with this array */674HPROF_ASSERT(index==list&&info->next==0);675HPROF_ASSERT(is_array==JNI_TRUE);676HPROF_ASSERT(is_prim_array==JNI_TRUE);677primType = info->primType;678elements = get_key_elements(index, primType,679&num_elements, &num_bytes);680HPROF_ASSERT(info->length==num_elements);681size = num_bytes;682break;683default:684HPROF_ASSERT(0);685break;686}687index = info->next;688}689690if ( is_array == JNI_TRUE ) {691if ( is_prim_array == JNI_TRUE ) {692HPROF_ASSERT(values==NULL);693io_heap_prim_array(object_index, trace_serial_num,694(jint)size, num_elements, sig, elements);695} else {696HPROF_ASSERT(elements==NULL);697io_heap_object_array(object_index, trace_serial_num,698(jint)size, num_elements, sig, values, class_index);699}700} else {701io_heap_instance_dump(cnum, object_index, trace_serial_num,702class_index, (jint)size, sig, fields, fvalues, n_fields);703}704if ( values != NULL ) {705HPROF_FREE(values);706}707if ( fvalues != NULL ) {708HPROF_FREE(fvalues);709}710if ( elements != NULL ) {711/* Do NOT free elements, it's a key in the table, leave it be */712}713}714715/* External interfaces. */716717void718reference_init(void)719{720HPROF_ASSERT(gdata->reference_table==NULL);721gdata->reference_table = table_initialize("Ref", 2048, 4096, 0,722(int)sizeof(RefInfo));723}724725/* Save away a reference to an object */726RefIndex727reference_obj(RefIndex next, jvmtiHeapReferenceKind refKind,728ObjectIndex object_index, jint index, jint length)729{730static RefInfo empty_info;731RefIndex entry;732RefInfo info;733734info = empty_info;735info.flavor = INFO_OBJECT_REF_DATA;736info.refKind = refKind;737info.object_index = object_index;738info.index = index;739info.length = length;740info.next = next;741entry = table_create_entry(gdata->reference_table, NULL, 0, (void*)&info);742return entry;743}744745/* Save away some primitive field data */746RefIndex747reference_prim_field(RefIndex next, jvmtiHeapReferenceKind refKind,748jvmtiPrimitiveType primType, jvalue field_value, jint field_index)749{750static RefInfo empty_info;751RefIndex entry;752RefInfo info;753754HPROF_ASSERT(primType==JVMTI_PRIMITIVE_TYPE_BOOLEAN?(field_value.b==1||field_value.b==0):1);755756info = empty_info;757info.flavor = INFO_PRIM_FIELD_DATA;758info.refKind = refKind;759info.primType = primType;760info.index = field_index;761info.length = -1;762info.next = next;763entry = table_create_entry(gdata->reference_table,764(void*)&field_value, (int)sizeof(jvalue), (void*)&info);765return entry;766}767768/* Save away some primitive array data */769RefIndex770reference_prim_array(RefIndex next, jvmtiPrimitiveType primType,771const void *elements, jint elementCount)772{773static RefInfo empty_info;774RefIndex entry;775RefInfo info;776777HPROF_ASSERT(next == 0);778HPROF_ASSERT(elementCount >= 0);779HPROF_ASSERT(elements != NULL);780781info = empty_info;782info.flavor = INFO_PRIM_ARRAY_DATA;783info.refKind = 0;784info.primType = primType;785info.index = 0;786info.length = elementCount;787info.next = next;788entry = table_create_entry(gdata->reference_table, (void*)elements,789elementCount * get_prim_size(primType), (void*)&info);790return entry;791}792793void794reference_cleanup(void)795{796if ( gdata->reference_table == NULL ) {797return;798}799table_cleanup(gdata->reference_table, NULL, NULL);800gdata->reference_table = NULL;801}802803void804reference_dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)805{806dump_instance(env, object_index, list);807}808809void810reference_dump_class(JNIEnv *env, ObjectIndex object_index, RefIndex list)811{812dump_class_and_supers(env, object_index, list);813}814815816