00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #include "hprof.h"
00079
00080 typedef struct ObjectKey {
00081 SiteIndex site_index;
00082 jint size;
00083 ObjectKind kind;
00084 SerialNumber serial_num;
00085 } ObjectKey;
00086
00087 typedef struct ObjectInfo {
00088 RefIndex references;
00089 SerialNumber thread_serial_num;
00090 } ObjectInfo;
00091
00092
00093
00094 static ObjectKey*
00095 get_pkey(ObjectIndex index)
00096 {
00097 void *key_ptr;
00098 int key_len;
00099
00100 table_get_key(gdata->object_table, index, (void*)&key_ptr, &key_len);
00101 HPROF_ASSERT(key_len==(int)sizeof(ObjectKey));
00102 HPROF_ASSERT(key_ptr!=NULL);
00103 return (ObjectKey*)key_ptr;
00104 }
00105
00106 static ObjectInfo *
00107 get_info(ObjectIndex index)
00108 {
00109 ObjectInfo *info;
00110
00111 info = (ObjectInfo*)table_get_info(gdata->object_table, index);
00112 return info;
00113 }
00114
00115 static void
00116 list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00117 {
00118 ObjectKey *pkey;
00119 ObjectInfo *info;
00120
00121 HPROF_ASSERT(key_ptr!=NULL);
00122 HPROF_ASSERT(key_len!=0);
00123 HPROF_ASSERT(info_ptr!=NULL);
00124
00125 info = (ObjectInfo*)info_ptr;
00126
00127 pkey = (ObjectKey*)key_ptr;
00128 debug_message( "Object 0x%08x: site=0x%08x, SN=%u, "
00129 " size=%d, kind=%d, refs=0x%x, threadSN=%u\n",
00130 i, pkey->site_index, pkey->serial_num, pkey->size, pkey->kind,
00131 info->references, info->thread_serial_num);
00132 }
00133
00134 static void
00135 clear_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00136 {
00137 ObjectInfo *info;
00138
00139 HPROF_ASSERT(info_ptr!=NULL);
00140 info = (ObjectInfo *)info_ptr;
00141 info->references = 0;
00142 }
00143
00144 static void
00145 dump_class_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00146 {
00147 ObjectInfo *info;
00148
00149 HPROF_ASSERT(info_ptr!=NULL);
00150 info = (ObjectInfo *)info_ptr;
00151 reference_dump_class((JNIEnv*)arg, i, info->references);
00152 }
00153
00154 static void
00155 dump_instance_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00156 {
00157 ObjectInfo *info;
00158
00159 HPROF_ASSERT(info_ptr!=NULL);
00160 info = (ObjectInfo *)info_ptr;
00161 reference_dump_instance((JNIEnv*)arg, i, info->references);
00162 }
00163
00164
00165
00166 ObjectIndex
00167 object_new(SiteIndex site_index, jint size, ObjectKind kind, SerialNumber thread_serial_num)
00168 {
00169 ObjectIndex index;
00170 ObjectKey key;
00171 static ObjectKey empty_key;
00172
00173 key = empty_key;
00174 key.site_index = site_index;
00175 key.size = size;
00176 key.kind = kind;
00177 if ( gdata->heap_dump ) {
00178 static ObjectInfo empty_info;
00179 ObjectInfo i;
00180
00181 i = empty_info;
00182 i.thread_serial_num = thread_serial_num;
00183 key.serial_num = gdata->object_serial_number_counter++;
00184 index = table_create_entry(gdata->object_table,
00185 &key, (int)sizeof(ObjectKey), &i);
00186 } else {
00187 key.serial_num =
00188 class_get_serial_number(site_get_class_index(site_index));
00189 index = table_find_or_create_entry(gdata->object_table,
00190 &key, (int)sizeof(ObjectKey), NULL, NULL);
00191 }
00192 site_update_stats(site_index, size, 1);
00193 return index;
00194 }
00195
00196 void
00197 object_init(void)
00198 {
00199 jint bucket_count;
00200
00201 bucket_count = 511;
00202 if ( gdata->heap_dump ) {
00203 bucket_count = 0;
00204 }
00205 HPROF_ASSERT(gdata->object_table==NULL);
00206 gdata->object_table = table_initialize("Object", 4096,
00207 4096, bucket_count, (int)sizeof(ObjectInfo));
00208 }
00209
00210 SiteIndex
00211 object_get_site(ObjectIndex index)
00212 {
00213 ObjectKey *pkey;
00214
00215 pkey = get_pkey(index);
00216 return pkey->site_index;
00217 }
00218
00219 jint
00220 object_get_size(ObjectIndex index)
00221 {
00222 ObjectKey *pkey;
00223
00224 pkey = get_pkey(index);
00225 return pkey->size;
00226 }
00227
00228 ObjectKind
00229 object_get_kind(ObjectIndex index)
00230 {
00231 ObjectKey *pkey;
00232
00233 pkey = get_pkey(index);
00234 return pkey->kind;
00235 }
00236
00237 ObjectKind
00238 object_free(ObjectIndex index)
00239 {
00240 ObjectKey *pkey;
00241 ObjectKind kind;
00242
00243 pkey = get_pkey(index);
00244 kind = pkey->kind;
00245
00246
00247 site_update_stats(pkey->site_index, -(pkey->size), -1);
00248
00249 if ( gdata->heap_dump ) {
00250 table_free_entry(gdata->object_table, index);
00251 }
00252 return kind;
00253 }
00254
00255 void
00256 object_list(void)
00257 {
00258 debug_message(
00259 "--------------------- Object Table ------------------------\n");
00260 table_walk_items(gdata->object_table, &list_item, NULL);
00261 debug_message(
00262 "----------------------------------------------------------\n");
00263 }
00264
00265 void
00266 object_cleanup(void)
00267 {
00268 table_cleanup(gdata->object_table, NULL, NULL);
00269 gdata->object_table = NULL;
00270 }
00271
00272 void
00273 object_set_thread_serial_number(ObjectIndex index,
00274 SerialNumber thread_serial_num)
00275 {
00276 ObjectInfo *info;
00277
00278 info = get_info(index);
00279 info->thread_serial_num = thread_serial_num;
00280 }
00281
00282 SerialNumber
00283 object_get_thread_serial_number(ObjectIndex index)
00284 {
00285 ObjectInfo *info;
00286
00287 info = get_info(index);
00288 return info->thread_serial_num;
00289 }
00290
00291 RefIndex
00292 object_get_references(ObjectIndex index)
00293 {
00294 ObjectInfo *info;
00295
00296 info = get_info(index);
00297 return info->references;
00298 }
00299
00300 void
00301 object_set_references(ObjectIndex index, RefIndex ref_index)
00302 {
00303 ObjectInfo *info;
00304
00305 info = get_info(index);
00306 info->references = ref_index;
00307 }
00308
00309 void
00310 object_clear_references(void)
00311 {
00312 table_walk_items(gdata->object_table, &clear_references, NULL);
00313 }
00314
00315 void
00316 object_reference_dump(JNIEnv *env)
00317 {
00318 table_walk_items(gdata->object_table, &dump_instance_references, (void*)env);
00319 table_walk_items(gdata->object_table, &dump_class_references, (void*)env);
00320 }