LoaderIndex
loader_find_or_create(JNIEnv *env, jobject loader)
{
    LoaderIndex index;

    /* See if we remembered the system loader */
    if ( loader==NULL && gdata->system_loader != 0 ) {
        return gdata->system_loader;
    }
    if ( loader==NULL ) {
        env = NULL;
    }
    index = search(env, loader);
    if ( index == 0 ) {
        static LoaderInfo  empty_info;
        LoaderInfo  info;

        info = empty_info;
        if ( loader != NULL ) {
            HPROF_ASSERT(env!=NULL);
            info.globalref = newWeakGlobalReference(env, loader);
            info.object_index = 0;
        }
        index = table_create_entry(gdata->loader_table, NULL, 0, (void*)&info);
    }
    HPROF_ASSERT(search(env,loader)==index);
    /* Remember the system loader */
    if ( loader==NULL && gdata->system_loader == 0 ) {
        gdata->system_loader = index;
    }
    return index;
}
/* Allocate bytes from a Blocks area. */
void *
blocks_alloc(Blocks *blocks, int nbytes)
{
    BlockHeader *block;
    int   pos;
    void *ptr;

    HPROF_ASSERT(blocks!=NULL);
    HPROF_ASSERT(nbytes>=0);
    if ( nbytes == 0 ) {
        return NULL;
    }

    block = blocks->current_block;
    nbytes = real_size(blocks->alignment, nbytes);
    if ( block == NULL || block->bytes_left < nbytes ) {
        add_block(blocks, nbytes);
        block = blocks->current_block;
    }
    pos = block->next_pos;
    ptr = (void*)(((char*)block)+pos);
    block->next_pos   += nbytes;
    block->bytes_left -= nbytes;
    return ptr;
}
static void
search_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    LoaderInfo  *info;
    SearchData  *data;

    HPROF_ASSERT(info_ptr!=NULL);
    HPROF_ASSERT(arg!=NULL);
    info        = (LoaderInfo*)info_ptr;
    data        = (SearchData*)arg;
    if ( data->loader == info->globalref ) {
        /* Covers when looking for NULL too. */
        HPROF_ASSERT(data->found==0); /* Did we find more than one? */
        data->found = index;
    } else if ( data->env != NULL && data->loader != NULL &&
                info->globalref != NULL ) {
        jobject lref;

        lref = newLocalReference(data->env, info->globalref);
        if ( lref == NULL ) {
            /* Object went away, free reference and entry */
            free_entry(data->env, index);
        } else if ( isSameObject(data->env, data->loader, lref) ) {
            HPROF_ASSERT(data->found==0); /* Did we find more than one? */
            data->found = index;
        }
        if ( lref != NULL ) {
            deleteLocalReference(data->env, lref);
        }
    }

}
/* Primitive array data callback for FollowReferences */
static jint JNICALL 
cbPrimArrayData(jlong class_tag, jlong size, jlong* tag_ptr, 
         jint element_count, jvmtiPrimitiveType element_type, 
         const void* elements, void* user_data)
{
    ObjectIndex   object_index;
    RefIndex      ref_index;
    RefIndex      prev_ref_index;

    HPROF_ASSERT(tag_ptr!=NULL);
    HPROF_ASSERT(class_tag!=(jlong)0);
    HPROF_ASSERT((*tag_ptr)!=(jlong)0);
    if ( class_tag == (jlong)0 || (*tag_ptr) == (jlong)0 ) {
        /* We can't do anything with a class_tag==0, just skip it */
        return JVMTI_VISIT_OBJECTS;
    }
   
    /* Assume object has been tagged, get object index */
    object_index = tag_extract((*tag_ptr));

    /* Save string data */
    prev_ref_index = object_get_references(object_index);
    ref_index = reference_prim_array(prev_ref_index,
                  element_type, elements, element_count);
    object_set_references(object_index, ref_index);

    return JVMTI_VISIT_OBJECTS;
}
/* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */
static void
add_block(Blocks *blocks, int nbytes)
{
    int header_size;
    int block_size;
    BlockHeader *block_header;

    HPROF_ASSERT(blocks!=NULL);
    HPROF_ASSERT(nbytes>0);

    header_size          = real_size(blocks->alignment, sizeof(BlockHeader));
    block_size           = blocks->elem_size*blocks->population;
    if ( nbytes > block_size ) {
        block_size = real_size(blocks->alignment, nbytes);
    }
    block_header         = (BlockHeader*)HPROF_MALLOC(block_size+header_size);
    block_header->next   = NULL;
    block_header->bytes_left = block_size;
    block_header->next_pos   = header_size;

    /* Link in new block */
    if ( blocks->current_block != NULL ) {
        blocks->current_block->next = block_header;
    }
    blocks->current_block = block_header;
    if ( blocks->first_block == NULL ) {
        blocks->first_block = block_header;
    }
}
예제 #6
0
static SiteKey*
get_pkey(SiteIndex index)
{
    void *key_ptr;
    int   key_len;

    table_get_key(gdata->site_table, index, &key_ptr, &key_len);
    HPROF_ASSERT(key_len==sizeof(SiteKey));
    HPROF_ASSERT(key_ptr!=NULL);
    return (SiteKey*)key_ptr;
}
예제 #7
0
파일: hprof_site.c 프로젝트: cedarli/java
/* JVMTI callback function. */
static jvmtiIterationControl JNICALL
stack_object(jvmtiHeapRootKind root_kind, 
		jlong class_tag, jlong size, jlong* tag_ptr, 
		jlong thread_tag, jint depth, jmethodID method, jint slot,
		void *user_data)
{

   /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
    *   are allowed here (see the JVMTI Spec).
    */

    ObjectIndex  object_index;
    SerialNumber thread_serial_num;

    HPROF_ASSERT(tag_ptr!=NULL);
    if ( (*tag_ptr) != (jlong)0 ) {
	object_index = tag_extract(*tag_ptr);
	thread_serial_num = object_get_thread_serial_number(object_index);
        thread_serial_num = checkThreadSerialNumber(thread_serial_num);
    } else {
	SiteIndex site_index;
	
        site_index = site_find_or_create(find_cnum(class_tag), 
				gdata->system_trace_index);
	if ( thread_tag != (jlong)0 ) {
	    ObjectIndex thread_object_index;

	    thread_object_index = tag_extract(thread_tag);
	    thread_serial_num = 
	           object_get_thread_serial_number(thread_object_index);
            thread_serial_num = checkThreadSerialNumber(thread_serial_num);
	} else {
	    thread_serial_num = gdata->unknown_thread_serial_num;
	}
	object_index = object_new(site_index, (jint)size, OBJECT_SYSTEM,
			    thread_serial_num);
	/* Create and set the tag. */
	*tag_ptr = tag_create(object_index);
    }

    HPROF_ASSERT(thread_serial_num!=0);
    HPROF_ASSERT(object_index!=0);
    switch ( root_kind ) {
        case JVMTI_HEAP_ROOT_STACK_LOCAL:
	    io_heap_root_java_frame(object_index, thread_serial_num, depth);
	    break;
        case JVMTI_HEAP_ROOT_JNI_LOCAL:
	    io_heap_root_jni_local(object_index, thread_serial_num, depth);
	    break;
	default:
	    break;
    }
    return JVMTI_ITERATION_CONTINUE;
}
예제 #8
0
static ObjectKey*
get_pkey(ObjectIndex index)
{
    void *key_ptr;
    int   key_len;

    table_get_key(gdata->object_table, index, (void*)&key_ptr, &key_len);
    HPROF_ASSERT(key_len==(int)sizeof(ObjectKey));
    HPROF_ASSERT(key_ptr!=NULL);
    return (ObjectKey*)key_ptr;
}
예제 #9
0
static void
mark_unchanged_iterator(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    SiteInfo *info;

    HPROF_ASSERT(key_ptr!=NULL);
    HPROF_ASSERT(key_len==sizeof(SiteKey));
    
    info = (SiteInfo *)info_ptr;
    if ( info != NULL ) {
        info->changed = 0;
    }
}
static void
delete_globalref(JNIEnv *env, LoaderInfo *info)
{
    jobject     ref;

    HPROF_ASSERT(env!=NULL);
    HPROF_ASSERT(info!=NULL);
    ref = info->globalref;
    info->globalref = NULL;
    if ( ref != NULL ) {
        deleteWeakGlobalReference(env, ref);
    }
    info->object_index = 0;
}
예제 #11
0
/* 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;
    }
}
예제 #12
0
void
reference_init(void)
{
    HPROF_ASSERT(gdata->reference_table==NULL);
    gdata->reference_table = table_initialize("Ref", 2048, 4096, 0,
                            (int)sizeof(RefInfo));
}
예제 #13
0
static int 
qsort_compare_live_bytes(const void *p_site1, const void *p_site2)
{
    SiteIndex  site1;
    SiteIndex  site2;
    SiteInfo  *info1;
    SiteInfo  *info2;
    
    HPROF_ASSERT(p_site1!=NULL);
    HPROF_ASSERT(p_site2!=NULL);
    site1 = *(SiteIndex *)p_site1;
    site2 = *(SiteIndex *)p_site2;
    info1 = get_info(site1);
    info2 = get_info(site2);
    return info2->n_live_bytes - info1->n_live_bytes;
}
예제 #14
0
void
site_init(void)
{
    HPROF_ASSERT(gdata->site_table==NULL);
    gdata->site_table = table_initialize("Site",
                            1024, 1024, 511, (int)sizeof(SiteInfo));
}
예제 #15
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;
}
예제 #16
0
SiteIndex
site_find_or_create(ClassIndex cnum, TraceIndex trace_index)
{
    SiteIndex index;
    static SiteKey  empty_key;
    SiteKey   key;
    
    key = empty_key;
    HPROF_ASSERT(cnum!=0);
    HPROF_ASSERT(trace_index!=0);
    key.cnum        = cnum;
    key.trace_index = trace_index;
    index = table_find_or_create_entry(gdata->site_table, 
			    &key, (int)sizeof(key), NULL, NULL);
    return index;
}
예제 #17
0
/* JVMTI callback function. */
static jvmtiIterationControl JNICALL
reference_object(jvmtiObjectReferenceKind reference_kind, 
		jlong class_tag, jlong size, jlong* tag_ptr, 
		jlong referrer_tag, jint referrer_index, void *user_data)
{

   /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
    *   are allowed here (see the JVMTI Spec).
    */

    RefIndex      ref_index;
    RefIndex      prev_ref_index;
    ObjectIndex   referrer_object_index;
    ObjectIndex   object_index;
    jlong         object_tag;

    HPROF_ASSERT(tag_ptr!=NULL);
    HPROF_ASSERT(referrer_tag!=(jlong)0);
    
    if ( referrer_tag != (jlong)0 ) {
	referrer_object_index = tag_extract(referrer_tag);
    } else {
        return JVMTI_ITERATION_CONTINUE;
    }
    
    object_tag = *tag_ptr;
    if ( object_tag != (jlong)0 ) {
        object_index = tag_extract(object_tag);
    } else {
        SiteIndex site_index;
	
        site_index = site_find_or_create(find_cnum(class_tag), 
			gdata->system_trace_index);
	object_index = object_new(site_index, (jint)size, OBJECT_SYSTEM,
				gdata->system_thread_serial_num);
	object_tag = tag_create(object_index);
	*tag_ptr   = object_tag;
    }

    /* Save reference information */
    prev_ref_index = object_get_references(referrer_object_index);
    ref_index = reference_new(prev_ref_index, reference_kind,
		    class_tag, size, object_tag, referrer_index);
    object_set_references(referrer_object_index, ref_index);
    
    return JVMTI_ITERATION_CONTINUE;
}
예제 #18
0
static void
list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    FrameKey   key;
    FrameInfo *info;

    HPROF_ASSERT(key_ptr!=NULL);
    HPROF_ASSERT(key_len==sizeof(FrameKey));
    HPROF_ASSERT(info_ptr!=NULL);

    key = *((FrameKey*)key_ptr);
    info = (FrameInfo*)info_ptr;
    debug_message(
        "Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n",
                i, (void*)key.method, (jint)key.location,
                info->lineno, info->lineno_state, info->status);
}
예제 #19
0
/* 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;
}
/* Initialize a new Blocks */
Blocks *
blocks_init(int alignment, int elem_size, int population)
{
    Blocks *blocks;

    HPROF_ASSERT(alignment>0);
    HPROF_ASSERT(elem_size>0);
    HPROF_ASSERT(population>0);

    blocks                = (Blocks*)HPROF_MALLOC(sizeof(Blocks));
    blocks->alignment     = alignment;
    blocks->elem_size     = elem_size;
    blocks->population    = population;
    blocks->first_block   = NULL;
    blocks->current_block = NULL;
    return blocks;
}
예제 #21
0
static void
dump_instance_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    ObjectInfo *info;
    
    HPROF_ASSERT(info_ptr!=NULL);
    info = (ObjectInfo *)info_ptr;
    reference_dump_instance((JNIEnv*)arg, i, info->references);
}
예제 #22
0
static void
clear_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    ObjectInfo *info;
    
    HPROF_ASSERT(info_ptr!=NULL);
    info = (ObjectInfo *)info_ptr;
    info->references = 0;
}
예제 #23
0
static void
list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    ObjectKey  *pkey;
    ObjectInfo *info;
    
    HPROF_ASSERT(key_ptr!=NULL);
    HPROF_ASSERT(key_len!=0);
    HPROF_ASSERT(info_ptr!=NULL);

    info = (ObjectInfo*)info_ptr;
   
    pkey = (ObjectKey*)key_ptr;
    debug_message( "Object 0x%08x: site=0x%08x, SN=%u, "
			  " size=%d, kind=%d, refs=0x%x, threadSN=%u\n",
	 i, pkey->site_index, pkey->serial_num, pkey->size, pkey->kind,
	 info->references, info->thread_serial_num);
}
예제 #24
0
int
string_get_len(StringIndex index)
{
    void *key;
    int   key_len;

    table_get_key(gdata->string_table, index, &key, &key_len);
    HPROF_ASSERT(key_len>0);
    return key_len-1;
}
예제 #25
0
/* 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;
}
예제 #26
0
char *
string_get(StringIndex index)
{
    void *key;
    int   key_len;

    table_get_key(gdata->string_table, index, &key, &key_len);
    HPROF_ASSERT(key_len>0);
    return (char*)key;
}
예제 #27
0
/* Write to a fd */
static void
system_write(int fd, void *buf, int len)
{
    int res;

    HPROF_ASSERT(fd>=0);
    res = md_write(fd, buf, len);
    if (res < 0 || res!=len) {
        system_error("write", res, errno);
    }
}
예제 #28
0
static void
collect_iterator(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    IterateInfo     *iterate;

    HPROF_ASSERT(key_ptr!=NULL);
    HPROF_ASSERT(key_len==sizeof(SiteKey));
    HPROF_ASSERT(arg!=NULL);
    iterate = (IterateInfo *)arg;

    if ( iterate->changed_only ) {
        SiteInfo *info;
        
        info = (SiteInfo *)info_ptr;
        if ( info==NULL || !info->changed ) {
            return;
        }
    }
    iterate->site_nums[iterate->count++] = i;
}
static void
list_item(TableIndex index, void *key_ptr, int key_len,
                        void *info_ptr, void *arg)
{
    LoaderInfo     *info;

    HPROF_ASSERT(info_ptr!=NULL);

    info        = (LoaderInfo*)info_ptr;
    debug_message( "Loader 0x%08x: globalref=%p, object_index=%d\n",
                index, (void*)info->globalref, info->object_index);
}
예제 #30
0
static void
list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
{
    SiteKey         *pkey;
    jlong            n_alloced_instances;
    jlong            n_alloced_bytes;
    jlong            n_live_instances;
    jlong            n_live_bytes;

    HPROF_ASSERT(key_ptr!=NULL);
    HPROF_ASSERT(key_len==sizeof(SiteKey));
    pkey = (SiteKey*)key_ptr;
    
    if ( info_ptr != NULL ) {
        SiteInfo *info;
    
        info = (SiteInfo *)info_ptr;
        n_alloced_instances    = info->n_alloced_instances;
        n_alloced_bytes        = info->n_alloced_bytes;
        n_live_instances       = info->n_live_instances;
        n_live_bytes           = info->n_live_bytes;
    } else {
        n_alloced_instances    = 0;
        n_alloced_bytes        = 0;
        n_live_instances       = 0;
        n_live_bytes           = 0;
    }
    
    debug_message( "Site 0x%08x: class=0x%08x, trace=0x%08x, "
                          "Ninst=(%d,%d), Nbytes=(%d,%d), "
                          "Nlive=(%d,%d), NliveBytes=(%d,%d)\n",
             i, 
             pkey->cnum, 
             pkey->trace_index,
             jlong_high(n_alloced_instances), jlong_low(n_alloced_instances),
             jlong_high(n_alloced_bytes),     jlong_low(n_alloced_bytes),
             jlong_high(n_live_instances),    jlong_low(n_live_instances),
             jlong_high(n_live_bytes),        jlong_low(n_live_bytes));
}