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 #include <defs.h>
00033 #include <iostream>
00034 #include <fstream>
00035 #include <string.h>
00036 #include <hash_map>
00037 #include <stdlib.h>
00038
00039 #include "inline_script_parser.h"
00040
00041 const char *inline_action_log = "Inline_Action.verify";
00042 const char *inline_script_log = "Inline_Script.verify";
00043
00044 static CALLER_HTABLE inline_spec_table;
00045
00046 static BOOL inline_script_init = FALSE;
00047
00048
00049
00050
00051
00052
00053 void ISP_Fix_Filename(char *name)
00054 {
00055 char *p = strchr(name, '.');
00056 if (p != NULL) *p='\0';
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 static void Parse_inline_script(const char *script_name, MEM_POOL *parser_pool)
00066 {
00067
00068 char line_buffer[1024], *line_iterator;
00069 ifstream infile;
00070 char *callsite_ln, *callee_file, *callee_func;
00071 char cur_caller_key[1024], callee_key[1024], *key_temp;
00072 char *cur_caller_file, *cur_caller_func;
00073 CALLEE_HTABLE *cur_callee_htable;
00074 CALLEE_INFO callee_info;
00075 int outer_nest = 0, inner_nest = 0;
00076
00077 strcpy(cur_caller_key, "");
00078 strcpy(callee_key, "");
00079
00080 infile.open(script_name, ifstream::in);
00081 FmtAssert((infile.good()), ("Inline script parsing error: can't open the inlining description file"));
00082
00083 #ifdef Enable_ISP_Verify
00084 FILE *inline_script = fopen(inline_script_log, "a+");
00085 FmtAssert((inline_script != NULL), ("Inline script parsing error: can't open file"));
00086 #endif
00087
00088
00089
00090 while (infile.good()) {
00091 infile.getline(line_buffer, 1024);
00092 line_iterator = line_buffer;
00093
00094
00095 while (*line_iterator == ' ')
00096 line_iterator++;
00097
00098
00099 if (strncmp(line_iterator, "COMPILE", 7) == 0) {
00100 FmtAssert((outer_nest == 0),
00101 ("Inline script parsing error: nested parentheses don't match"));
00102 outer_nest++;
00103
00104 strtok(line_iterator, "\"");
00105 cur_caller_file = strtok(NULL, "\"");
00106 cur_caller_func = strtok(NULL, ",");
00107
00108 FmtAssert((cur_caller_file != NULL && cur_caller_func != NULL),
00109 ("Inline script parsing error: incorrect input format for caller specification"));
00110
00111 ISP_Fix_Filename(cur_caller_file);
00112 ISP_Fix_Filename(cur_caller_func);
00113 strcat(cur_caller_key, cur_caller_file);
00114 strcat(cur_caller_key, cur_caller_func);
00115
00116
00117 key_temp = TYPE_MEM_POOL_ALLOC_N(char, parser_pool, sizeof(char)*(strlen(cur_caller_key)+1));
00118 strcpy(key_temp, cur_caller_key);
00119 cur_callee_htable = &inline_spec_table[key_temp];
00120
00121 #ifdef ISP_DEBUG
00122 cout << "Inline script parsing info : added caller_key " << cur_caller_key << endl;
00123 #endif
00124 }
00125
00126 else if (strncmp(line_iterator, "INLINE", 6) == 0) {
00127 inner_nest++;
00128
00129 strtok(line_iterator, "(");
00130 callsite_ln = strtok(NULL, ",");
00131 strtok(NULL, "\"");
00132 callee_file = strtok(NULL, "\"");
00133 char *patch_strtok = strtok(NULL, ",");
00134 callee_func = strtok(patch_strtok, ")");
00135
00136 FmtAssert((callsite_ln != NULL && callee_file != NULL && callee_func != NULL),
00137 ("Inline script parsing error: incorrect input format for callee specification"));
00138
00139 ISP_Fix_Filename(callee_file);
00140 ISP_Fix_Filename(callee_func);
00141 strcat(callee_key, callsite_ln);
00142 strcat(callee_key, callee_file);
00143 strcat(callee_key, callee_func);
00144 #ifdef Enable_ISP_Verify
00145 fprintf(inline_script, "[%s] inlined into [%s]\n",
00146 callee_key, cur_caller_key);
00147 #endif
00148 callee_info.attrib = INLINE;
00149 callee_info.nested_inline = NULL;
00150
00151 key_temp = TYPE_MEM_POOL_ALLOC_N(char, parser_pool, sizeof(char)*(strlen(callee_key)+1));
00152 strcpy(key_temp, callee_key);
00153 (*cur_callee_htable)[key_temp] = callee_info;
00154
00155 #ifdef ISP_DEBUG
00156 cout << "Inline script parsing info : added INLINE type callee_key " << callee_key << endl;
00157 #endif
00158 callsite_ln = NULL;
00159 callee_file = NULL;
00160 callee_func = NULL;
00161 strcpy(callee_key, "");
00162 }
00163
00164 else if (*line_iterator == '}') {
00165 if(outer_nest == 1 && inner_nest > 0) {
00166 inner_nest--;
00167 }
00168 else if(outer_nest == 1 && inner_nest == 0) {
00169 outer_nest--;
00170 strcpy(cur_caller_key, "");
00171 }
00172 else {
00173 FmtAssert(0,("Inline script parsing error: nested parentheses don't match"));
00174 }
00175 }
00176
00177 else if (strncmp(line_iterator, "CALL", 4) == 0) {
00178 strtok(line_iterator, "(");
00179 callsite_ln = strtok(NULL, ",");
00180 strtok(NULL, "\"");
00181 callee_file = strtok(NULL, "\"");
00182 char *patch_strtok = strtok(NULL, ",");
00183 callee_func = strtok(patch_strtok, ")");
00184
00185 FmtAssert((callsite_ln != NULL && callee_file != NULL && callee_func != NULL),
00186 ("Inline script parsing error : invalid input format for callee specification"));
00187
00188 ISP_Fix_Filename(callee_file);
00189 ISP_Fix_Filename(callee_func);
00190 strcat(callee_key, callsite_ln);
00191 strcat(callee_key, callee_file);
00192 strcat(callee_key, callee_func);
00193
00194 callee_info.attrib = CALL;
00195 callee_info.nested_inline = NULL;
00196
00197 key_temp = TYPE_MEM_POOL_ALLOC_N(char, parser_pool, sizeof(char)*(strlen(callee_key)+1));
00198 strcpy(key_temp, callee_key);
00199 (*cur_callee_htable)[key_temp] = callee_info;
00200
00201 #ifdef ISP_DEBUG
00202 cout << "Inline script parsing info : added CALL type callee_key " << callee_key << endl;
00203 #endif
00204 callsite_ln = NULL;
00205 callee_file = NULL;
00206 callee_func = NULL;
00207 strcpy(callee_key, "");
00208 }
00209 else {
00210
00211 }
00212 }
00213 #ifdef Enable_ISP_Verify
00214 fclose(inline_script);
00215 #endif
00216 infile.close();
00217 }
00218
00219
00220
00221
00222
00223 BOOL Check_Inline_Script(const char *script_name, const char *caller_key, const char *callee_key, MEM_POOL* parser_pool)
00224 {
00225 #ifdef ISP_DEBUG
00226 cout << "Inline script check info: analyze call-pair (" << caller_key << " --> " << callee_key << ")" << endl;
00227 #endif
00228
00229
00230 if (inline_script_init == FALSE) {
00231 Parse_inline_script (script_name, parser_pool);
00232 inline_script_init = TRUE;
00233 }
00234
00235
00236 if (inline_spec_table.find(caller_key) == inline_spec_table.end()) {
00237 #ifdef ISP_DEBUG
00238 fprintf(stderr, " ...... check failed: caller \"%s\" not found in inline description file %s\n",
00239 caller_key, script_name);
00240 #endif
00241 return FALSE;
00242 } else if ((inline_spec_table[caller_key]).find(callee_key) == (inline_spec_table[caller_key]).end()) {
00243 #ifdef ISP_DEBUG
00244 fprintf(stderr, " ...... check failed: callee \"%s\" not found in inline description file %s\n",
00245 callee_key, script_name);
00246 #endif
00247 return FALSE;
00248 }
00249 else {
00250 if ((inline_spec_table[caller_key])[callee_key].attrib == INLINE) {
00251 (inline_spec_table[caller_key])[callee_key].process_flag += 1;
00252 #ifdef ISP_DEBUG
00253 fprintf(stderr, " ...... check successful: the call-site is inlined\n");
00254 #endif
00255 return TRUE;
00256 }
00257 else {
00258 #ifdef ISP_DEBUG
00259 fprintf(stderr, " ...... check failed: the call-site is not inlined (type = %d)\n",
00260 (inline_spec_table[caller_key])[callee_key].attrib);
00261 #endif
00262 return FALSE;
00263 }
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272 void Verify_Inline_Script(void)
00273 {
00274 CALLER_HTABLE::iterator caller_it;
00275 CALLEE_HTABLE::iterator callee_it;
00276 int total_inline_count = 0;
00277
00278 #ifdef ISP_DEBUG
00279 fprintf(stderr, "### Inline script verify info ### \n");
00280 #endif
00281 #ifdef Enable_ISP_Verify
00282 FILE *inline_action = fopen(inline_action_log, "a+");
00283 FmtAssert((inline_action != NULL), ("Inline script parsing error: can't open file"));
00284 #endif
00285 for(caller_it = inline_spec_table.begin(); caller_it != inline_spec_table.end(); caller_it++) {
00286 for(callee_it = (*caller_it).second.begin(); callee_it != (*caller_it).second.end(); callee_it++) {
00287 if((*callee_it).second.attrib == INLINE)
00288 total_inline_count++;
00289
00290 if( ((*callee_it).second.attrib == INLINE) && ((*callee_it).second.process_flag == 0)) {
00291 #ifdef ISP_DEBUG
00292 fprintf(stderr, " ...... callsite is specified but not processed [%s] --> [%s] \n",
00293 (*caller_it).first, (*callee_it).first);
00294 #endif
00295 #ifdef Enable_ISP_Verify
00296 fprintf(inline_action, "[%s] inlined into [%s]\n",
00297 (*callee_it).first, (*caller_it).first);
00298 #endif
00299 }
00300 #ifdef ISP_DEBUG
00301 else if(((*callee_it).second.attrib == INLINE) && ((*callee_it).second.process_flag > 1))
00302 fprintf(stderr, " ...... callsite was queried %d times [%s] --> [%s] \n",
00303 (*callee_it).second.process_flag, (*caller_it).first, (*callee_it).first);
00304 #endif
00305 }
00306 }
00307 #ifdef Enable_ISP_Verify
00308 fprintf(inline_action, "(The above call-sites are actually not processed!)\n");
00309 fclose(inline_action);
00310 #endif
00311 #ifdef ISP_DEBUG
00312 fprintf(stderr, " ...... The total number of inlined call-sites in the description file is %d \n",
00313 total_inline_count);
00314 #endif
00315 }