Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

PickleStats.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // File: Pickle.C
00020 // Last modified on Wed Apr 27 10:52:31 EDT 2005 by irina.furman@intel.com
00021 //      modified on Fri Aug  6 17:21:24 EDT 2004 by ken@xorian.net
00022 //      modified on Sat Mar 14 11:04:36 PST 1998 by yuanyu
00023 //      modified on Tue Feb 27 15:47:00 PST 1996 by levin
00024 
00025 #include "PickleStats.H"
00026 #include <FP.H>
00027 #include <CacheC.H>
00028 #include <VestaSource.H>
00029 
00030 using std::ios;
00031 using std::streampos;
00032 using std::istream;
00033 using std::ifstream;
00034 using std::cout;
00035 using std::cin;
00036 using std::cerr;
00037 using std::endl;
00038 
00039 static int pickleDpndSize = 0;
00040 static int bangFPNum = 0;
00041 static int typeFPNum = 0;
00042 static int pickleSize = 0;
00043 static int depFPNum = 0;
00044 static int bvSize = 0;
00045 static int bvNum = 0;
00046 static int bvEmptySize = 0;
00047 static int bvEmptyNum = 0;
00048 
00049 static int modelValSize;
00050 static int textValSize;
00051 static int modelValNum;
00052 static int textValNum;
00053 static int bindingValSize;
00054 static int bindingValNum;
00055 static int exprSize;
00056 static int exprNum;
00057 static int nameExprSize;
00058 static int nameExprNum;
00059 static int constantExprSize;
00060 static int constantExprNum;
00061 static int funcExprSize;
00062 static int funcExprNum;
00063 static int assignExprSize;
00064 static int assignExprNum;
00065 static int selectExprSize;
00066 static int selectExprNum;
00067 static int opExprSize;
00068 static int opExprNum;
00069 static int unOpExprSize;
00070 static int unOpExprNum;
00071 static int primExprSize;
00072 static int primExprNum;
00073 static int argListExprSize;
00074 static int argListExprNum;
00075 static int listExprSize;
00076 static int listExprNum;
00077 
00078 bool PickleValDpndSize(bool cut, istream *pickle);
00079 
00080 bool SkipLocation(istream *pickle) {
00081   // unpickle loc->line:
00082   pickle->seekg(sizeof(char), ios::cur);
00083   // unpickle loc->character:
00084   pickle->seekg(sizeof(char), ios::cur);
00085   return true;
00086 }
00087 
00088 bool PickleContextDpndSize(istream *pickle) {
00089   bool success = true;
00090   short int cLen;
00091   pickle->read((char*)&cLen, sizeof(cLen));
00092   while (success && cLen--) {
00093     short int nameLen;
00094     pickle->read((char*)&nameLen, sizeof(nameLen));
00095     if (nameLen < 0 || nameLen > pickleSize)
00096       throw FS::EndOfFile();
00097     pickle->seekg(nameLen, ios::cur);
00098     success = PickleValDpndSize(true, pickle);
00099   }
00100   return success;
00101 }
00102 
00103 bool PickleDepPathSize(istream *pickle) {
00104   // Allocate the DepPath:
00105   short int pathLen;
00106   pickle->read((char*)(&pathLen), sizeof(pathLen));
00107   // path kind:
00108   char pk;
00109   pickle->read((char*)(&pk), sizeof(pk));
00110   if (pk == '!')
00111     bangFPNum++;
00112   else if (pk == 'T')
00113     typeFPNum++;
00114   // arcs:  
00115   for (int i = 0; i < pathLen; i++) {
00116     short int len;
00117     pickle->read((char*)(&len), sizeof(len));
00118     if (len < 0 || len > pickleSize)
00119       throw FS::EndOfFile();
00120     pickle->seekg(len, ios::cur);
00121   }
00122   // fingerprint:
00123   depFPNum++;
00124   FP::Tag tag;
00125   tag.Read(*pickle);
00126   return true;
00127 }
00128 
00129 bool PickleDPathsSize(istream *pickle) {
00130   short int dSize;
00131   pickle->read((char*)(&dSize), sizeof(dSize));
00132   for (int i = 0; i < dSize; i++) {
00133     PickleDepPathSize(pickle);
00134     FP::Tag tag;
00135     tag.Read(*pickle);
00136   }
00137   return true;
00138 }
00139 
00140 bool PickleDPSSize(istream *pickle) {
00141   /* Unpickle the dps of the value.  */
00142   streampos startPos = pickle->tellg();
00143   BitVector bv;
00144   bv.Read(*pickle);
00145   pickleDpndSize += pickle->tellg() - startPos;
00146   bvNum++;
00147   bvSize += pickle->tellg() - startPos;
00148   if (bv.IsEmpty()) {
00149     bvEmptySize += pickle->tellg() - startPos;
00150     bvEmptyNum++;
00151   }
00152   return true;
00153 }
00154 
00155 bool PickleLenDPSSize(istream *pickle) {
00156   streampos startPos = pickle->tellg();
00157   short int len;
00158   pickle->read((char*)&len, sizeof(len));
00159   while (len-- > 0) {
00160     PickleDepPathSize(pickle);
00161   }
00162   pickleDpndSize += pickle->tellg() - startPos;
00163   return true;
00164 }
00165 
00166 bool PickleExprDpndSize(istream *pickle) {
00167   exprNum++;
00168   SkipLocation(pickle);
00169   char ek;
00170   pickle->read((char*)&ek, sizeof(ek));
00171   switch (ek) {
00172   case ConstantEK:
00173     {
00174       streampos startPos = pickle->tellg();
00175       PickleValDpndSize(true, pickle);
00176       constantExprSize += pickle->tellg() - startPos;
00177       constantExprNum++;
00178       break;
00179     }
00180   case IfEK:
00181     PickleExprDpndSize(pickle);
00182     PickleExprDpndSize(pickle);
00183     PickleExprDpndSize(pickle);
00184     break;
00185   case ComputedEK:
00186     PickleExprDpndSize(pickle);
00187     break;
00188   case ExprListEK: case StmtListEK: case ListEK:
00189     {
00190       short int len;
00191       pickle->read((char*)&len, sizeof(len));
00192       while (len--)
00193         PickleExprDpndSize(pickle);
00194       listExprSize += sizeof(len);
00195       listExprNum++;
00196       break;
00197     }
00198   case ArgListEK: 
00199     {
00200       pickle->seekg(sizeof(Bit64), ios::cur);
00201       short int len;
00202       pickle->read((char*)&len, sizeof(len));
00203       while (len--)
00204         PickleExprDpndSize(pickle);
00205       argListExprSize += sizeof(Bit64) + sizeof(len);
00206       argListExprNum++;
00207       break;
00208     }
00209   case AssignEK:
00210     {
00211       PickleExprDpndSize(pickle);
00212       PickleExprDpndSize(pickle);
00213       pickle->seekg(sizeof(char), ios::cur);
00214       assignExprSize += sizeof(char);
00215       assignExprNum++;
00216       break;
00217     }
00218   case BindEK:
00219     PickleExprDpndSize(pickle);
00220     PickleExprDpndSize(pickle);
00221     break;
00222   case NameEK:
00223     {
00224       short int len;
00225       pickle->read((char*)&len, sizeof(len));
00226       if (len < 0 || len > pickleSize)
00227         throw FS::EndOfFile();
00228       pickle->seekg(len, ios::cur);
00229       nameExprSize += sizeof(len) + len;
00230       nameExprNum++;
00231       break;
00232     }
00233   case BindingEK:
00234     {
00235       short int len;
00236       pickle->read((char*)&len, sizeof(len));
00237       while (len--)
00238         PickleExprDpndSize(pickle);
00239       break;
00240     }
00241   case ApplyOpEK:
00242     {
00243       // the operator:
00244       short int len;
00245       pickle->read((char*)&len, sizeof(len));
00246       if (len < 0 || len > pickleSize)
00247         throw FS::EndOfFile();
00248       pickle->seekg(len, ios::cur);
00249       // the operands:
00250       PickleExprDpndSize(pickle);
00251       PickleExprDpndSize(pickle);
00252       opExprSize += sizeof(len) + len;
00253       opExprNum++;
00254       break;
00255     }
00256   case ApplyUnOpEK:
00257     {
00258       // the operator:
00259       short int len;
00260       pickle->read((char*)&len, sizeof(len));
00261       if (len < 0 || len > pickleSize)
00262         throw FS::EndOfFile();
00263       pickle->seekg(len, ios::cur);
00264       // the operand:
00265       PickleExprDpndSize(pickle);
00266       unOpExprSize += sizeof(len) + len;
00267       unOpExprNum++;
00268       break;
00269     }
00270   case ModelEK:
00271     {
00272       PickleExprDpndSize(pickle);
00273       PickleExprDpndSize(pickle);
00274       PickleExprDpndSize(pickle);
00275       pickle->seekg(32, ios::cur);
00276       break;
00277     }
00278   case FileEK:
00279     {
00280       PickleExprDpndSize(pickle);
00281       short int len;
00282       pickle->read((char*)&len, sizeof(len));
00283       if (len < 0 || len > pickleSize)
00284         throw FS::EndOfFile();
00285       pickle->seekg(len, ios::cur);
00286       pickle->seekg(32, ios::cur);
00287       pickle->seekg(sizeof(bool), ios::cur);
00288       break;
00289     }
00290   case PrimitiveEK:
00291     {
00292       short int len;
00293       pickle->read((char*)&len, sizeof(len));
00294       if (len < 0 || len > pickleSize)
00295         throw FS::EndOfFile();
00296       pickle->seekg(len, ios::cur);
00297       primExprSize += sizeof(len) + len;
00298       primExprNum++;
00299       break;
00300     }
00301   case PairEK:
00302     PickleExprDpndSize(pickle);
00303     PickleExprDpndSize(pickle);
00304     break;
00305   case SelectEK:
00306     {
00307       PickleExprDpndSize(pickle);
00308       PickleExprDpndSize(pickle);
00309       pickle->seekg(sizeof(char), ios::cur);
00310       selectExprSize += sizeof(char);
00311       selectExprNum++;
00312       break;
00313     }
00314   case FuncEK:
00315     {
00316       short int nameLen;
00317       pickle->read((char*)&nameLen, sizeof(nameLen));
00318       if (nameLen < 0 || nameLen > pickleSize)
00319         throw FS::EndOfFile();
00320       pickle->seekg(nameLen, ios::cur);
00321       pickle->seekg(sizeof(char), ios::cur);
00322       PickleExprDpndSize(pickle);
00323       PickleExprDpndSize(pickle);
00324       funcExprSize += sizeof(nameLen) + nameLen + sizeof(char);
00325       funcExprNum++;
00326       break;
00327     }
00328   case BlockEK:
00329     PickleExprDpndSize(pickle);
00330     PickleExprDpndSize(pickle);
00331     pickle->seekg(sizeof(bool), ios::cur);
00332     break;
00333   case IterateEK:
00334     PickleExprDpndSize(pickle);
00335     PickleExprDpndSize(pickle);
00336     PickleExprDpndSize(pickle);
00337     break;
00338   case ApplyEK:
00339     PickleExprDpndSize(pickle);
00340     PickleExprDpndSize(pickle);
00341     break;
00342   case ErrorEK:    
00343     break;
00344   default:
00345     break;
00346   }
00347   return true;
00348 }
00349 
00350 bool PickleValDpndSize(bool cut, istream *pickle) {
00351   bool success = true;
00352   
00353   // path of the value:
00354   streampos startPos = pickle->tellg();
00355   char hasPath;
00356   pickle->read((char*)&hasPath, sizeof(hasPath));
00357   if ((bool)hasPath) PickleDepPathSize(pickle);
00358   pickleDpndSize += pickle->tellg() - startPos;
00359 
00360   // subvalues of the value:
00361   if (!hasPath || !cut) {
00362     char vk;
00363     pickle->read((char*)&vk, sizeof(vk));
00364 
00365     switch (vk) {
00366     case BooleanVK:
00367       pickle->seekg(sizeof(char), ios::cur);
00368       break;
00369     case IntegerVK:
00370       pickle->seekg(sizeof(int), ios::cur);
00371       break;
00372     case PrimitiveVK:
00373       {
00374         short int nameLen;
00375         pickle->read((char*)&nameLen, sizeof(nameLen));
00376         if (nameLen < 0 || nameLen > pickleSize)
00377           throw FS::EndOfFile();
00378         pickle->seekg(nameLen, ios::cur);
00379         break;
00380       }
00381     case ListVK:
00382       {
00383         short int len;
00384         pickle->read((char*)&len, sizeof(len));
00385         while ((len-- > 0) && PickleValDpndSize(cut, pickle));
00386         success = PickleLenDPSSize(pickle);
00387         break;
00388       }
00389     case BindingVK:
00390       {
00391         short int len;
00392         pickle->read((char*)&len, sizeof(len));
00393         bindingValSize += sizeof(len);
00394         short int nameLen;
00395         while (success && len--) {
00396           pickle->read((char*)&nameLen, sizeof(nameLen));
00397           if (nameLen < 0 || nameLen > pickleSize)
00398             throw FS::EndOfFile();
00399           pickle->seekg(nameLen, ios::cur);
00400           bindingValSize += sizeof(nameLen) + nameLen;
00401           success = PickleValDpndSize(cut, pickle);
00402         }
00403         success = PickleLenDPSSize(pickle);
00404         bindingValNum++;
00405         break;
00406       }
00407     case TextVK:
00408       {
00409         streampos startPos = pickle->tellg();
00410         char hasTxt;
00411         pickle->read((char*)&hasTxt, sizeof(hasTxt));
00412         if ((bool)hasTxt) {
00413           int tLen;
00414           pickle->read((char*)&tLen, sizeof(tLen));
00415           if (tLen < 0 || tLen > pickleSize)
00416             throw FS::EndOfFile();
00417           pickle->seekg(tLen, ios::cur);
00418         }
00419         else {
00420           // Must have sid.
00421           short int nameLen;
00422           pickle->read((char*)&nameLen, sizeof(nameLen));
00423           if (nameLen < 0 || nameLen > pickleSize)
00424             throw FS::EndOfFile();
00425           pickle->seekg(nameLen, ios::cur);
00426           pickle->seekg(sizeof(ShortId), ios::cur);
00427           FP::Tag tag;
00428           tag.Read(*pickle);
00429         }
00430         textValSize += pickle->tellg() - startPos;
00431         textValNum++;
00432         break;
00433       }
00434     case ClosureVK:
00435       {
00436         // the function body:
00437         short int pathNameLen;
00438         pickle->read((char*)(&pathNameLen), sizeof(pathNameLen));
00439         if (pathNameLen < 0 || pathNameLen > pickleSize)
00440           throw FS::EndOfFile();
00441         pickle->seekg(pathNameLen, ios::cur);
00442         pickle->seekg(sizeof(ShortId), ios::cur);
00443         pickle->seekg(sizeof(int), ios::cur);
00444         streampos startPos = pickle->tellg();
00445 
00446 /*      char unpickled;
00447         pickle->read((char*)&unpickled, sizeof(unpickled));
00448         if (unpickled)
00449           pickle->seekg(sizeof(int), ios::cur);
00450         else
00451           success = PickleExprDpndSize(pickle);
00452 */
00453         PickleExprDpndSize(pickle);
00454         exprSize += pickle->tellg() - startPos;
00455 
00456         // the context:
00457         if (success)
00458           success = PickleContextDpndSize(pickle);
00459 
00460         // the name:
00461         if (success) {
00462           pickle->seekg(sizeof(bool), ios::cur);
00463           int nameLen;
00464           pickle->read((char*)&nameLen, sizeof(nameLen));
00465           if (nameLen < 0 || nameLen > pickleSize)
00466             throw FS::EndOfFile();
00467           pickle->seekg(nameLen, ios::cur);
00468         }
00469         break;
00470       }
00471     case ModelVK:
00472       {
00473         streampos startPos = pickle->tellg();
00474 
00475         // Name of the model:
00476         short int nameLen;
00477         pickle->read((char*)&nameLen, sizeof(nameLen));
00478         if (nameLen < 0 || nameLen > pickleSize)
00479           throw FS::EndOfFile();
00480         pickle->seekg(nameLen, ios::cur);
00481 
00482         // Sid of the model:
00483         pickle->seekg(sizeof(ShortId), ios::cur);
00484 
00485         // Lid for the model root:
00486         char lidLen;
00487         pickle->read((char*)&lidLen, sizeof(char));
00488         pickle->seekg(lidLen, ios::cur);
00489 
00490         // VestaSource of the model root:
00491         // We leave master, pseudoInode, ac, rep, and attribs uninitialized,
00492         // since we know we do not need them.  We believe we do not need the
00493         // sid and fptag, but we decided to pickle/unpickle them just in case.
00494         pickle->seekg(sizeof(ShortId), ios::cur);
00495         FP::Tag rootTag;
00496         rootTag.Read(*pickle);
00497 
00498         // Fingerprint:
00499         FP::Tag tag;
00500         tag.Read(*pickle);
00501         FP::Tag lidTag;
00502         lidTag.Read(*pickle);
00503         modelValSize += pickle->tellg() - startPos;
00504         modelValNum++;
00505         break;
00506       }
00507     case ErrorVK:
00508       break;
00509     default:
00510       cerr << "Bad value type in unpickling. Cache data may be corrupted!\n";
00511       success = false;
00512       break;
00513     }
00514   }
00515   if (success)
00516     success = PickleDPSSize(pickle);
00517   return success;
00518 }
00519 
00520 bool PickleDpndSize(istream *pickle) {
00521   modelValSize = modelValNum = 0;
00522   textValSize = textValNum = 0;
00523   bindingValSize = bindingValNum = 0;
00524   exprSize = exprNum = 0;
00525   nameExprSize = nameExprNum = 0;
00526   constantExprSize = constantExprNum = 0;
00527   funcExprSize = funcExprNum = 0;
00528   assignExprSize = assignExprNum = 0;
00529   selectExprSize = selectExprNum = 0;
00530   opExprSize = opExprNum = 0;
00531   unOpExprSize = unOpExprNum = 0;
00532   primExprSize = primExprNum = 0;
00533   argListExprSize = argListExprNum = 0;
00534   listExprSize = listExprNum = 0;
00535   try {
00536     // Version number:
00537     pickle->seekg(sizeof(int), ios::cur);
00538     // Dependency:
00539     streampos startPos = pickle->tellg();
00540     bool success = PickleDPathsSize(pickle);
00541     // Value:
00542     if (success) {
00543       pickleDpndSize = pickle->tellg() - startPos;
00544       return PickleValDpndSize(true, pickle);
00545     }
00546   } catch (FS::Failure f) {
00547     cerr << f;
00548   } catch (FS::EndOfFile f) {
00549     cerr << "EOF while collecting data for pickle value.\n";
00550   } catch (...) {
00551     cerr << "Unknown exception in collecting data for pickle value.\n";
00552   }
00553   return false;
00554 }
00555 
00556 int tellg(istream *is) { return is->tellg(); }
00557 
00558 int main(int argc, char* argv[]) {
00559   istream *pickle = &cin;
00560   bool verbose = false;
00561 
00562   int i = 1;
00563   while (i < argc) {
00564     if (argv[i][0] == '-') {
00565       if (strcmp(argv[i], "-verbose") == 0) {
00566         verbose = true;
00567         i++;
00568       }
00569       else {
00570         cout << "\n++++ unrecognized flag: " << argv[i] << ".\n\n";
00571         exit(0);
00572       }
00573     }
00574     else
00575       pickle = NEW_CONSTR(ifstream, (argv[i++]));
00576   } // end of while
00577 
00578   if (verbose) cout << "Cache entries:\n";
00579   int valTotal = 0;
00580   int depTotal = 0;
00581   int entryNum = 0;
00582   int valMax = 0;
00583   int depMax = 0;
00584   int maxSize = 0;
00585   int modelValMax = 0;
00586   int textValMax = 0;
00587   while (pickle->read((char*)&pickleSize, sizeof(int))) {
00588     if (PickleDpndSize(pickle)) {
00589       valTotal += pickleSize - pickleDpndSize;
00590       depTotal += pickleDpndSize;
00591       entryNum++;
00592       if (maxSize < pickleSize) {
00593         valMax = pickleSize - pickleDpndSize;
00594         modelValMax = modelValSize;
00595         textValMax = textValSize;
00596         depMax = pickleDpndSize;
00597         maxSize = pickleSize;
00598       }
00599       if (verbose) {
00600         cout << "Val: " << (pickleSize - pickleDpndSize) << endl;
00601         cout << "  ModelVal: " << "[ size=" << modelValSize 
00602                                << ", num=" << modelValNum << " ]\n";
00603         cout << "  TextVal:" << "[ size=" << textValSize
00604                              << ", num=" << textValNum << " ]\n";
00605         cout << "  BindingVal: " << "[ size=" << bindingValSize
00606                                  << ", num=" << bindingValNum << " ]\n";
00607         cout << "  Expr: " << "[ size=" << exprSize
00608                            << ", num=" << exprNum << " ]\n";
00609         cout << "    NameExpr: " << "[ size=" << nameExprSize
00610                                  << ", num=" << nameExprNum << " ]\n";
00611         cout << "    ConstantExpr: " << "[ size=" << constantExprSize
00612                                      << ", num=" << constantExprNum << " ]\n";
00613         cout << "    FuncExpr: " << "[ size=" << funcExprSize
00614                                  << ", num=" << funcExprNum << " ]\n";
00615         cout << "    AssignExpr: " << "[ size=" << assignExprSize
00616                                    << ", num=" << assignExprNum << " ]\n";
00617         cout << "    SelectExpr: " << "[ size=" << selectExprSize
00618                                    << ", num=" << selectExprNum << " ]\n";
00619         cout << "    OpExpr: " << "[ size=" << opExprSize
00620                                << ", num=" << opExprNum << " ]\n";
00621         cout << "    UnOpExpr: " << "[ size=" << unOpExprSize
00622                                  << ", num=" << unOpExprNum << " ]\n";
00623         cout << "    PrimExpr: " << "[ size=" << primExprSize
00624                                  << ", num=" << primExprNum << " ]\n";
00625         cout << "    ArgListExpr: " << "[ size=" << argListExprSize
00626                                     << ", num=" << argListExprNum << " ]\n";
00627         cout << "    ListExpr: " << "[ size=" << listExprSize
00628                                  << ", num=" << listExprNum << " ]\n";
00629         cout << "Dpnd: " << pickleDpndSize << "\n\n";
00630       }
00631     }
00632     else {
00633       cerr << "Failed in PickleDpndSize.\n";
00634       break;
00635     }
00636   }
00637   if (entryNum > 0) {
00638     cout << "Number of Entry: " << entryNum << endl;
00639     cout << "FP: " << depFPNum << endl;
00640     cout << "BangFP: " << bangFPNum << endl;
00641     cout << "TypeFP: " << typeFPNum << endl;
00642     cout << "Bit Vectors: " << bvNum << ", " << bvSize << endl;
00643     cout << "Empty Bit Vectors: " << bvEmptyNum << ", " << bvEmptySize << endl;
00644 
00645     cout << "Max:" << endl;
00646     cout << "Val: " << valMax << endl;
00647     cout << "Dpnd: " << depMax << "\n\n";
00648 
00649     cout << "Average:" << endl;
00650     cout << "Val: " << (valTotal/entryNum) << endl;
00651     cout << "Dpnd: " << (depTotal/entryNum) << "\n\n";
00652   }
00653   else
00654     cerr << "The input file is empty.\n";
00655   return 0;
00656 }

Generated on Mon May 8 00:48:39 2006 for Vesta by  doxygen 1.4.2