hprof_site.c

来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 903 行 · 第 1/3 页

C
903
字号
    return index;}voidsite_init(void){    HPROF_ASSERT(gdata->site_table==NULL);    gdata->site_table = table_initialize("Site",                            1024, 1024, 511, (int)sizeof(SiteInfo));}voidsite_list(void){    debug_message(         "--------------------- Site Table ------------------------\n");    table_walk_items(gdata->site_table, &list_item, NULL);    debug_message(        "----------------------------------------------------------\n");}voidsite_cleanup(void){    table_cleanup(gdata->site_table, NULL, NULL);    gdata->site_table = NULL;}voidsite_update_stats(SiteIndex index, jint size, jint hits){    SiteInfo *info;        table_lock_enter(gdata->site_table); {        info = get_info(index);                info->n_live_instances          += hits;        info->n_live_bytes              += size;        info->changed                   = 1;                gdata->total_live_bytes         += size;        gdata->total_live_instances     += hits;                 if ( size > 0 ) {            info->n_alloced_instances   += hits;            info->n_alloced_bytes       += size;            gdata->total_alloced_bytes =                 jlong_add(gdata->total_alloced_bytes, jint_to_jlong(size));            gdata->total_alloced_instances =                 jlong_add(gdata->total_alloced_instances, jint_to_jlong(hits));        }    } table_lock_exit(gdata->site_table);}/* Output allocation sites, up to the given cut-off point, and according * to the given flags: * *      SITE_DUMP_INCREMENTAL only dump what's changed since last dump. *      SITE_SORT_BY_ALLOC    sort sites by total allocation rather *                                  than live data. *      SITE_FORCE_GC         force a GC before the site dump. */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);}/* 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;}/* Primitive field data callback for FollowReferences */static jint JNICALL cbPrimFieldData(jvmtiHeapReferenceKind reference_kind,          const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,          jlong* tag_ptr, jvalue value, jvmtiPrimitiveType value_type,          void* user_data){    ObjectIndex   object_index;    jint          field_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;    }    /* If the field is 0, just skip it, we assume 0 */    if ( value.j == (jlong)0 ) {        return JVMTI_VISIT_OBJECTS;    }    /* Get field index */    field_index = reference_info->field.index;       /* We assume the object was tagged */    object_index = tag_extract((*tag_ptr));        /* Save primitive field data */    prev_ref_index = object_get_references(object_index);    ref_index = reference_prim_field(prev_ref_index, reference_kind,                  value_type, value, field_index);    object_set_references(object_index, ref_index);    return JVMTI_VISIT_OBJECTS;}static SerialNumbercheckThreadSerialNumber(SerialNumber thread_serial_num){    TlsIndex tls_index;        if ( thread_serial_num == gdata->unknown_thread_serial_num ) {        return thread_serial_num;    }    tls_index = tls_find(thread_serial_num);    if ( tls_index != 0 && tls_get_in_heap_dump(tls_index) != 0 ) {        return thread_serial_num;    }    return gdata->unknown_thread_serial_num;}/* Get the object index and thread serial number for this local object */static voidlocalReference(jlong *tag_ptr, jlong class_tag, jlong thread_tag,      jlong size, ObjectIndex *pobject_index, SerialNumber *pthread_serial_num){    ObjectIndex  object_index;    SerialNumber thread_serial_num;    HPROF_ASSERT(pobject_index!=NULL);    HPROF_ASSERT(pthread_serial_num!=NULL);    HPROF_ASSERT(tag_ptr!=NULL);    HPROF_ASSERT(class_tag!=(jlong)0);        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 {        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;        }        /* Create and set the tag. */        *tag_ptr = make_new_tag(class_tag, size, gdata->system_trace_index,                  thread_serial_num, &object_index, NULL);    }    HPROF_ASSERT(thread_serial_num!=0);    HPROF_ASSERT(object_index!=0);    *pobject_index      = object_index;    *pthread_serial_num = thread_serial_num;}/* Store away plain object reference information */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?