/*
 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Object references table (used in hprof_object.c). */

/*
 * This table is used by the object table to store object reference
 *   and primitive data information obtained from iterations over the
 *   heap (see hprof_site.c).
 *
 * Most of these table entries have no Key, but the key is used to store
 *   the primitive array and primitive field jvalue. None of these entries
 *   are ever looked up, there will be no hash table, use of the
 *   LookupTable was just an easy way to handle a unbounded table of
 *   entries. The object table (see hprof_object.c) will completely
 *   free this reference table after each heap dump or after processing the
 *   references and primitive data.
 *
 * The hprof format required this accumulation of all heap iteration
 *   references and primitive data from objects in order to compose an
 *   hprof records for it.
 *
 * This file contains detailed understandings of how an hprof CLASS
 *   and INSTANCE dump is constructed, most of this is derived from the
 *   original hprof code, but some has been derived by reading the HAT
 *   code that accepts this format.
 *
 */

#include "hprof.h"

/* The flavor of data being saved in the RefInfo */
enum {
    INFO_OBJECT_REF_DATA    = 1,
    INFO_PRIM_FIELD_DATA    = 2,
    INFO_PRIM_ARRAY_DATA    = 3
};

/* Reference information, object reference or primitive data information */
typedef struct RefInfo {
    ObjectIndex object_index; /* If an object reference, the referree index */
    jint        index;        /* If array or field, array or field index */
    jint        length;       /* If array the element count, if not -1 */
    RefIndex    next;         /* The next table element */
    unsigned    flavor   : 8; /* INFO_*, flavor of RefInfo */
    unsigned    refKind  : 8; /* The kind of reference */
    unsigned    primType : 8; /* If primitive data involved, it's type */
} RefInfo;

/* Private internal functions. */

/* Get the RefInfo structure from an entry */
static RefInfo *
get_info(RefIndex index)
{
    RefInfo *info;

    info = (RefInfo*)table_get_info(gdata->reference_table, index);
    return info;
}

/* Get a jvalue that was stored as the key. */
static jvalue
get_key_value(RefIndex index)
{
    void  *key;
    int    len;
    jvalue value;
    static jvalue empty_value;

    key = NULL;
    table_get_key(gdata->reference_table, index, &key, &len);
    HPROF_ASSERT(key!=NULL);
    HPROF_ASSERT(len==(int)sizeof(jvalue));
    if ( key != NULL ) {
        (void)memcpy(&value, key, (int)sizeof(jvalue));
    } else {
        value = empty_value;
    }
    return value;
}

/* Get size of a primitive type */
static jint
get_prim_size(jvmtiPrimitiveType primType)
{
    jint size;

    switch ( primType ) {
        case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
            size = (jint)sizeof(jboolean);
            break;
        case JVMTI_PRIMITIVE_TYPE_BYTE:
            size = (jint)sizeof(jbyte);
            break;
        case JVMTI_PRIMITIVE_TYPE_CHAR:
            size = (jint)sizeof(jchar);
            break;
        case JVMTI_PRIMITIVE_TYPE_SHORT:
            size = (jint)sizeof(jshort);
            break;
        case JVMTI_PRIMITIVE_TYPE_INT:
            size = (jint)sizeof(jint);
            break;
        case JVMTI_PRIMITIVE_TYPE_FLOAT:
            size = (jint)sizeof(jfloat);
            break;
        case JVMTI_PRIMITIVE_TYPE_LONG:
            size = (jint)sizeof(jlong);
            break;
        case JVMTI_PRIMITIVE_TYPE_DOUBLE:
            size = (jint)sizeof(jdouble);
            break;
        default:
            HPROF_ASSERT(0);
            size = 1;
            break;
    }
    return size;
}

/* Get a void* elements array that was stored as the key. */
static void *
get_key_elements(RefIndex index, jvmtiPrimitiveType primType,
                 jint *nelements, jint *nbytes)
{
    void  *key;
    jint   byteLen;

    HPROF_ASSERT(nelements!=NULL);
    HPROF_ASSERT(nbytes!=NULL);

    table_get_key(gdata->reference_table, index, &key, &byteLen);
    HPROF_ASSERT(byteLen>=0);
    HPROF_ASSERT(byteLen!=0?key!=NULL:key==NULL);
    *nbytes      = byteLen;
    *nelements   = byteLen / get_prim_size(primType);
    return key;
}

/* Dump a RefInfo* structure */
static void
dump_ref_info(RefInfo *info)
{
    debug_message("[%d]: flavor=%d"
                          ", refKind=%d"
                          ", primType=%d"
                          ", object_index=0x%x"
                          ", length=%d"
                          ", next=0x%x"
                          "\n",
            info->index,
            info->flavor,
            info->refKind,
            info->primType,
            info->object_index,
            info->length,
            info->next);
}

/* Dump a RefIndex list */
static void
dump_ref_list(RefIndex list)
{
    RefInfo *info;
    RefIndex index;

    debug_message("\nFOLLOW REFERENCES RETURNED:\n");
    index = list;
    while ( index != 0 ) {
        info = get_info(index);
        dump_ref_info(info);
        index = info->next;
    }
}

/* Dump information about a field and what ref data we had on it */
static void
dump_field(FieldInfo *fields, jvalue *fvalues, int n_fields,
                jint index, jvalue value, jvmtiPrimitiveType primType)
{
    ClassIndex  cnum;
    StringIndex name;
    StringIndex sig;

    cnum = fields[index].cnum;
    name = fields[index].name_index;
    sig  = fields[index].sig_index;
    debug_message("[%d] %s \"%s\" \"%s\"",
          index,
          cnum!=0?string_get(class_get_signature(cnum)):"?",
          name!=0?string_get(name):"?",
          sig!=0?string_get(sig):"?");
    if ( fields[index].primType!=0 || fields[index].primType!=primType ) {
        debug_message(" (primType=%d(%c)",
          fields[index].primType,
          primTypeToSigChar(fields[index].primType));
        if ( primType != fields[index].primType ) {
            debug_message(", got %d(%c)",
              primType,
              primTypeToSigChar(primType));
        }
        debug_message(")");
    } else {
        debug_message("(ty=OBJ)");
    }
    if ( value.j != (jlong)0 || fvalues[index].j != (jlong)0 ) {
        debug_message(" val=[0x%08x,0x%08x] or [0x%08x,0x%08x]",
            jlong_high(value.j), jlong_low(value.j),
            jlong_high(fvalues[index].j), jlong_low(fvalues[index].j));
    }
    debug_message("\n");
}

/* Dump all the fields of interest */
static void
dump_fields(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields)
{
    int i;

    debug_message("\nHPROF LIST OF ALL FIELDS:\n");
    for ( i = 0 ; i < n_fields ; i++ ) {
        if ( fields[i].name_index != 0 ) {
            dump_field(fields, fvalues, n_fields, i, fvalues[i], fields[i].primType);
        }
    }
    dump_ref_list(list);
}

/* Verify field data */
static void
verify_field(RefIndex list, FieldInfo *fields, jvalue *fvalues, int n_fields,
                jint index, jvalue value, jvmtiPrimitiveType primType)
{
    HPROF_ASSERT(fvalues != NULL);
    HPROF_ASSERT(n_fields > 0);
    HPROF_ASSERT(index < n_fields);
    HPROF_ASSERT(index >= 0 );
    if ( primType!=fields[index].primType ) {
        dump_fields(list, fields, fvalues, n_fields);
        debug_message("\nPROBLEM WITH:\n");
        dump_field(fields, fvalues, n_fields, index, value, primType);
        debug_message("\n");
        HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
    }
    if ( primType == JVMTI_PRIMITIVE_TYPE_BOOLEAN &&
         ( value.b != 1 && value.b != 0 ) ) {
        dump_fields(list, fields, fvalues, n_fields);
        debug_message("\nPROBLEM WITH:\n");
        dump_field(fields, fvalues, n_fields, index, value, primType);
        debug_message("\n");
        HPROF_ERROR(JNI_FALSE, "Trouble with fields and heap data");
    }
}

/* Fill in a field value, making sure the index is safe */
static void
fill_in_field_value(RefIndex list, FieldInfo *fields, jvalue *fvalues,
                    int n_fields, jint index, jvalue value,
                    jvmtiPrimitiveType primType)
{
    HPROF_ASSERT(fvalues != NULL);
    HPROF_ASSERT(n_fields > 0);
    HPROF_ASSERT(index < n_fields);
    HPROF_ASSERT(index >= 0 );
    HPROF_ASSERT(fvalues[index].j==(jlong)0);
    verify_field(list, fields, fvalues, n_fields, index, value, primType);
    if (index >= 0 && index < n_fields) {
        fvalues[index] = value;
    }
}

/* Walk all references for an ObjectIndex and construct the hprof CLASS dump. */
static void
dump_class_and_supers(JNIEnv *env, ObjectIndex object_index, RefIndex list)
{
    SiteIndex    site_index;
    SerialNumber trace_serial_num;
    RefIndex     index;
    ClassIndex   super_cnum;
    ObjectIndex  super_index;
    LoaderIndex  loader_index;
    ObjectIndex  signers_index;
    ObjectIndex  domain_index;
    FieldInfo   *fields;
    jvalue      *fvalues;
    jint         n_fields;
    jboolean     skip_fields;
    jint         n_fields_set;
    jlong        size;
    ClassIndex   cnum;
    char        *sig;
    ObjectKind   kind;
    TraceIndex   trace_index;
    Stack       *cpool_values;
    ConstantPoolValue *cpool;
    jint         cpool_count;

    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);
    if ( class_get_status(cnum) & CLASS_DUMPED ) {
        return;
    }
    class_add_status(cnum, CLASS_DUMPED);
    size        = (jlong)object_get_size(object_index);

    super_index = 0;
    super_cnum  = class_get_super(cnum);
    if ( super_cnum != 0 ) {
        super_index  = class_get_object_index(super_cnum);
        if ( super_index != 0 ) {
            dump_class_and_supers(env, super_index,
                        object_get_references(super_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));
    loader_index     = class_get_loader(cnum);
    signers_index    = 0;
    domain_index     = 0;

    /* Get field information */
    n_fields     = 0;
    skip_fields  = JNI_FALSE;
    n_fields_set = 0;
    fields       = NULL;
    fvalues      = NULL;
    if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 1 ) {
        /* Problems getting all the fields, can't trust field index values */
        skip_fields = JNI_TRUE;
        /* Class with no references at all? (ok to be unprepared if list==0?) */
        if ( list != 0 ) {
            /* 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 ) {
                dump_ref_list(list);
                debug_message("Unprepared class with references: %s\n",
                               sig);
            }
            HPROF_ERROR(JNI_FALSE, "Trouble with unprepared classes");
        }
        /* Why would an unprepared class contain references? */
    }
    if ( n_fields > 0 ) {
        fvalues      = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
        (void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
    }

    /* We use a Stack just because it will automatically expand as needed */
    cpool_values = stack_init(16, 16, sizeof(ConstantPoolValue));
    cpool = NULL;
    cpool_count = 0;

    index      = list;
    while ( index != 0 ) {
        RefInfo    *info;
        jvalue      ovalue;
        static jvalue empty_value;

        info = get_info(index);

        switch ( info->flavor ) {
            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 void
dump_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. */

void
reference_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 */
RefIndex
reference_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 */
RefIndex
reference_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 */
RefIndex
reference_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;
}

void
reference_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);
}
