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 #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
00082 pickle->seekg(sizeof(char), ios::cur);
00083
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
00105 short int pathLen;
00106 pickle->read((char*)(&pathLen), sizeof(pathLen));
00107
00108 char pk;
00109 pickle->read((char*)(&pk), sizeof(pk));
00110 if (pk == '!')
00111 bangFPNum++;
00112 else if (pk == 'T')
00113 typeFPNum++;
00114
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
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
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
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
00250 PickleExprDpndSize(pickle);
00251 PickleExprDpndSize(pickle);
00252 opExprSize += sizeof(len) + len;
00253 opExprNum++;
00254 break;
00255 }
00256 case ApplyUnOpEK:
00257 {
00258
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
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
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
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
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
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
00447
00448
00449
00450
00451
00452
00453 PickleExprDpndSize(pickle);
00454 exprSize += pickle->tellg() - startPos;
00455
00456
00457 if (success)
00458 success = PickleContextDpndSize(pickle);
00459
00460
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
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
00483 pickle->seekg(sizeof(ShortId), ios::cur);
00484
00485
00486 char lidLen;
00487 pickle->read((char*)&lidLen, sizeof(char));
00488 pickle->seekg(lidLen, ios::cur);
00489
00490
00491
00492
00493
00494 pickle->seekg(sizeof(ShortId), ios::cur);
00495 FP::Tag rootTag;
00496 rootTag.Read(*pickle);
00497
00498
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
00537 pickle->seekg(sizeof(int), ios::cur);
00538
00539 streampos startPos = pickle->tellg();
00540 bool success = PickleDPathsSize(pickle);
00541
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 }
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 }