hprof_object.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 433 行
C
433 行
/* * @(#)hprof_object.c 1.18 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "hprof.h"/* The table that maps objects to allocation sites */static hprof_objmap_t **hprof_objmap_table;static hprof_objmap_t *objmap_free_list = NULL;static int table_size = HPROF_SMALL_OBJMAP_TABLE_SIZE;#ifdef HASH_STATSstatic unsigned int table_deletes; /* # of entries deleted */static unsigned int table_hits; /* # of hash hits */static unsigned int table_misses; /* # of hash misses */#endif /* HASH_STATS */#define HASH_OBJ(obj) (((unsigned long)obj >> HASH_OBJ_SHIFT) % table_size)void hprof_objmap_init(void){ if (alloc_sites || heap_dump) table_size = HPROF_LARGE_OBJMAP_TABLE_SIZE; hprof_objmap_table = HPROF_CALLOC(ALLOC_TYPE_HASH_TABLES + ALLOC_HASH_OBJMAP, table_size * sizeof(hprof_objmap_t *));#ifdef HASH_STATS table_deletes = 0; table_hits = 0; table_misses = 0;#endif /* HASH_STATS */} static void add_alloc_stats(hprof_site_t *site, int size){ site->n_alloced_instances += 1; site->n_live_instances += 1; site->n_alloced_bytes += size; site->n_live_bytes += size; site->changed = 1; total_alloced_bytes = jlong_add(total_alloced_bytes, jint_to_jlong(size)); total_alloced_instances = jlong_add(total_alloced_instances, jint_to_jlong(1)); total_live_bytes += size; total_live_instances += 1;}static void sub_alloc_stats(hprof_site_t *site, int size){ site->n_live_instances--; site->n_live_bytes -= size; site->changed = 1; total_live_instances--; total_live_bytes -= size;} /* The objmap table maps objects to where they are allocated. Since this * is a much bigger table than site or trace tables, we do not use the * generic hash table routines for this purpose. Instead, we write * specialized code for better performance. */static hprof_objmap_t *hprof_objmap_add(jobjectID obj_id, jint arena_id, hprof_site_t *site, int size){ int index = HASH_OBJ(obj_id); hprof_objmap_t *bucket; if (objmap_free_list) { bucket = objmap_free_list; objmap_free_list = bucket->next; } else { bucket = HPROF_CALLOC(ALLOC_TYPE_OBJMAP, sizeof(hprof_objmap_t)); } bucket->size = size; bucket->site = site; bucket->obj_id = obj_id; bucket->arena_id = arena_id; bucket->next = hprof_objmap_table[index]; hprof_objmap_table[index] = bucket; if (site != NULL) { add_alloc_stats(site , size); } return bucket;}static void hprof_objmap_del(jobjectID obj_id){ int index = HASH_OBJ(obj_id); hprof_objmap_t **p = hprof_objmap_table + index; hprof_objmap_t *bucket; while ((bucket = *p)) { if (bucket->obj_id == obj_id) { *p = bucket->next; bucket->next = objmap_free_list; objmap_free_list = bucket; if (bucket->site != NULL) { sub_alloc_stats(bucket->site, bucket->size); } return; } p = &(bucket->next); } return;}static void hprof_objmap_del_arena(jint arena_id){ int i; for (i = 0; i < table_size; i++) { hprof_objmap_t **p = hprof_objmap_table + i; hprof_objmap_t *bucket; while ((bucket = *p)) { if (bucket->arena_id == arena_id) { *p = bucket->next; bucket->next = objmap_free_list; objmap_free_list = bucket; if ((bucket->site != NULL) && (bucket->size != 0)) { sub_alloc_stats(bucket->site, bucket->size); } } p = &(bucket->next); } }}static void hprof_objmap_move(jobjectID obj_id, jint arena_id, jobjectID new_obj_id, jint new_arena_id){ int old_index = HASH_OBJ(obj_id); int new_index = HASH_OBJ(new_obj_id); hprof_objmap_t **p = hprof_objmap_table + old_index; hprof_objmap_t *bucket; /* remove it from the old position in the hash table */ while ((bucket = *p)) { if (bucket->obj_id == obj_id) { *p = bucket->next; break; } p = &(bucket->next); } if (bucket != NULL) { /* rehash using the new obj_id; NOTE - the bucket remains the same */ bucket->obj_id = new_obj_id; bucket->arena_id = new_arena_id; bucket->next = hprof_objmap_table[new_index]; hprof_objmap_table[new_index] = bucket; } /* we ignore moves for objects with no prior record */}hprof_objmap_t * hprof_objmap_lookup(jobjectID obj_id){ int index = HASH_OBJ(obj_id); hprof_objmap_t *bucket = hprof_objmap_table[index]; while (bucket) { if (bucket->obj_id == obj_id) {#ifdef HASH_STATS table_hits++;#endif /* HASH_STATS */ return bucket; } bucket = bucket->next; }#ifdef HASH_STATS table_misses++;#endif /* HASH_STATS */ return NULL;}void hprof_objmap_print(hprof_objmap_t *objmap){ hprof_class_t *hclass = objmap->site->class; hprof_printf(" "); switch(objmap->site->is_array) { case JVMPI_NORMAL_OBJECT: hprof_printf("%s", hclass ? hclass->name->name : "<unknown class>"); break; case JVMPI_CLASS: hprof_printf("[L%s;", hclass->name->name); break; case JVMPI_BOOLEAN: hprof_printf("[Z"); break; case JVMPI_BYTE: hprof_printf("[B"); break; case JVMPI_CHAR: hprof_printf("[C"); break; case JVMPI_SHORT: hprof_printf("[S"); break; case JVMPI_INT: hprof_printf("[I"); break; case JVMPI_LONG: hprof_printf("[J"); break; case JVMPI_FLOAT: hprof_printf("[F"); break; case JVMPI_DOUBLE: hprof_printf("[D"); break; } hprof_printf("(%x)", objmap);}void hprof_obj_alloc_event(JNIEnv *env_id, jobjectID class_id, int is_array, int size, jobjectID obj_id, jint arena_id, int requested){ hprof_site_t *site; int trace_num = 0; CALL(RawMonitorEnter)(data_access_lock); if (requested) { if (hprof_objmap_lookup(obj_id)) { goto done; } trace_num = 0; } else { hprof_trace_t *htrace = hprof_get_trace(env_id, max_trace_depth); if (htrace == NULL) { fprintf(stderr, "HPROF ERROR: got NULL trace in obj_alloc\n"); } else { trace_num = htrace->serial_num; } } site = hprof_intern_site(class_id, is_array, trace_num); hprof_objmap_add(obj_id, arena_id, site, size); done: CALL(RawMonitorExit)(data_access_lock);}void hprof_obj_free_event(JNIEnv *env_id, jobjectID obj_id){ /* data_access_lock already entered in GC_START event */ hprof_objmap_del(obj_id);}void hprof_delete_arena_event(JNIEnv *env_id, jint arena_id){ /* data_access_lock already entered in GC_START event */ hprof_objmap_del_arena(arena_id);}void hprof_obj_move_event(JNIEnv *env_id, jobjectID obj_id, jint arena_id, jobjectID new_obj_id, jint new_arena_id){ /* data_access_lock already entered in GC_START event */ hprof_objmap_move(obj_id, arena_id, new_obj_id, new_arena_id);}hprof_objmap_t * hprof_fetch_object_info(jobjectID obj){ hprof_objmap_t * objmap; if (obj == NULL) { return NULL; } objmap = hprof_objmap_lookup(obj); if (objmap == NULL) {#ifdef OBJMAP_DEBUG fprintf(stderr, "requesting info for obj %x ", obj);#endif CALL(RequestEvent)(JVMPI_EVENT_OBJ_ALLOC, obj); objmap = hprof_objmap_lookup(obj);#ifdef OBJMAP_DEBUG fprintf(stderr, "=> %x\n", objmap);#endif } return objmap;}void hprof_print_object_info(jobjectID obj){ hprof_objmap_t *objmap = hprof_fetch_object_info(obj); hprof_class_t *hclass = objmap->site->class; if (objmap == NULL) { fprintf(stderr, "HPROF ERROR: unknown object ID 0x%p\n", obj); } hprof_printf(" "); switch(objmap->site->is_array) { case JVMPI_NORMAL_OBJECT: hprof_printf("%s", hclass ? hclass->name->name : "<unknown class>"); break; case JVMPI_CLASS: hprof_printf("[L%s;", hclass->name->name); break; case JVMPI_BOOLEAN: hprof_printf("[Z"); break; case JVMPI_BYTE: hprof_printf("[B"); break; case JVMPI_CHAR: hprof_printf("[C"); break; case JVMPI_SHORT: hprof_printf("[S"); break; case JVMPI_INT: hprof_printf("[I"); break; case JVMPI_LONG: hprof_printf("[J"); break; case JVMPI_FLOAT: hprof_printf("[F"); break; case JVMPI_DOUBLE: hprof_printf("[D"); break; } hprof_printf("(%x)", objmap);}#ifdef HASH_STATSvoid hprof_print_objmap_hash_stats(FILE *fp){ unsigned int elem_count = 0; /* total element count */ unsigned int empties = 0; /* number of empty slots */ unsigned int i; /* scratch index */ unsigned int prev_elems; /* previous element count */ fprintf(fp, "\nHash Table Statistics for 'objmap_tbl'\n\n"); if (print_verbose_hash_stats) { fprintf(fp, "Table Histogram:\n"); fprintf(fp, "'K'-1024 elements, '#'-100 elements, '@'-1 element\n"); } prev_elems = 0; /* skip leading empty slots */ for (i = 0; i < table_size; i++) { hprof_objmap_t *bucket; /* element index */ unsigned int count; /* # of markers to print */ unsigned int elems = 0; /* # of elements in slot */ unsigned int saved_elems; /* saved elems value */ for (bucket = hprof_objmap_table[i]; bucket; bucket = bucket->next) { elems++; } if (elems == 0) { /* nothing in this slot */ empties++; if (prev_elems != 0) { if (print_verbose_hash_stats) fprintf(fp, " ::\n"); prev_elems = 0; } continue; } saved_elems = elems; elem_count += elems; if (print_verbose_hash_stats) { fprintf(fp, "%7u: ", i); count = elems / 1024; if (count != 0) { elems -= count * 1024; for (; count > 0; count--) fputc('K', fp); } count = elems / 100; if (count != 0) { elems -= count * 100; for (; count > 0; count--) fputc('#', fp); } for (; elems > 0; elems--) fputc('@', fp); fprintf(fp, " (%u)\n", saved_elems); } prev_elems = saved_elems; } fprintf(fp, "#-elems=%u #-hits=%u #-misses=%u " "empty-slots=%.2f%% avg-#-elems=%.2f\n\n", elem_count, table_hits, table_misses, ((float)empties / table_size) * 100.0, (float)elem_count / (table_size - empties));}#endif /* HASH_STATS */#ifdef WATCH_ALLOCSvoid hprof_free_objmap_table(void) { int i; for (i = 0; i < table_size; i++) { hprof_objmap_t **p = &hprof_objmap_table[i]; hprof_objmap_t *bucket; while (bucket = *p) { *p = bucket->next; hprof_free(bucket);#ifdef HASH_STATS table_deletes++;#endif /* HASH_STATS */ } } hprof_free(hprof_objmap_table);}#endif /* WATCH_ALLOCS */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?