#include <assert.h>#include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <string.h>#include <limits.h>Go to the source code of this file.
Classes | |
| struct | codestruct |
| struct | trie |
| struct | seq |
Defines | |
| #define | LAST_INSTR 0x102 |
| #define | INSTRCOUNT LAST_INSTR+1 |
| #define | DEF(name, opds) assert(name < INSTRCOUNT); iname[name] = #name + 3; operands[name] = opds |
| #define | MIN(a, b) ((a) < (b) ? (a) : (b)) |
Typedefs | |
| typedef codestruct | codestruct_t |
| typedef trie | trie_t |
| typedef seq | seq_t |
Enumerations | |
| enum | { OP_bkpt = 0x01, OP_throw = 0x03, OP_getsuper = 0x04, OP_setsuper = 0x05, OP_dxns = 0x06, OP_dxnslate = 0x07, OP_kill = 0x08, OP_ifnlt = 0x0C, OP_ifnle = 0x0D, OP_ifngt = 0x0E, OP_ifnge = 0x0F, OP_jump = 0x10, OP_iftrue = 0x11, OP_iffalse = 0x12, OP_ifeq = 0x13, OP_ifne = 0x14, OP_iflt = 0x15, OP_ifle = 0x16, OP_ifgt = 0x17, OP_ifge = 0x18, OP_ifstricteq = 0x19, OP_ifstrictne = 0x1A, OP_lookupswitch = 0x1B, OP_pushwith = 0x1C, OP_popscope = 0x1D, OP_nextname = 0x1E, OP_hasnext = 0x1F, OP_pushnull = 0x20, OP_pushundefined = 0x21, OP_nextvalue = 0x23, OP_pushtrue = 0x26, OP_pushfalse = 0x27, OP_pushnan = 0x28, OP_pop = 0x29, OP_dup = 0x2A, OP_swap = 0x2B, OP_pushstring = 0x2C, OP_pushdouble = 0x2F, OP_pushscope = 0x30, OP_pushnamespace = 0x31, OP_hasnext2 = 0x32, OP_newfunction = 0x40, OP_call = 0x41, OP_construct = 0x42, OP_callmethod = 0x43, OP_callstatic = 0x44, OP_callsuper = 0x45, OP_callproperty = 0x46, OP_returnvoid = 0x47, OP_returnvalue = 0x48, OP_constructsuper = 0x49, OP_constructprop = 0x4A, OP_callproplex = 0x4C, OP_callsupervoid = 0x4E, OP_callpropvoid = 0x4F, OP_applytype = 0x53, OP_newobject = 0x55, OP_newarray = 0x56, OP_newactivation = 0x57, OP_newclass = 0x58, OP_getdescendants = 0x59, OP_newcatch = 0x5A, OP_findpropstrict = 0x5D, OP_findproperty = 0x5E, OP_finddef = 0x5F, OP_getlex = 0x60, OP_setproperty = 0x61, OP_getlocal = 0x62, OP_setlocal = 0x63, OP_getglobalscope = 0x64, OP_getscopeobject = 0x65, OP_getproperty = 0x66, OP_getouterscope = 0x67, OP_initproperty = 0x68, OP_deleteproperty = 0x6A, OP_getslot = 0x6C, OP_setslot = 0x6D, OP_getglobalslot = 0x6E, OP_setglobalslot = 0x6F, OP_convert_s = 0x70, OP_esc_xelem = 0x71, OP_esc_xattr = 0x72, OP_convert_i = 0x73, OP_convert_u = 0x74, OP_convert_d = 0x75, OP_convert_b = 0x76, OP_convert_o = 0x77, OP_checkfilter = 0x78, OP_coerce = 0x80, OP_coerce_b = 0x81, OP_coerce_a = 0x82, OP_coerce_i = 0x83, OP_coerce_d = 0x84, OP_coerce_s = 0x85, OP_astype = 0x86, OP_astypelate = 0x87, OP_coerce_u = 0x88, OP_coerce_o = 0x89, OP_negate = 0x90, OP_increment = 0x91, OP_inclocal = 0x92, OP_decrement = 0x93, OP_declocal = 0x94, OP_typeof = 0x95, OP_not = 0x96, OP_bitnot = 0x97, OP_add = 0xA0, OP_subtract = 0xA1, OP_multiply = 0xA2, OP_divide = 0xA3, OP_modulo = 0xA4, OP_lshift = 0xA5, OP_rshift = 0xA6, OP_urshift = 0xA7, OP_bitand = 0xA8, OP_bitor = 0xA9, OP_bitxor = 0xAA, OP_equals = 0xAB, OP_strictequals = 0xAC, OP_lessthan = 0xAD, OP_lessequals = 0xAE, OP_greaterthan = 0xAF, OP_greaterequals = 0xB0, OP_instanceof = 0xB1, OP_istype = 0xB2, OP_istypelate = 0xB3, OP_in = 0xB4, OP_increment_i = 0xC0, OP_decrement_i = 0xC1, OP_inclocal_i = 0xC2, OP_declocal_i = 0xC3, OP_negate_i = 0xC4, OP_add_i = 0xC5, OP_subtract_i = 0xC6, OP_multiply_i = 0xC7, OP_getlocal0 = 0xD0, OP_getlocal1 = 0xD1, OP_getlocal2 = 0xD2, OP_getlocal3 = 0xD3, OP_setlocal0 = 0xD4, OP_setlocal1 = 0xD5, OP_setlocal2 = 0xD6, OP_setlocal3 = 0xD7, OP_debugline = 0xF0, OP_debugfile = 0xF1, OP_bkptline = 0xF2, OP_ext_pushbits = 0x101, OP_ext_push_doublebits = 0x102 } |
Functions | |
| void | read_code (const char *filename) |
| void | read_samples (const char *filename) |
| void | extract_superwords () |
| int | fail (const char *s,...) |
| int | codestruct_cmp (const void *a, const void *b) |
| int | pc_cmp (const void *a, const void *b) |
| int | seq_cmp (const void *a, const void *b) |
| trie_t * | new_trie_node (unsigned opcode, unsigned opd1, unsigned opd2) |
| unsigned | compute_operands (unsigned opcodes[], unsigned op, unsigned *opd1, unsigned *opd2, int trackeridx, unsigned opd[][10], unsigned next[]) |
| void | descend (trie_t *t, int level) |
| void | emit (int level, unsigned count) |
| void | printseq (int i, int indent) |
| void | printhseq (int i, int level) |
| void * | safemalloc (size_t nbytes) |
| int | main (int argc, char **argv) |
Variables | |
| const char * | progname = "superwordprof" |
| int | verbose = 0 |
| int | flat = 0 |
| int | hierarchical = 1 |
| int | operand_tracking = 0 |
| int | cutoff_count = 100 |
| int | cutoff_length = INT_MAX |
| int | scale = 0 |
| codestruct_t | codestructs [1000] |
| int | wordsize = 4 |
| int | nextcodestruct = 0 |
| trie_t | toplevel [INSTRCOUNT] |
| int | jumps [INSTRCOUNT] |
| int | operands [INSTRCOUNT] |
| const char * | iname [INSTRCOUNT] |
| unsigned | ibuf [1000] |
| unsigned | operand1 [1000] |
| unsigned | operand2 [1000] |
| seq_t | seqs [10000] |
| int | nextseq = 0 |
|
|
Definition at line 298 of file superwordprof.c. |
|
|
Definition at line 297 of file superwordprof.c. Referenced by extract_superwords(), and main(). |
|
|
Definition at line 296 of file superwordprof.c. |
|
|
Definition at line 299 of file superwordprof.c. Referenced by _profileEntryValue(), compute_operands(), and profileValue(). |
|
|
Definition at line 117 of file superwordprof.c. |
|
|
Definition at line 135 of file superwordprof.c. |
|
|
Definition at line 125 of file superwordprof.c. |
|
|
Definition at line 145 of file superwordprof.c. 00145 { 00146 OP_bkpt=0x01, 00147 OP_throw=0x03, 00148 OP_getsuper=0x04, 00149 OP_setsuper=0x05, 00150 OP_dxns=0x06, 00151 OP_dxnslate=0x07, 00152 OP_kill=0x08, 00153 OP_ifnlt=0x0C, 00154 OP_ifnle=0x0D, 00155 OP_ifngt=0x0E, 00156 OP_ifnge=0x0F, 00157 OP_jump=0x10, 00158 OP_iftrue=0x11, 00159 OP_iffalse=0x12, 00160 OP_ifeq=0x13, 00161 OP_ifne=0x14, 00162 OP_iflt=0x15, 00163 OP_ifle=0x16, 00164 OP_ifgt=0x17, 00165 OP_ifge=0x18, 00166 OP_ifstricteq=0x19, 00167 OP_ifstrictne=0x1A, 00168 OP_lookupswitch=0x1B, 00169 OP_pushwith=0x1C, 00170 OP_popscope=0x1D, 00171 OP_nextname=0x1E, 00172 OP_hasnext=0x1F, 00173 OP_pushnull=0x20, 00174 OP_pushundefined=0x21, 00175 OP_nextvalue=0x23, 00176 OP_pushtrue=0x26, 00177 OP_pushfalse=0x27, 00178 OP_pushnan=0x28, 00179 OP_pop=0x29, 00180 OP_dup=0x2A, 00181 OP_swap=0x2B, 00182 OP_pushstring=0x2C, 00183 OP_pushdouble=0x2F, 00184 OP_pushscope=0x30, 00185 OP_pushnamespace=0x31, 00186 OP_hasnext2=0x32, 00187 OP_newfunction=0x40, 00188 OP_call=0x41, 00189 OP_construct=0x42, 00190 OP_callmethod=0x43, 00191 OP_callstatic=0x44, 00192 OP_callsuper=0x45, 00193 OP_callproperty=0x46, 00194 OP_returnvoid=0x47, 00195 OP_returnvalue=0x48, 00196 OP_constructsuper=0x49, 00197 OP_constructprop=0x4A, 00198 OP_callproplex=0x4C, 00199 OP_callsupervoid=0x4E, 00200 OP_callpropvoid=0x4F, 00201 OP_applytype=0x53, 00202 OP_newobject=0x55, 00203 OP_newarray=0x56, 00204 OP_newactivation=0x57, 00205 OP_newclass=0x58, 00206 OP_getdescendants=0x59, 00207 OP_newcatch=0x5A, 00208 OP_findpropstrict=0x5D, 00209 OP_findproperty=0x5E, 00210 OP_finddef=0x5F, 00211 OP_getlex=0x60, 00212 OP_setproperty=0x61, 00213 OP_getlocal=0x62, 00214 OP_setlocal=0x63, 00215 OP_getglobalscope=0x64, 00216 OP_getscopeobject=0x65, 00217 OP_getproperty=0x66, 00218 OP_getouterscope=0x67, 00219 OP_initproperty=0x68, 00220 OP_deleteproperty=0x6A, 00221 OP_getslot=0x6C, 00222 OP_setslot=0x6D, 00223 OP_getglobalslot=0x6E, 00224 OP_setglobalslot=0x6F, 00225 OP_convert_s=0x70, 00226 OP_esc_xelem=0x71, 00227 OP_esc_xattr=0x72, 00228 OP_convert_i=0x73, 00229 OP_convert_u=0x74, 00230 OP_convert_d=0x75, 00231 OP_convert_b=0x76, 00232 OP_convert_o=0x77, 00233 OP_checkfilter=0x78, 00234 OP_coerce=0x80, 00235 OP_coerce_b=0x81, 00236 OP_coerce_a=0x82, 00237 OP_coerce_i=0x83, 00238 OP_coerce_d=0x84, 00239 OP_coerce_s=0x85, 00240 OP_astype=0x86, 00241 OP_astypelate=0x87, 00242 OP_coerce_u=0x88, 00243 OP_coerce_o=0x89, 00244 OP_negate=0x90, 00245 OP_increment=0x91, 00246 OP_inclocal=0x92, 00247 OP_decrement=0x93, 00248 OP_declocal=0x94, 00249 OP_typeof=0x95, 00250 OP_not=0x96, 00251 OP_bitnot=0x97, 00252 OP_add=0xA0, 00253 OP_subtract=0xA1, 00254 OP_multiply=0xA2, 00255 OP_divide=0xA3, 00256 OP_modulo=0xA4, 00257 OP_lshift=0xA5, 00258 OP_rshift=0xA6, 00259 OP_urshift=0xA7, 00260 OP_bitand=0xA8, 00261 OP_bitor=0xA9, 00262 OP_bitxor=0xAA, 00263 OP_equals=0xAB, 00264 OP_strictequals=0xAC, 00265 OP_lessthan=0xAD, 00266 OP_lessequals=0xAE, 00267 OP_greaterthan=0xAF, 00268 OP_greaterequals=0xB0, 00269 OP_instanceof=0xB1, 00270 OP_istype=0xB2, 00271 OP_istypelate=0xB3, 00272 OP_in=0xB4, 00273 OP_increment_i=0xC0, 00274 OP_decrement_i=0xC1, 00275 OP_inclocal_i=0xC2, 00276 OP_declocal_i=0xC3, 00277 OP_negate_i=0xC4, 00278 OP_add_i=0xC5, 00279 OP_subtract_i=0xC6, 00280 OP_multiply_i=0xC7, 00281 OP_getlocal0=0xD0, 00282 OP_getlocal1=0xD1, 00283 OP_getlocal2=0xD2, 00284 OP_getlocal3=0xD3, 00285 OP_setlocal0=0xD4, 00286 OP_setlocal1=0xD5, 00287 OP_setlocal2=0xD6, 00288 OP_setlocal3=0xD7, 00289 OP_debugline=0xF0, 00290 OP_debugfile=0xF1, 00291 OP_bkptline=0xF2, 00292 OP_ext_pushbits=0x101, 00293 OP_ext_push_doublebits=0x102 00294 };
|
|
||||||||||||
|
Definition at line 1112 of file superwordprof.c. 01113 { 01114 if (a == b) 01115 return 0; 01116 if (((codestruct_t*)a)->start < ((codestruct_t*)b)->start) 01117 return -1; 01118 return 1; 01119 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 885 of file superwordprof.c. 00886 { 00887 int n; 00888 unsigned *p[2]; 00889 p[0] = opd1; 00890 p[1] = opd2; 00891 unsigned **q = p; 00892 *opd1 = *opd2 = 0; 00893 00894 for ( n=operands[code[codeidx++]] ; n > 0 ; n-- ) { 00895 unsigned x = code[codeidx++]; 00896 unsigned symbol = 0; 00897 unsigned i; 00898 unsigned limit=MIN(next_symbol[trackeridx],10); 00899 for ( i=0 ; i < limit ; i++ ) { 00900 if (operand_value[trackeridx][i] == x) { 00901 symbol = i+1; 00902 break; 00903 } 00904 } 00905 if (symbol == 0) { 00906 unsigned value_index = next_symbol[trackeridx]++; 00907 if (value_index < 10) 00908 operand_value[trackeridx][value_index] = x; 00909 symbol = value_index + 1; 00910 } 00911 assert(symbol != 0); 00912 **q++ = symbol; 00913 } 00914 00915 return codeidx; 00916 }
|
|
||||||||||||
|
Definition at line 1040 of file superwordprof.c. References trie::count, emit(), ibuf, trie::left_child, NULL, trie::opcode, trie::opd1, trie::opd2, operand1, operand2, and trie::right_sibling. Referenced by extract_superwords(). 01041 { 01042 trie_t *t2, *t3; 01043 01044 for ( t2=t ; t2 != NULL ; t2 = t2->right_sibling) { 01045 int emitted = 0; 01046 01047 ibuf[level] = t2->opcode; 01048 operand1[level] = t2->opd1; 01049 operand2[level] = t2->opd2; 01050 01051 if (t2->left_child == NULL) { 01052 emit(level+1, t2->count); 01053 continue; 01054 } 01055 01056 for ( t3=t2->left_child ; t3 != NULL ; t3 = t3->right_sibling ) { 01057 if (t3->count < t2->count && !emitted) { 01058 emitted = 1; 01059 emit(level+1, t2->count); 01060 } 01061 } 01062 01063 descend(t2->left_child, level+1); 01064 } 01065 }
|
|
||||||||||||
|
Definition at line 1067 of file superwordprof.c. References seq::count, cutoff_count, runtests::fail(), ibuf, seq::length, NULL, seq::opcode, operand1, seq::operand1, operand2, seq::operand2, operand_tracking, safemalloc(), scale, seqs, and seq::suffix. Referenced by descend(). 01068 { 01069 if (level > 1 && level <= cutoff_length && count/scale >= cutoff_count) { 01070 nextseq < sizeof(seqs)/sizeof(seq_t) || fail("Out of seq memory."); 01071 seq_t *seq = &seqs[nextseq++]; 01072 seq->opcode = (unsigned*) safemalloc(sizeof(unsigned) * level); 01073 memcpy(seq->opcode, ibuf, level*sizeof(unsigned)); 01074 if (operand_tracking) { 01075 seq->operand1 = (unsigned*) safemalloc(sizeof(unsigned) * level); 01076 memcpy(seq->operand1, operand1, level*sizeof(unsigned)); 01077 seq->operand2 = (unsigned*) safemalloc(sizeof(unsigned) * level); 01078 memcpy(seq->operand2, operand2, level*sizeof(unsigned)); 01079 } 01080 else { 01081 seq->operand1 = NULL; 01082 seq->operand2 = NULL; 01083 } 01084 seq->count = count/scale; 01085 seq->length = level; 01086 seq->suffix = 0; 01087 } 01088 }
|
|
|
Definition at line 931 of file superwordprof.c. References seq::count, descend(), INSTRCOUNT, length, nextseq, seq::opcode, seq_cmp(), seqs, suffix, and toplevel. 00932 { 00933 int i, j, ki, kj; 00934 00935 for ( i=0 ; i < INSTRCOUNT ; i++ ) 00936 descend(&toplevel[i], 0); 00937 00938 qsort(seqs, nextseq, sizeof(seq_t), seq_cmp); 00939 00940 for ( i=0 ; i < nextseq ; i++ ) { 00941 for ( j=i+1 ; j < nextseq && seqs[i].count == seqs[j].count ; j++ ) { 00942 if (seqs[j].length < seqs[i].length) { 00943 for ( ki=seqs[i].length-1, kj=seqs[j].length-1 ; kj >= 0 && seqs[i].opcode[ki] == seqs[j].opcode[kj] ; ki--, kj-- ) 00944 ; 00945 if (kj < 0) 00946 seqs[j].suffix = 1; 00947 } 00948 } 00949 } 00950 00951 /* Remove suffix sequences */ 00952 j=0; 00953 for ( i=0 ; i < nextseq ; i++ ) 00954 if (!seqs[i].suffix) 00955 seqs[j++] = seqs[i]; 00956 nextseq = j; 00957 00958 /* Flat */ 00959 00960 if (flat) 00961 for ( i=0 ; i < nextseq ; i++ ) 00962 printseq(i, 0); 00963 00964 00965 /* Hierarchical. Every sequence that is a proper prefix of 00966 another sequence will necessarily have a higher execution 00967 count, and will be printed with the longer sequence as a 00968 child. 00969 00970 Note this messes with the suffix flag. 00971 */ 00972 00973 if (hierarchical) { 00974 if (flat) 00975 printf("\n\n----------\n\n"); 00976 for ( i=0 ; i < nextseq ; i++ ) { 00977 if (!seqs[i].suffix) { 00978 printseq(i, 0); 00979 printhseq(i, 1); 00980 } 00981 } 00982 } 00983 }
|
|
||||||||||||
|
Definition at line 1138 of file superwordprof.c. References runtests::args, and progname. 01139 { 01140 va_list args; 01141 01142 fprintf(stderr, "%s: ", progname); 01143 va_start(args, s); 01144 vfprintf(stderr, s, args); 01145 va_end(args); 01146 fprintf(stderr, "\n"); 01147 exit(1); 01148 return 0; 01149 }
|
|
||||||||||||
|
Definition at line 337 of file superwordprof.c. References trie::count, util::threadpool::i, iname, INSTRCOUNT, jumps, trie::left_child, NULL, operands, trie::right_sibling, and toplevel. 00338 { 00339 int i; 00340 00341 for ( i=0 ; i < INSTRCOUNT ; i++ ) { 00342 toplevel[i].opcode = i; 00343 toplevel[i].count = 0; 00344 toplevel[i].left_child = NULL; 00345 toplevel[i].right_sibling = NULL; 00346 jumps[i] = 0; 00347 operands[i] = 0; 00348 iname[i] = "***"; 00349 } 00350 jumps[OP_throw] = 1; 00351 jumps[OP_ifnlt] = 1; 00352 jumps[OP_ifnle] = 1; 00353 jumps[OP_ifngt] = 1; 00354 jumps[OP_ifnge] = 1; 00355 jumps[OP_jump] = 1; 00356 jumps[OP_iftrue] = 1; 00357 jumps[OP_iffalse] = 1; 00358 jumps[OP_ifeq] = 1; 00359 jumps[OP_ifne] = 1; 00360 jumps[OP_iflt] = 1; 00361 jumps[OP_ifle] = 1; 00362 jumps[OP_ifgt] = 1; 00363 jumps[OP_ifge] = 1; 00364 jumps[OP_ifstricteq] = 1; 00365 jumps[OP_ifstrictne] = 1; 00366 jumps[OP_lookupswitch] = 1; 00367 jumps[OP_returnvoid] = 1; 00368 jumps[OP_returnvalue] = 1; 00369 00370 /* The operand count here is not important for correctness. 0 is 00371 * always a safe answer, and a too high number will result in an 00372 * out-of-bounds reference only occasionally :-P 00373 * 00374 * Getting the operand count right makes for better analysis, 00375 * though. 00376 */ 00377 DEF(OP_bkpt, 0); 00378 DEF(OP_throw, 0); 00379 DEF(OP_getsuper, 1); 00380 DEF(OP_setsuper, 1); 00381 DEF(OP_dxns, 1); 00382 DEF(OP_dxnslate, 0); 00383 DEF(OP_kill, 1); 00384 DEF(OP_ifnlt, 1); 00385 DEF(OP_ifnle, 1); 00386 DEF(OP_ifngt, 1); 00387 DEF(OP_ifnge, 1); 00388 DEF(OP_jump, 1); 00389 DEF(OP_iftrue, 1); 00390 DEF(OP_iffalse, 1); 00391 DEF(OP_ifeq, 1); 00392 DEF(OP_ifne, 1); 00393 DEF(OP_iflt, 1); 00394 DEF(OP_ifle, 1); 00395 DEF(OP_ifgt, 1); 00396 DEF(OP_ifge, 1); 00397 DEF(OP_ifstricteq, 1); 00398 DEF(OP_ifstrictne, 1); 00399 DEF(OP_lookupswitch, 2); 00400 DEF(OP_pushwith, 0); 00401 DEF(OP_popscope, 0); 00402 DEF(OP_nextname, 0); 00403 DEF(OP_hasnext, 0); 00404 DEF(OP_pushnull, 0); 00405 DEF(OP_pushundefined, 0); 00406 DEF(OP_nextvalue, 0); 00407 DEF(OP_pushtrue, 0); 00408 DEF(OP_pushfalse, 0); 00409 DEF(OP_pushnan, 0); 00410 DEF(OP_pop, 0); 00411 DEF(OP_dup, 0); 00412 DEF(OP_swap, 0); 00413 DEF(OP_pushstring, 1); 00414 DEF(OP_pushdouble, 1); 00415 DEF(OP_pushscope, 0); 00416 DEF(OP_pushnamespace, 1); 00417 DEF(OP_hasnext2, 2); 00418 DEF(OP_newfunction, 1); 00419 DEF(OP_call, 1); 00420 DEF(OP_construct, 1); 00421 DEF(OP_callmethod, 2); 00422 DEF(OP_callstatic, 2); 00423 DEF(OP_callsuper, 2); 00424 DEF(OP_callproperty, 2); 00425 DEF(OP_returnvoid, 0); 00426 DEF(OP_returnvalue, 0); 00427 DEF(OP_constructsuper, 1); 00428 DEF(OP_constructprop, 1); 00429 DEF(OP_callproplex, 1); 00430 DEF(OP_callsupervoid, 2); 00431 DEF(OP_callpropvoid, 2); 00432 DEF(OP_applytype, 1); 00433 DEF(OP_newobject, 1); 00434 DEF(OP_newarray, 1); 00435 DEF(OP_newactivation, 0); 00436 DEF(OP_newclass, 1); 00437 DEF(OP_getdescendants, 1); 00438 DEF(OP_newcatch, 1); 00439 DEF(OP_findpropstrict, 1); 00440 DEF(OP_findproperty, 1); 00441 DEF(OP_finddef, 1); 00442 DEF(OP_getlex, 1); 00443 DEF(OP_setproperty, 1); 00444 DEF(OP_getlocal, 1); 00445 DEF(OP_setlocal, 1); 00446 DEF(OP_getglobalscope, 0); 00447 DEF(OP_getscopeobject, 1); 00448 DEF(OP_getproperty, 1); 00449 DEF(OP_getouterscope, 1); 00450 DEF(OP_initproperty, 1); 00451 DEF(OP_deleteproperty, 1); 00452 DEF(OP_getslot, 1); 00453 DEF(OP_setslot, 1); 00454 DEF(OP_getglobalslot, 1); 00455 DEF(OP_setglobalslot, 1); 00456 DEF(OP_convert_s, 0); 00457 DEF(OP_esc_xelem, 0); 00458 DEF(OP_esc_xattr, 0); 00459 DEF(OP_convert_i, 0); 00460 DEF(OP_convert_u, 0); 00461 DEF(OP_convert_d, 0); 00462 DEF(OP_convert_b, 0); 00463 DEF(OP_convert_o, 0); 00464 DEF(OP_checkfilter, 0); 00465 DEF(OP_coerce, 1); 00466 DEF(OP_coerce_b, 0); 00467 DEF(OP_coerce_a, 0); 00468 DEF(OP_coerce_i, 0); 00469 DEF(OP_coerce_d, 0); 00470 DEF(OP_coerce_s, 0); 00471 DEF(OP_astype, 1); 00472 DEF(OP_astypelate, 0); 00473 DEF(OP_coerce_u, 0); 00474 DEF(OP_coerce_o, 0); 00475 DEF(OP_negate, 0); 00476 DEF(OP_increment, 0); 00477 DEF(OP_inclocal, 1); 00478 DEF(OP_decrement, 0); 00479 DEF(OP_declocal, 1); 00480 DEF(OP_typeof, 0); 00481 DEF(OP_not, 0); 00482 DEF(OP_bitnot, 0); 00483 DEF(OP_add, 0); 00484 DEF(OP_subtract, 0); 00485 DEF(OP_multiply, 0); 00486 DEF(OP_divide, 0); 00487 DEF(OP_modulo, 0); 00488 DEF(OP_lshift, 0); 00489 DEF(OP_rshift, 0); 00490 DEF(OP_urshift, 0); 00491 DEF(OP_bitand, 0); 00492 DEF(OP_bitor, 0); 00493 DEF(OP_bitxor, 0); 00494 DEF(OP_equals, 0); 00495 DEF(OP_strictequals, 0); 00496 DEF(OP_lessthan, 0); 00497 DEF(OP_lessequals, 0); 00498 DEF(OP_greaterthan, 0); 00499 DEF(OP_greaterequals, 0); 00500 DEF(OP_instanceof, 0); 00501 DEF(OP_istype, 1); 00502 DEF(OP_istypelate, 0); 00503 DEF(OP_in, 0); 00504 DEF(OP_increment_i, 0); 00505 DEF(OP_decrement_i, 0); 00506 DEF(OP_inclocal_i, 1); 00507 DEF(OP_declocal_i, 1); 00508 DEF(OP_negate_i, 0); 00509 DEF(OP_add_i, 0); 00510 DEF(OP_subtract_i, 0); 00511 DEF(OP_multiply_i, 0); 00512 DEF(OP_getlocal0, 0); 00513 DEF(OP_getlocal1, 0); 00514 DEF(OP_getlocal2, 0); 00515 DEF(OP_getlocal3, 0); 00516 DEF(OP_setlocal0, 0); 00517 DEF(OP_setlocal1, 0); 00518 DEF(OP_setlocal2, 0); 00519 DEF(OP_setlocal3, 0); 00520 DEF(OP_debugline, 1); 00521 DEF(OP_debugfile, 1); 00522 DEF(OP_bkptline, 1); 00523 DEF(OP_ext_pushbits, 1); 00524 DEF(OP_ext_push_doublebits, 2); 00525 00526 progname = argv[0]; 00527 00528 i=1; 00529 while (i < argc && argv[i][0] == '-') { 00530 if (strcmp(argv[i], "-c") == 0) { 00531 if (i+1 == argc || sscanf(argv[i+1], "%d", &cutoff_count) != 1) { 00532 i=argc; 00533 break; 00534 } 00535 i += 2; 00536 } 00537 else if (strcmp(argv[i], "-l") == 0) { 00538 if (i+1 == argc || sscanf(argv[i+1], "%d", &cutoff_length) != 1) { 00539 i=argc; 00540 break; 00541 } 00542 i += 2; 00543 } 00544 else if (strcmp(argv[i], "-f") == 0) { 00545 flat = 1; 00546 i++; 00547 } 00548 else if (strcmp(argv[i], "-h") == 0) { 00549 hierarchical = 0; 00550 i++; 00551 } 00552 else if (strcmp(argv[i], "-o") == 0) { 00553 operand_tracking = 1; 00554 i++; 00555 } 00556 else if (strcmp(argv[i], "-v") == 0) { 00557 verbose = 1; 00558 i++; 00559 } 00560 else { 00561 i = argc; 00562 break; 00563 } 00564 } 00565 00566 if (i > argc-2 || (argc - i) % 2 != 0) { 00567 fprintf(stderr, "Usage: %s [options] ( code_file sample_file ) ... \n\n", progname); 00568 fprintf(stderr, "Options:\n"); 00569 fprintf(stderr, " -c n Set sample cutoff = n (default 100)\n"); 00570 fprintf(stderr, " -l n Set length cutoff = n (default unbounded)\n"); 00571 fprintf(stderr, " -f Enable flat report\n"); 00572 fprintf(stderr, " -h Disable hierarchical report\n"); 00573 fprintf(stderr, " -o Operand tracking\n"); 00574 fprintf(stderr, " -v Verbose"); 00575 return 1; 00576 } 00577 00578 while (i < argc) { 00579 read_code(argv[i]); 00580 read_samples(argv[i+1]); 00581 i += 2; 00582 scale++; 00583 } 00584 extract_superwords(); 00585 00586 return 0; 00587 }
|
|
||||||||||||||||
|
Definition at line 1090 of file superwordprof.c. References trie::count, runtests::fail(), trie::left_child, NULL, trie::opcode, trie::opd1, trie::opd2, and trie::right_sibling. 01091 { 01092 trie_t* t2 = (trie_t*)malloc(sizeof(trie_t)); 01093 t2 != NULL || fail("allocation failure: trie_t"); 01094 t2->opcode = opcode; 01095 t2->opd1 = opd1; 01096 t2->opd2 = opd2; 01097 t2->count = 1; 01098 t2->left_child = NULL; 01099 t2->right_sibling = NULL; 01100 return t2; 01101 }
|
|
||||||||||||
|
Definition at line 1121 of file superwordprof.c. References codestruct::start. 01121 { 01122 unsigned pc = *(unsigned*)a; 01123 codestruct_t* elt = (codestruct_t*)b; 01124 if (pc >= elt->start && pc < elt->limit) 01125 return 0; 01126 if (pc < elt->start) 01127 return -1; 01128 return 1; 01129 }
|
|
||||||||||||
|
Definition at line 985 of file superwordprof.c. References length, seq::length, printseq(), seqs, and seq::suffix. 00986 { 00987 int j, k, l; 00988 00989 l=seqs[i].length; 00990 for ( j=i+1 ; j < nextseq ; j++ ) { 00991 if (seqs[j].suffix || seqs[j].length < l) 00992 goto next_j; 00993 for ( k=0 ; k < l ; k++ ) 00994 if (seqs[i].opcode[k] != seqs[j].opcode[k]) 00995 goto next_j; 00996 printseq(j, level); 00997 seqs[j].suffix = 1; 00998 printhseq(j, level+1); 00999 next_j: 01000 ; 01001 } 01002 }
|
|
||||||||||||
|
Definition at line 1004 of file superwordprof.c. References iname, seq::length, operand1, operand2, operand_tracking, and seqs. Referenced by printhseq(). 01005 { 01006 int j; 01007 01008 printf("%11d | ", seqs[i].count); 01009 for ( j=0 ; j < indent ; j++ ) 01010 printf(" "); 01011 if (operand_tracking) { 01012 for ( j=0 ; j < seqs[i].length ; j++ ) { 01013 printf("%s", iname[seqs[i].opcode[j]]); 01014 if (seqs[i].operand1[j] != 0) { 01015 printf("[%d", seqs[i].operand1[j]); 01016 if (seqs[i].operand2[j] != 0) 01017 printf(",%d", seqs[i].operand2[j]); 01018 printf("] "); 01019 } 01020 else 01021 printf(" "); 01022 } 01023 } 01024 else { 01025 for ( j=0 ; j < seqs[i].length ; j++ ) 01026 printf("%s ", iname[seqs[i].opcode[j]]); 01027 } 01028 printf("| "); 01029 for ( j=0 ; j < seqs[i].length ; j++ ) 01030 printf("%x ", seqs[i].opcode[j]); 01031 printf("\n"); 01032 }
|
|
|
Definition at line 591 of file superwordprof.c. References codestruct::code, codestructs, runtests::fail(), codestruct::limit, nextcodestruct, NULL, runtests::res, safemalloc(), codestruct::start, build::calcdepends::verbose, and wordsize. 00592 { 00593 FILE *code_fp; 00594 unsigned total_wordcount, numcodes, signature; 00595 codestruct_t *codestruct; 00596 00597 (code_fp = fopen(filename, "rb")) != NULL || fail("No such file: %s", filename); 00598 if (verbose) 00599 fprintf(stderr, "%s\n", filename); 00600 00601 nextcodestruct = 0; /* Don't bother deallocating data from previous code file */ 00602 total_wordcount = 0; 00603 numcodes = 0; 00604 fread(&signature, sizeof(unsigned), 1, code_fp) == 1 || fail("No code signature"); 00605 signature == 0xC0DEC0DE || fail("Bad code signature: %08x", signature); 00606 for (;;) { 00607 unsigned start, limit, wordcount; 00608 unsigned *codebuf; 00609 int res; 00610 00611 if (fread(&start, sizeof(unsigned), 1, code_fp) != 1) 00612 break; 00613 fread(&limit, sizeof(unsigned), 1, code_fp) || fail("Could not read end"); 00614 wordcount = (limit - start) / wordsize; 00615 total_wordcount += wordcount; 00616 codebuf = (unsigned*)safemalloc(wordcount * sizeof(unsigned)); 00617 (res = fread(codebuf, sizeof(unsigned), wordcount, code_fp)) == wordcount || fail("Could not read code vector: %08x %08x %d (%d) %d", start, limit, wordcount, numcodes, res); 00618 nextcodestruct < sizeof(codestructs)/sizeof(codestruct_t) || fail("Out of codestruct memory: %d", nextcodestruct); 00619 codestruct = &codestructs[nextcodestruct++]; 00620 codestruct->code = codebuf; 00621 codestruct->start = start; 00622 codestruct->limit = limit; 00623 numcodes++; 00624 } 00625 00626 fclose(code_fp); 00627 00628 qsort(codestructs, nextcodestruct, sizeof(codestruct_t), codestruct_cmp); 00629 00630 if (verbose) { 00631 fprintf(stderr, "Number of code structs: %d\n", nextcodestruct); 00632 fprintf(stderr, "Words of code: %d\n", total_wordcount); 00633 } 00634 }
|
|
|
Definition at line 644 of file superwordprof.c. References runtests::fail(), NULL, op, runtests::res, and build::calcdepends::verbose. 00645 { 00646 static unsigned bigbuf[1000000]; 00647 FILE *sample_fp; 00648 unsigned total_samples, signature, prev_pc; 00649 codestruct_t *prev_codestruct; 00650 trie_t* tracker[1000]; 00651 unsigned operand_value[1000][10]; /* Up to 10 distinct operand values per tracker. We use offset 0..9 + 1; 0 means "no information" */ 00652 unsigned next_symbol[1000]; /* Next symbol (= operand slot, if below 10) */ 00653 int nexttracker; 00654 int trie_nodes = 0; 00655 int bigbuflim = 0; 00656 int bigbufptr = 0; 00657 int despecializations = 0; 00658 00659 if (verbose) 00660 fprintf(stderr, "%s\n", filename); 00661 (sample_fp = fopen(filename, "rb")) != NULL || fail("No such file: %s", filename); 00662 00663 fread(&signature, sizeof(unsigned), 1, sample_fp) == 1 || fail("No sample signature"); 00664 signature == 0xDA1ADA1A || fail("Bad sample signature: %08x", signature); 00665 00666 total_samples = 0; 00667 prev_codestruct = NULL; 00668 prev_pc = 0; 00669 nexttracker = 0; 00670 for (;;) { 00671 unsigned pc, opcode, ops, op, opcodes[10]; 00672 codestruct_t *codestruct; 00673 00674 if (bigbufptr == bigbuflim) { 00675 int res; 00676 res = fread(bigbuf, sizeof(unsigned), sizeof(bigbuf)/sizeof(bigbuf[0]), sample_fp); 00677 if (res <= 0) 00678 break; 00679 bigbufptr = 0; 00680 bigbuflim = res; 00681 } 00682 pc = bigbuf[bigbufptr++]; 00683 total_samples++; 00684 codestruct = (codestruct_t*)bsearch(&pc, codestructs, nextcodestruct, sizeof(codestruct_t), pc_cmp); 00685 codestruct != NULL || fail("Could not find pc=%08x anywhere in code memory.", pc); 00686 opcode = codestruct->code[(pc - codestruct->start)/wordsize]; 00687 if (opcode > 255) 00688 opcode = 256 + (opcode >> 8); 00689 00690 /* Despecialize. We can do it in the interpreter or here; 00691 * doing it here is simpler for the moment, provided we don't 00692 * have to adjust branch targets and so on. Despecialization 00693 * merely inserts opcodes into a buffer, across which we then 00694 * iterate; in the degenerate case, the single opcode is not 00695 * despecialized and is just inserted into the buffer alone. 00696 * 00697 * Right now there's no need to handle argument values. 00698 * 00699 * Open questions (likely answers are always "no"): 00700 * - Should we despecialize IFFALSE as NOT; IFTRUE? 00701 * - Should increment and decrement be despecialized as PUSHINT 1; ADD? 00702 * - Should inclocal and declocal be despecialized by breaking 00703 * it into GETLOCAL; INCREMENT; SETLOCAL? 00704 */ 00705 ops = 0; 00706 switch (opcode) { 00707 default: { 00708 int n = operands[opcode]; 00709 opcodes[ops++] = opcode; 00710 if (n > 0) { n--; opcodes[ops++] = codestruct->code[(pc - codestruct->start)/wordsize + 1]; } 00711 if (n > 0) { n--; opcodes[ops++] = codestruct->code[(pc - codestruct->start)/wordsize + 2]; } 00712 assert(n == 0); 00713 break; 00714 } 00715 case OP_getlocal0: 00716 case OP_getlocal1: 00717 case OP_getlocal2: 00718 case OP_getlocal3: 00719 opcodes[ops++] = OP_getlocal; 00720 opcodes[ops++] = OP_getlocal - opcode; 00721 break; 00722 case OP_setlocal0: 00723 case OP_setlocal1: 00724 case OP_setlocal2: 00725 case OP_setlocal3: 00726 opcodes[ops++] = OP_setlocal; 00727 opcodes[ops++] = OP_setlocal - opcode; 00728 break; 00729 case OP_iflt: 00730 opcodes[ops++] = OP_lessthan; 00731 opcodes[ops++] = OP_iftrue; 00732 opcodes[ops++] = 0; 00733 break; 00734 case OP_ifle: 00735 opcodes[ops++] = OP_lessequals; 00736 opcodes[ops++] = OP_iftrue; 00737 opcodes[ops++] = 0; 00738 break; 00739 case OP_ifnlt: 00740 opcodes[ops++] = OP_lessthan; 00741 opcodes[ops++] = OP_iffalse; 00742 opcodes[ops++] = 0; 00743 break; 00744 case OP_ifnle: 00745 opcodes[ops++] = OP_lessequals; 00746 opcodes[ops++] = OP_iffalse; 00747 opcodes[ops++] = 0; 00748 break; 00749 case OP_ifgt: 00750 opcodes[ops++] = OP_greaterthan; 00751 opcodes[ops++] = OP_iftrue; 00752 opcodes[ops++] = 0; 00753 break; 00754 case OP_ifge: 00755 opcodes[ops++] = OP_greaterequals; 00756 opcodes[ops++] = OP_iftrue; 00757 opcodes[ops++] = 0; 00758 break; 00759 case OP_ifngt: 00760 opcodes[ops++] = OP_greaterthan; 00761 opcodes[ops++] = OP_iffalse; 00762 opcodes[ops++] = 0; 00763 break; 00764 case OP_ifnge: 00765 opcodes[ops++] = OP_greaterequals; 00766 opcodes[ops++] = OP_iffalse; 00767 opcodes[ops++] = 0; 00768 break; 00769 case OP_ifeq: 00770 opcodes[ops++] = OP_equals; 00771 opcodes[ops++] = OP_iftrue; 00772 opcodes[ops++] = 0; 00773 break; 00774 case OP_ifstricteq: 00775 opcodes[ops++] = OP_strictequals; 00776 opcodes[ops++] = OP_iftrue; 00777 opcodes[ops++] = 0; 00778 break; 00779 case OP_ifne: 00780 opcodes[ops++] = OP_equals; 00781 opcodes[ops++] = OP_iffalse; 00782 opcodes[ops++] = 0; 00783 break; 00784 case OP_ifstrictne: 00785 opcodes[ops++] = OP_strictequals; 00786 opcodes[ops++] = OP_iffalse; 00787 opcodes[ops++] = 0; 00788 break; 00789 } 00790 00791 if (opcodes[0] != opcode || ops > 1) 00792 despecializations++; 00793 00794 if (prev_codestruct != codestruct) 00795 nexttracker = 0; 00796 00797 op = 0; 00798 while ( op < ops ) { 00799 int i; 00800 opcode = opcodes[op]; 00801 assert( opcode < INSTRCOUNT ); 00802 for ( i=0 ; i < nexttracker ; i++ ) { 00803 trie_t *t = tracker[i]; 00804 unsigned opd1=0, opd2=0; 00805 if (operand_tracking) 00806 compute_operands(opcodes, op, &opd1, &opd2, i, operand_value, next_symbol); 00807 if (t->left_child == NULL) { 00808 t->left_child = new_trie_node(opcode, opd1, opd2); 00809 ++trie_nodes; 00810 tracker[i] = t->left_child; 00811 } 00812 else { 00813 trie_t *t2 = t->left_child; 00814 trie_t *t3 = NULL; 00815 if (operand_tracking) { 00816 while (t2 != NULL && (t2->opcode != opcode || t2->opd1 != opd1 || t2->opd2 != opd2)) 00817 t3 = t2, t2 = t2->right_sibling; 00818 } 00819 else { 00820 while (t2 != NULL && t2->opcode != opcode) 00821 t3 = t2, t2 = t2->right_sibling; 00822 } 00823 if (t2 != NULL) { 00824 /* Move the node to the head of the list in order to keep the 00825 hottest nodes first */ 00826 t2->count++; 00827 if (t3 != NULL) { /* Otherwise it's already at the head of the list */ 00828 t3->right_sibling = t2->right_sibling; 00829 t2->right_sibling = t->left_child; 00830 t->left_child = t2; 00831 } 00832 } 00833 else { 00834 t2 = new_trie_node(opcode, opd1, opd2); 00835 ++trie_nodes; 00836 t2->right_sibling = t->left_child; 00837 t->left_child = t2; 00838 } 00839 tracker[i] = t2; 00840 } 00841 } 00842 nexttracker < sizeof(tracker)/sizeof(tracker[0]) || fail("Out of tracker memory, probably a bug"); 00843 tracker[nexttracker++] = &toplevel[opcode]; 00844 toplevel[opcode].count++; 00845 if (operand_tracking) { 00846 unsigned opd1, opd2; 00847 next_symbol[nexttracker-1] = 0; 00848 compute_operands(opcodes, op, &opd1, &opd2, nexttracker-1, operand_value, next_symbol); 00849 /* Wrong. This breaks down for two-operand instructions at the top level, 00850 * as there may be two variants: op[1,1] and op[1,2]. In almost all cases 00851 * it will be latter, and it is very unlikely that this bug will cause 00852 * actual problems. So ignore it, rather than reengineering it. 00853 */ 00854 toplevel[opcode].opd1 = opd1; 00855 toplevel[opcode].opd2 = opd2; 00856 } 00857 00858 op += operands[opcode] + 1; 00859 00860 if (jumps[opcode]) { 00861 assert(op == ops); 00862 nexttracker = 0; 00863 } 00864 } 00865 prev_codestruct = codestruct; 00866 prev_pc = pc; 00867 } 00868 00869 fclose(sample_fp); 00870 00871 if (verbose) { 00872 fprintf(stderr, "Samples processed: %d\n", total_samples); 00873 fprintf(stderr, "Despecializations: %d\n", despecializations); 00874 fprintf(stderr, "Trie nodes: %d\n", trie_nodes); 00875 } 00876 }
|
|
|
Definition at line 1131 of file superwordprof.c. References runtests::fail(), build::dependparser::m, and NULL. Referenced by emit(), and read_code(). 01132 { 01133 void *m = malloc(nbytes); 01134 m != NULL || fail("Allocation failure: %d", nbytes); 01135 return m; 01136 }
|
|
||||||||||||
|
Definition at line 1103 of file superwordprof.c. References length, and runtests::res. Referenced by extract_superwords(). 01104 { 01105 // descending by count, longest first 01106 int res = ((seq_t*)b)->count - ((seq_t*)a)->count; 01107 if (res != 0) 01108 return res; 01109 return ((seq_t*)b)->length - ((seq_t*)a)->length; 01110 }
|
|
|
Definition at line 309 of file superwordprof.c. Referenced by read_code(). |
|
|
Definition at line 306 of file superwordprof.c. Referenced by emit(). |
|
|
Definition at line 307 of file superwordprof.c. |
|
|
Definition at line 303 of file superwordprof.c. |
|
|
Definition at line 304 of file superwordprof.c. |
|
|
Definition at line 316 of file superwordprof.c. |
|
|
Definition at line 315 of file superwordprof.c. Referenced by main(), and printseq(). |
|
|
Definition at line 313 of file superwordprof.c. Referenced by main(). |
|
|
Definition at line 311 of file superwordprof.c. Referenced by read_code(). |
|
|
Definition at line 320 of file superwordprof.c. Referenced by extract_superwords(). |
|
|
Definition at line 317 of file superwordprof.c. Referenced by descend(), emit(), and printseq(). |
|
|
Definition at line 318 of file superwordprof.c. Referenced by descend(), emit(), and printseq(). |
|
|
Definition at line 305 of file superwordprof.c. Referenced by emit(), and printseq(). |
|
|
Definition at line 314 of file superwordprof.c. Referenced by compute_operands(), and main(). |
|
|
Definition at line 301 of file superwordprof.c. Referenced by fail(). |
|
|
Definition at line 308 of file superwordprof.c. Referenced by emit(). |
|
|
Definition at line 319 of file superwordprof.c. Referenced by emit(), extract_superwords(), printhseq(), and printseq(). |
|
|
|
Definition at line 302 of file superwordprof.c. |
|
|
Definition at line 310 of file superwordprof.c. Referenced by read_code(). |
1.4.6