#include #include #include #include #include #include "runtime.h" #include "xmem.h" #include "profile.h" #ifdef PROFILE int maxSet = 1; int memberAdr(int keep,char *function,Retainer *rinfo) { int l = 0; int h; if(!rinfo) {fprintf(stderr,"No retainer set\n"); return 1;} if(!rinfo->no) return !keep || rinfo->keep; h = rinfo->no-1; if(rinfo->member[l] == function) return 1; if(rinfo->member[h] == function) return 1; while(l+1member[m] == function) return 1; if(rinfo->member[m] < function) l = m; else h = m; } return 0; } int memberStr(int keep,Restriction *f,Retainer *rinfo) { int i; char *function = f->str; if(!rinfo) {fprintf(stderr,"No retainer set\n"); return 1;} if(!rinfo->no) return !keep || rinfo->keep; for(i=0; ino; i++) { if (!strcmp(rinfo->member[i],function)) { f->address = 1; f->str = rinfo->member[i]; return 1; } } return 0; } int keepFunction(char *function) { Restriction *f = restriction[PROFILE_RETAINER]; if(f) { while(f) { if(f->address) {if(f->str == function) return 1;} else {if(!strcmp(f->str,function)) {f->address = 1; f->str = function; return 1;}} f = f->next; } } else return 1; return 0; } static int helpFilterR(Retainer *retainer) { #if 1 return !retainer || retainer->keep; #else Restriction *f = restriction[PROFILE_RETAINER]; if(f) { while(f) { if(f->address) {if(memberAdr(1,f->str,retainer)) return 1;} else {if(memberStr(1,f,retainer)) return 1;} f = f->next; } } else return 1; return 0; #endif } void saveLastUse(Info *info) { pm_data pm; long offset = info->unique*sizeof(pm_data); pm.lastused = info->binfo.parts.last; pm.dead = year; pm.used = info->binfo.parts.used; if (offset) { /* this node is visible during at least one census */ if(0 != fseek(lastFILE,offset,SEEK_SET)) { fprintf(stderr,"offset == %ld\n",offset); perror("Failed when trying to seek in last"); } if(1 != fwrite(&pm,sizeof(pm_data),1,lastFILE)) perror("Failed when trying to write post-mortem data"); } return; } static int helpFilterB(Info *info) { BInfo binfo = info->binfo; pm_data pm; if(!RestrictionBiography && lifetimeLow == -1 && lifetimeHigh == -1) return 1; if(useUnique && lastAREA) { long offset = info->unique; /* Need to look into the future */ if (offset) { /* this node is visible during at least one census */ if(offset > 0 && offset < lastSIZE) { pm = lastAREA[offset]; } else { fprintf(stderr,"Skipping offset %ld",offset); return 0; } } else { fprintf(stderr,"Found cell without enumeration"); return 0; } if(lifetimeLow > (signed int) (pm.dead-binfo.parts.created)) return 0; if(lifetimeHigh > -1 && lifetimeHigh < (signed int)(pm.dead-binfo.parts.created)) return 0; if(!pm.used) { return (RestrictionBiography & BIO_VOID); } else { if(info->binfo.parts.used) { /* used before this census ? */ if(pm.lastused>year) return (RestrictionBiography & BIO_USE); else return (RestrictionBiography & BIO_DRAG); } else { return (RestrictionBiography & BIO_LAG); } } } return 1; /* Filter in hp2graph instead */ } int dynamicRestrictions(Info *info) { return helpFilterR(info->rinfo) && helpFilterB(info); } /**********************************************************/ Retainer *newRetainer(int hashv, int keep, int no, char **members,Retainer *next) { Retainer *re = xmalloc(sizeof(Retainer)+(no-1)*sizeof(char *)); char **s = &re->member[0]; re->next = next; re->size = 0; re->hashv = hashv; re->keep = keep; re->no = no; while(no--) *s++ = *members++; return re; } /*******************************************/ int identical(int n,char **s1,char **s2) { while(n--) if(*s1++ != *s2++) return 0; return 1; } char *ugly[10]; char *check(char *s) { char *t; if(!s) { fprintf(stderr,"Nullpointer instead of function name\n"); return s; } if(!*s) { fprintf(stderr,"Empty string as function name\n"); return s; } for(t=s; *t; t++) { if(!isprint(*t)) { fprintf(stderr,"Nonprintable character in function name\n"); return s; } } return s; } Retainer *findRetainer(Retainer *rinfo,int keep,char *function) { int hashv = hashInt((Int)function); Retainer *es; int i=0; char **tmp = ugly; check(function); if(rinfo) { if(rinfo->no && rinfo->no+1 <= maxSet) { hashv = rinfo->hashv ^ hashv; if(functionmember[rinfo->no-1]) { while(function>rinfo->member[i]) *tmp++ = rinfo->member[i++]; *tmp++ = function; while(i < rinfo->no) *tmp++ = rinfo->member[i++]; } else { while(i < rinfo->no) *tmp++ = rinfo->member[i++]; *tmp++ = function; } i = rinfo->no+1; keep |= rinfo->keep; } else { if(rinfo->no) /* Extending old set to U */ keep |= rinfo->keep; else /* Old set is U */ if (keep == rinfo->keep) return rinfo; hashv = 1; i = 0; } } else { ugly[0] = function; i = 1; } { int j; for(j=0; jnext) { if(i == es->no && keep == es->keep && identical(i,&es->member[0],ugly)) return es; } es = RetainerTable[hashv] = newRetainer(hashv,keep,i,ugly,RetainerTable[hashv]); return es; } /*******************************************/ void printTableRetainer(FILE *fp) { int i; for(i = 0; inext) { if(rs->size) { if(rs->no) { int j = rs->no; putc('{',fp); while(j--) { fprintf(fp,"%s",rs->member[j]); if(j) putc(',',fp); } putc('}',fp); } else fprintf(fp," U "); fprintf(fp,"\t%d\n",rs->size); } } } } #endif