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 #include "hprof.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 enum LinenoState {
00051 LINENUM_UNINITIALIZED = 0,
00052 LINENUM_AVAILABLE = 1,
00053 LINENUM_UNAVAILABLE = 2
00054 };
00055
00056 typedef struct FrameKey {
00057 jmethodID method;
00058 jlocation location;
00059 } FrameKey;
00060
00061 typedef struct FrameInfo {
00062 unsigned short lineno;
00063 unsigned char lineno_state;
00064 unsigned char status;
00065 SerialNumber serial_num;
00066 } FrameInfo;
00067
00068 static FrameKey*
00069 get_pkey(FrameIndex index)
00070 {
00071 void *key_ptr;
00072 int key_len;
00073
00074 table_get_key(gdata->frame_table, index, &key_ptr, &key_len);
00075 HPROF_ASSERT(key_len==sizeof(FrameKey));
00076 HPROF_ASSERT(key_ptr!=NULL);
00077 return (FrameKey*)key_ptr;
00078 }
00079
00080 static FrameInfo *
00081 get_info(FrameIndex index)
00082 {
00083 FrameInfo *info;
00084
00085 info = (FrameInfo*)table_get_info(gdata->frame_table, index);
00086 return info;
00087 }
00088
00089 static void
00090 list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)
00091 {
00092 FrameKey key;
00093 FrameInfo *info;
00094
00095 HPROF_ASSERT(key_ptr!=NULL);
00096 HPROF_ASSERT(key_len==sizeof(FrameKey));
00097 HPROF_ASSERT(info_ptr!=NULL);
00098
00099 key = *((FrameKey*)key_ptr);
00100 info = (FrameInfo*)info_ptr;
00101 debug_message(
00102 "Frame 0x%08x: method=%p, location=%d, lineno=%d(%d), status=%d \n",
00103 i, (void*)key.method, (jint)key.location,
00104 info->lineno, info->lineno_state, info->status);
00105 }
00106
00107 void
00108 frame_init(void)
00109 {
00110 gdata->frame_table = table_initialize("Frame",
00111 1024, 1024, 1023, (int)sizeof(FrameInfo));
00112 }
00113
00114 FrameIndex
00115 frame_find_or_create(jmethodID method, jlocation location)
00116 {
00117 FrameIndex index;
00118 static FrameKey empty_key;
00119 FrameKey key;
00120 jboolean new_one;
00121
00122 key = empty_key;
00123 key.method = method;
00124 key.location = location;
00125 new_one = JNI_FALSE;
00126 index = table_find_or_create_entry(gdata->frame_table,
00127 &key, (int)sizeof(key), &new_one, NULL);
00128 if ( new_one ) {
00129 FrameInfo *info;
00130
00131 info = get_info(index);
00132 info->lineno_state = LINENUM_UNINITIALIZED;
00133 if ( location < 0 ) {
00134 info->lineno_state = LINENUM_UNAVAILABLE;
00135 }
00136 info->serial_num = gdata->frame_serial_number_counter++;
00137 }
00138 return index;
00139 }
00140
00141 void
00142 frame_list(void)
00143 {
00144 debug_message(
00145 "--------------------- Frame Table ------------------------\n");
00146 table_walk_items(gdata->frame_table, &list_item, NULL);
00147 debug_message(
00148 "----------------------------------------------------------\n");
00149 }
00150
00151 void
00152 frame_cleanup(void)
00153 {
00154 table_cleanup(gdata->frame_table, NULL, NULL);
00155 gdata->frame_table = NULL;
00156 }
00157
00158 void
00159 frame_set_status(FrameIndex index, jint status)
00160 {
00161 FrameInfo *info;
00162
00163 info = get_info(index);
00164 info->status = (unsigned char)status;
00165 }
00166
00167 void
00168 frame_get_location(FrameIndex index, SerialNumber *pserial_num,
00169 jmethodID *pmethod, jlocation *plocation, jint *plineno)
00170 {
00171 FrameKey *pkey;
00172 FrameInfo *info;
00173 jint lineno;
00174
00175 pkey = get_pkey(index);
00176 *pmethod = pkey->method;
00177 *plocation = pkey->location;
00178 info = get_info(index);
00179 lineno = (jint)info->lineno;
00180 if ( info->lineno_state == LINENUM_UNINITIALIZED ) {
00181 info->lineno_state = LINENUM_UNAVAILABLE;
00182 if ( gdata->lineno_in_traces ) {
00183 if ( pkey->location >= 0 && !isMethodNative(pkey->method) ) {
00184 lineno = getLineNumber(pkey->method, pkey->location);
00185 if ( lineno >= 0 ) {
00186 info->lineno = (unsigned short)lineno;
00187 info->lineno_state = LINENUM_AVAILABLE;
00188 }
00189 }
00190 }
00191 }
00192 if ( info->lineno_state == LINENUM_UNAVAILABLE ) {
00193 lineno = -1;
00194 }
00195 *plineno = lineno;
00196 *pserial_num = info->serial_num;
00197 }
00198
00199 jint
00200 frame_get_status(FrameIndex index)
00201 {
00202 FrameInfo *info;
00203
00204 info = get_info(index);
00205 return (jint)info->status;
00206 }
00207