예제 #1
0
/* Add a instance field information to this cmap. */
static void
add_inst_field_to_cmap(CmapInfo *cmap, HprofId id, HprofType ty)
{
   int i;

   HPROF_ASSERT(cmap!=NULL);
   i = cmap->n_finfo++;
   if ( i+1 >= cmap->max_finfo ) {
       int    osize;
       Finfo *new_finfo;

       osize            = cmap->max_finfo;
       cmap->max_finfo += 12;
       new_finfo = (Finfo*)HPROF_MALLOC(cmap->max_finfo*(int)sizeof(Finfo));
       (void)memset(new_finfo,0,cmap->max_finfo*(int)sizeof(Finfo));
       if ( i == 0 ) {
           cmap->finfo = new_finfo;
       } else {
           (void)memcpy(new_finfo,cmap->finfo,osize*(int)sizeof(Finfo));
           HPROF_FREE(cmap->finfo);
           cmap->finfo = new_finfo;
       }
   }
   cmap->finfo[i].id = id;
   cmap->finfo[i].ty = ty;
}
예제 #2
0
void
check_binary_file(char *filename)
{
    unsigned char *image;
    unsigned char *p;
    unsigned       idsize;
    int            nbytes;
    int            nrecords;

    image = get_binary_file_image(filename, &nbytes);
    if ( image == NULL ) {
        check_printf("No file image: %s\n", filename);
        return;
    }
    p = image;
    CHECK_FOR_ERROR(strcmp((char*)p, gdata->header)==0);
    check_printf("Filename=%s, nbytes=%d, header=\"%s\"\n",
                        filename, nbytes, p);
    p+=((int)strlen((char*)p)+1);
    idsize = read_u4(&p);
    CHECK_FOR_ERROR(idsize==sizeof(HprofId));
    (void)read_u4(&p);
    (void)read_u4(&p);
    /* LINTED */
    nrecords = check_tags(p, nbytes - (int)( p - image ) );
    check_printf("#%d total records found in %d bytes\n", nrecords, nbytes);
    HPROF_FREE(image);
}
/* Terminate the Blocks */
void
blocks_term(Blocks *blocks)
{
    BlockHeader *block;

    HPROF_ASSERT(blocks!=NULL);

    block = blocks->first_block;
    while ( block != NULL ) {
        BlockHeader *next_block;

        next_block = block->next;
        HPROF_FREE(block);
        block = next_block;
    }
    HPROF_FREE(blocks);
}
예제 #4
0
/* LookupTable cleanup callback for utab */
static void
utab_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data)
{
    UmapInfo *umap = info;

    if ( umap == NULL ) {
        return;
    }
    if ( umap->str != NULL ) {
        HPROF_FREE(umap->str);
        umap->str = NULL;
    }
}
예제 #5
0
/* LookupTable callback for cmap entry cleanup */
static void
cmap_cleanup(TableIndex i, void *key_ptr, int key_len, void*info, void*data)
{
    CmapInfo *cmap = info;

    if ( cmap == NULL ) {
        return;
    }
    if ( cmap->finfo != NULL ) {
        HPROF_FREE(cmap->finfo);
        cmap->finfo = NULL;
    }
}
/* 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 */
    }
}
/* 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);
    }
}
예제 #8
0
void 
site_write(JNIEnv *env, int flags, double cutoff)
{
    HPROF_ASSERT(gdata->site_table!=NULL);
    LOG3("site_write", "flags", flags);
    
    if (flags & SITE_FORCE_GC) {
        runGC();
    }

    HPROF_ASSERT(gdata->total_live_bytes!=0);

    rawMonitorEnter(gdata->data_access_lock); {
        
        IterateInfo     iterate;
        int             site_table_size;
        double          accum_percent;
        void *          comment_str;
        int             i;
        int             cutoff_count;
	int             nbytes;

        accum_percent = 0;
        site_table_size = table_element_count(gdata->site_table);
        
        (void)memset(&iterate, 0, sizeof(iterate));
	nbytes            = site_table_size * (int)sizeof(SiteIndex);
	if ( nbytes > 0 ) {
	    iterate.site_nums = HPROF_MALLOC(nbytes);
	    (void)memset(iterate.site_nums, 0, nbytes);
	}
        iterate.count   = 0;
        iterate.changed_only = flags & SITE_DUMP_INCREMENTAL;
        table_walk_items(gdata->site_table, &collect_iterator, &iterate);

        site_table_size = iterate.count;
        
        if (flags & SITE_SORT_BY_ALLOC) {
            comment_str = "allocated bytes";
            qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex), 
                    &qsort_compare_allocated_bytes);
        } else {
            comment_str = "live bytes";
            qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex), 
                    &qsort_compare_live_bytes); 
        }

        trace_output_unmarked(env);
        
        cutoff_count = 0;
        for (i = 0; i < site_table_size; i++) {
            SiteInfo   *info;
            SiteIndex   index;
            double      ratio;
            
            index= iterate.site_nums[i];
            HPROF_ASSERT(index!=0);
            info        = get_info(index);
            ratio       = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
            if (ratio < cutoff) {
                break;
            }
            cutoff_count++;
        }
        
        io_write_sites_header(  comment_str,
                                flags,
                                cutoff,
                                gdata->total_live_bytes,
                                gdata->total_live_instances,
                                gdata->total_alloced_bytes,
                                gdata->total_alloced_instances,
                                cutoff_count);
        
        for (i = 0; i < cutoff_count; i++) {
            SiteInfo     *info;
            SiteKey      *pkey;
            SiteIndex     index;
            char         *class_signature;
            double        ratio;
            
            index = iterate.site_nums[i];
            pkey         = get_pkey(index);
            info         = get_info(index);
            
            ratio       = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
            accum_percent += ratio;
            
            class_signature  = string_get(class_get_signature(pkey->cnum));
            
            io_write_sites_elem(i + 1,
                                ratio,
                                accum_percent,
                                class_signature,
                                class_get_serial_number(pkey->cnum),
                                trace_get_serial_number(pkey->trace_index),
                                info->n_live_bytes,
                                info->n_live_instances,
                                info->n_alloced_bytes,
                                info->n_alloced_instances);
        }
        
        io_write_sites_footer();

        table_walk_items(gdata->site_table, &mark_unchanged_iterator, NULL);

	if ( iterate.site_nums != NULL ) {
	    HPROF_FREE(iterate.site_nums);
        }

    } rawMonitorExit(gdata->data_access_lock);
}
예제 #9
0
/* 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;
    jlong        size;
    ClassIndex   cnum;
    char        *sig;
    ObjectKind   kind;
    TraceIndex   trace_index;
    Stack       *cpool_values;
    ConstantPoolValue *cpool;
    jint         cpool_count;
    jboolean     skip_fields;

    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));
    
    n_fields     = 0;
    fields       = NULL;
    fvalues      = NULL;
    skip_fields  = JNI_TRUE;
    if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 0 ) {
        if ( n_fields > 0 ) {
            skip_fields  = JNI_FALSE;
	    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;
    
    loader_index     = class_get_loader(cnum);
    signers_index    = 0;
    domain_index     = 0;

    index      = list;
    while ( index != 0 ) {
	RefInfo    *info;

	info = get_info(index);

	/* Process reference objects, many not used right now. */
	switch ( info->kind ) {
	    case JVMTI_REFERENCE_STATIC_FIELD:
		/* If the class_tag is 0, it is possible for 
		 *    info->element_index to be >= n_fields
		 *    and when this happens we just skip this field ref
		 *    for now. We probably have a java.lang.Object class
		 *    with n_fields==0, which is probably the wrong class.
		 */
		if (info->class_tag == (jlong)0 || skip_fields == JNI_TRUE ) {
		    break;
		}
		HPROF_ASSERT(info->element_index < n_fields);
		if (info->element_index < n_fields) {
	            ObjectIndex field_object_index;
		
		    /* Field index is referrer_index from referrer_tag */
		    field_object_index = tag_to_object_index(info->object_tag);
		    fvalues[info->element_index].i = field_object_index;
		}
		break;
	    case JVMTI_REFERENCE_CONSTANT_POOL: {
		ConstantPoolValue cpv;
		ObjectIndex       cp_object_index;
		SiteIndex         cp_site_index;
		ClassIndex        cp_cnum;
	        
		cp_object_index = tag_to_object_index(info->object_tag);
                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->element_index;
		cpv.sig_index = class_get_signature(cp_cnum); 
		cpv.value.i = cp_object_index;
		stack_push(cpool_values, (void*)&cpv);
		cpool_count++;
		break;
		}
	    default:
		break;
	}
	index = info->next;
    }

    /* FIXUP: Fill rest of static primitive fields? If requested? */
    /*   Use: value = getStaticFieldValue(env, klass, field, field_sig); ? */

    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_index, signers_index, domain_index,
	    (jint)size, cpool_count, cpool, n_fields, fields, fvalues);

    stack_term(cpool_values);
    if ( fvalues != NULL ) {
	HPROF_FREE(fvalues);
    }
}
예제 #10
0
/* Walk all references for an ObjectIndex and construct the hprof INST dump. */
static void
dump_instance(JNIEnv *env, ObjectIndex object_index, RefIndex list)
{
    SiteIndex    site_index;
    SerialNumber trace_serial_num;
    RefIndex     index;
    ObjectIndex  class_index;
    jlong        size;
    ClassIndex   cnum;
    char        *sig;
    jint         num_elements;
    jvalue      *values;
    FieldInfo   *fields;
    jvalue      *fvalues;
    jint         n_fields;
    ObjectKind   kind;
    TraceIndex   trace_index;
    jboolean     skip_fields;

    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;
    num_elements = 0;
    
    n_fields     = 0;
    fields       = NULL;
    fvalues      = NULL;
    
    index = list;
    
    skip_fields  = JNI_TRUE;
    if ( sig[0] != JVM_SIGNATURE_ARRAY ) {
	if ( class_get_all_fields(env, cnum, &n_fields, &fields) == 0 ) {
	    if ( n_fields > 0 ) {
                skip_fields  = JNI_FALSE;
		fvalues = (jvalue*)HPROF_MALLOC(n_fields*(int)sizeof(jvalue));
		(void)memset(fvalues, 0, n_fields*(int)sizeof(jvalue));
	    }
	}
    }

    while ( index != 0 ) {
	ObjectIndex field_object_index;
	RefInfo *info;

	info = get_info(index);

	/* Process reference objects, many not used right now. */
	switch ( info->kind ) {
	    case JVMTI_REFERENCE_FIELD:
		/* If the class_tag is 0, it is possible for 
		 *    info->element_index to be >= n_fields
		 *    and when this happens we just skip this field ref
		 *    for now. We probably have a java.lang.Object class
		 *    with n_fields==0, which is probably the wrong class.
		 */
		if (info->class_tag == (jlong)0 || skip_fields == JNI_TRUE ) {
		    break;
		}
		HPROF_ASSERT(info->element_index < n_fields);
		if (info->element_index < n_fields) {
		    /* Field index is referrer_index from referrer_tag */
		    field_object_index = tag_to_object_index(info->object_tag);
		    fvalues[info->element_index].i = field_object_index;
		}
		break;
	    case JVMTI_REFERENCE_ARRAY_ELEMENT:
		/* Array element index is referrer_index in referrer_tag */
		if ( num_elements <= info->element_index  ) {
		    int nbytes;
		    
		    if ( values == NULL ) {
		        num_elements = info->element_index + 1;
			nbytes = num_elements*(int)sizeof(jvalue);
			values = (jvalue*)HPROF_MALLOC(nbytes);
			(void)memset(values, 0, nbytes);
		    } else {
		        void *new_values;
			int   new_size;
			int   obytes;

			obytes = num_elements*(int)sizeof(jvalue);
			new_size = info->element_index + 1;
			nbytes = new_size*(int)sizeof(jvalue);
			new_values = (jvalue*)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;
		    }
		}
                field_object_index = tag_to_object_index(info->object_tag);
		HPROF_ASSERT(values[info->element_index].i==0);
		values[info->element_index].i = field_object_index;
		break;
	    default:
		break;
	}
	index = info->next;
    }
    
    if ( sig[0] == JVM_SIGNATURE_ARRAY ) {
	/* FIXUP: Fill primitive arrays? If requested? */
	switch ( sig[1] ) {
	    case JVM_SIGNATURE_CLASS:
	    case JVM_SIGNATURE_ENUM:
	    case JVM_SIGNATURE_ARRAY:
		io_heap_object_array(object_index, trace_serial_num,
			(jint)size, num_elements, class_index, values, sig);
		break;
	    case JVM_SIGNATURE_BYTE:
	    case JVM_SIGNATURE_BOOLEAN:
		io_heap_prim_array(object_index, (jint)size, 
			trace_serial_num, num_elements, sig, values);
		break;
	    case JVM_SIGNATURE_CHAR:
	    case JVM_SIGNATURE_SHORT:
		io_heap_prim_array(object_index, (jint)size, 
			trace_serial_num, num_elements, sig, values);
		break;
	    case JVM_SIGNATURE_INT:
	    case JVM_SIGNATURE_FLOAT:
		io_heap_prim_array(object_index, (jint)size, 
			    trace_serial_num, num_elements, sig, values);
		break;
	    case JVM_SIGNATURE_DOUBLE:
	    case JVM_SIGNATURE_LONG:
		io_heap_prim_array(object_index, (jint)size, 
			trace_serial_num, num_elements, sig, values);
		break;
	    default:
		HPROF_ASSERT(0);
		break;
	}
    } else { 
	/* FIXUP: Fill rest of primitive fields? If requested? */
        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);
    }
}