cp_annotate.cc revision 6658
1/* 2 * Copyright (c) 2006-2009 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Ali Saidi 29 */ 30 31#include "arch/utility.hh" 32#include "arch/alpha/linux/threadinfo.hh" 33#include "base/cp_annotate.hh" 34#include "base/callback.hh" 35#include "base/loader/object_file.hh" 36#include "base/output.hh" 37#include "base/trace.hh" 38#include "config/the_isa.hh" 39#include "cpu/thread_context.hh" 40#include "sim/arguments.hh" 41#include "sim/core.hh" 42#include "sim/sim_exit.hh" 43#include "sim/system.hh" 44 45struct CPAIgnoreSymbol 46{ 47 const char *symbol; 48 size_t len; 49}; 50#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) } 51 52CPAIgnoreSymbol ignoreSymbols[] = { 53 CPA_IGNORE_SYMBOL("m5a_"), 54 CPA_IGNORE_SYMBOL("ret_from_sys_call"), 55 CPA_IGNORE_SYMBOL("ret_from_reschedule"), 56 CPA_IGNORE_SYMBOL("_spin_"), 57 CPA_IGNORE_SYMBOL("local_bh_"), 58 CPA_IGNORE_SYMBOL("restore_all"), 59 CPA_IGNORE_SYMBOL("Call_Pal_"), 60 CPA_IGNORE_SYMBOL("pal_post_interrupt"), 61 CPA_IGNORE_SYMBOL("rti_to_"), 62 CPA_IGNORE_SYMBOL("sys_int_2"), 63 CPA_IGNORE_SYMBOL("sys_interrupt"), 64 CPA_IGNORE_SYMBOL("normal_int"), 65 CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"), 66 CPA_IGNORE_SYMBOL("Trap_Interrupt"), 67 CPA_IGNORE_SYMBOL("do_entInt"), 68 CPA_IGNORE_SYMBOL("__do_softirq"), 69 CPA_IGNORE_SYMBOL("_end"), 70 CPA_IGNORE_SYMBOL("entInt"), 71 CPA_IGNORE_SYMBOL("entSys"), 72 {0,0} 73}; 74#undef CPA_IGNORE_SYMBOL 75 76using namespace std; 77using namespace TheISA; 78 79bool CPA::exists; 80CPA *CPA::_cpa; 81 82class AnnotateDumpCallback : public Callback 83{ 84 85 private: 86 CPA *cpa; 87 public: 88 virtual void process(); 89 AnnotateDumpCallback(CPA *_cpa) 90 : cpa(_cpa) 91 {} 92}; 93 94void 95AnnotateDumpCallback::process() 96{ 97 cpa->dump(true); 98 cpa->dumpKey(); 99} 100 101 102CPA::CPA(Params *p) 103 : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0) 104{ 105 if (exists) 106 fatal("Multiple annotation objects found in system"); 107 exists = true; 108 109 _enabled = p->enabled; 110 _cpa = this; 111 112 vector<string>::iterator i; 113 i = p->user_apps.begin(); 114 115 while (i != p->user_apps.end()) { 116 ObjectFile *of = createObjectFile(*i); 117 string sf; 118 if (!of) 119 fatal("Couldn't load symbols from file: %s\n", *i); 120 sf = *i; 121 sf.erase(0, sf.rfind('/') + 1);; 122 DPRINTFN("file %s short: %s\n", *i, sf); 123 userApp[sf] = new SymbolTable; 124 bool result1 = of->loadGlobalSymbols(userApp[sf]); 125 bool result2 = of->loadLocalSymbols(userApp[sf]); 126 if (!result1 || !result2) 127 panic("blah"); 128 assert(result1 && result2); 129 i++; 130 } 131} 132 133void 134CPA::startup() 135{ 136 osbin = simout.create("annotate.bin", true); 137 // MAGIC version number 'M''5''A'N' + version/capabilities 138 ah.version = 0x4D35414E00000101ULL; 139 ah.num_recs = 0; 140 ah.key_off = 0; 141 osbin->write((char*)&ah, sizeof(AnnotateHeader)); 142 143 registerExitCallback(new AnnotateDumpCallback(this)); 144} 145void 146CPA::swSmBegin(ThreadContext *tc) 147{ 148 if (!enabled()) 149 return; 150 151 Arguments args(tc); 152 std::string st; 153 Addr junk; 154 char sm[50]; 155 if (!TheISA::inUserMode(tc)) 156 debugSymbolTable->findNearestSymbol( 157 tc->readIntReg(ReturnAddressReg), st, junk); 158 159 CopyStringOut(tc, sm, args[0], 50); 160 System *sys = tc->getSystemPtr(); 161 StringWrap name(sys->name()); 162 163 if (!sm[0]) 164 warn("Got null SM at tick %d\n", curTick); 165 166 int sysi = getSys(sys); 167 int smi = getSm(sysi, sm, args[1]); 168 DPRINTF(Annotate, "Starting machine: %s(%d) sysi: %d id: %#x\n", sm, 169 smi, sysi, args[1]); 170 DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi, 171 smMap[smi-1].first, smMap[smi-1].second.first, 172 smMap[smi-1].second.second); 173 174 uint64_t frame = getFrame(tc); 175 StackId sid = StackId(sysi, frame); 176 177 // check if we need to link to the previous state machine 178 int flags = args[2]; 179 if (flags & FL_LINK) { 180 if (smStack[sid].size()) { 181 int prev_smi = smStack[sid].back(); 182 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n", 183 prev_smi, sm, smi, args[1]); 184 185 if (lnMap[smi]) 186 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n", 187 smi, lnMap[smi]); 188 assert(lnMap[smi] == 0); 189 lnMap[smi] = prev_smi; 190 191 add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi); 192 } else { 193 DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n", 194 sm, smi, args[1]); 195 } 196 } 197 198 199 smStack[sid].push_back(smi); 200 201 DPRINTF(Annotate, "Stack Now (%#X):\n", frame); 202 for (int x = smStack[sid].size()-1; x >= 0; x--) 203 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]); 204 205 // reset the sw state exculsion to false 206 if (swExpl[sid]) 207 swExpl[sid] = false; 208 209 210 Id id = Id(sm, frame); 211 if (scLinks[sysi-1][id]) { 212 AnnDataPtr an = scLinks[sysi-1][id]; 213 scLinks[sysi-1].erase(id); 214 an->stq = smi; 215 an->dump = true; 216 DPRINTF(Annotate, 217 "Found prev unknown linking from %d to state machine %s(%d)\n", 218 an->sm, sm, smi); 219 220 if (lnMap[smi]) 221 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n", 222 smi, lnMap[smi]); 223 assert(lnMap[smi] == 0); 224 lnMap[smi] = an->sm; 225 } 226 227 // add a new begin ifwe have that info 228 if (st != "") { 229 DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st, 230 smi, stCache.size()); 231 int sti = getSt(sm, st); 232 lastState[smi] = sti; 233 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti); 234 } 235} 236 237void 238CPA::swSmEnd(ThreadContext *tc) 239{ 240 if (!enabled()) 241 return; 242 243 Arguments args(tc); 244 char sm[50]; 245 CopyStringOut(tc, sm, args[0], 50); 246 System *sys = tc->getSystemPtr(); 247 doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc)); 248} 249 250void 251CPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame) 252{ 253 int sysi = getSys(sys); 254 StackId sid = StackId(sysi, frame); 255 256 257 // reset the sw state exculsion to false 258 if (swExpl[sid]) 259 swExpl[sid] = false; 260 261 262 int smib = smStack[sid].back(); 263 StringWrap name(sys->name()); 264 DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi, 265 frame, smib); 266 267 if (!smStack[sid].size() || smMap[smib-1].second.first != sm) { 268 DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x" 269 " top of stack: %s Current Stack:\n", 270 sysi, frame, smMap[smib-1].second.first); 271 for (int x = smStack[sid].size()-1; x >= 0; x--) 272 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]); 273 DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm, 274 smMap[smib-1].second.first); 275 276 warn("State machine stack not unwinding correctly at %d\n", curTick); 277 } else { 278 DPRINTF(Annotate, 279 "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n", 280 sm, sysi, smMap[smib-1].second.second, smStack[sid].back(), 281 getSm(sysi, sm, smMap[smib-1].second.second)); 282 assert(getSm(sysi, sm, smMap[smib-1].second.second) == 283 smStack[sid].back()); 284 285 int smi = smStack[sid].back(); 286 smStack[sid].pop_back(); 287 288 if (lnMap[smi]) { 289 DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]); 290 add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]); 291 lnMap.erase(smi); 292 } 293 294 if (smStack[sid].size()) { 295 add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]); 296 } 297 298 DPRINTF(Annotate, "Stack Now:\n"); 299 for (int x = smStack[sid].size()-1; x >= 0; x--) 300 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]); 301 } 302} 303 304 305void 306CPA::swExplictBegin(ThreadContext *tc) 307{ 308 if (!enabled()) 309 return; 310 311 Arguments args(tc); 312 char st[50]; 313 CopyStringOut(tc, st, args[1], 50); 314 315 StringWrap name(tc->getSystemPtr()->name()); 316 DPRINTF(Annotate, "Explict begin of state %s\n", st); 317 uint32_t flags = args[0]; 318 if (flags & FL_BAD) 319 warn("BAD state encountered: at cycle %d: %s\n", curTick, st); 320 swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]); 321} 322 323void 324CPA::swAutoBegin(ThreadContext *tc, Addr next_pc) 325{ 326 if (!enabled()) 327 return; 328 329 string sym; 330 Addr sym_addr = 0; 331 SymbolTable *symtab = NULL; 332 333 334 if (!TheISA::inUserMode(tc)) { 335 debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr); 336 symtab = debugSymbolTable; 337 } else { 338 Linux::ThreadInfo ti(tc); 339 string app = ti.curTaskName(); 340 if (userApp.count(app)) 341 userApp[app]->findNearestSymbol(next_pc, sym, sym_addr); 342 } 343 344 if (sym_addr) 345 swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc)); 346} 347 348void 349CPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl, 350 int flags) 351{ 352 int x = 0; 353 int len; 354 while (ignoreSymbols[x].len) 355 { 356 len = ignoreSymbols[x].len; 357 if (!st.compare(0,len, ignoreSymbols[x].symbol, len)) 358 return; 359 x++; 360 } 361 362 int sysi = getSys(sys); 363 StackId sid = StackId(sysi, frame); 364 // if expl is true suspend symbol table based states 365 if (!smStack[sid].size()) 366 return; 367 if (!expl && swExpl[sid]) 368 return; 369 if (expl) 370 swExpl[sid] = true; 371 DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi); 372 int smi = smStack[sid].back(); 373 int sti = getSt(smMap[smi-1].second.first, st); 374 if (lastState[smi] != sti) { 375 lastState[smi] = sti; 376 add(OP_BEGIN, flags, cpuid, smi, sti); 377 } 378} 379 380void 381CPA::swEnd(ThreadContext *tc) 382{ 383 if (!enabled()) 384 return; 385 386 std::string st; 387 Addr junk; 388 if (!TheISA::inUserMode(tc)) 389 debugSymbolTable->findNearestSymbol( 390 tc->readIntReg(ReturnAddressReg), st, junk); 391 System *sys = tc->getSystemPtr(); 392 StringWrap name(sys->name()); 393 394 int sysi = getSys(sys); 395 StackId sid = StackId(sysi, getFrame(tc)); 396 if (!smStack[sid].size()) { 397 DPRINTF(Annotate, "Explict end of State: %s IGNORED\n", st); 398 return; 399 } 400 DPRINTF(Annotate, "Explict end of State: %s\n", st); 401 // return back to symbol table based states 402 swExpl[sid] = false; 403 int smi = smStack[sid].back(); 404 if (st != "") { 405 int sti = getSt(smMap[smi-1].second.first, st); 406 lastState[smi] = sti; 407 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti); 408 } 409} 410 411void 412CPA::swQ(ThreadContext *tc) 413{ 414 if (!enabled()) 415 return; 416 417 char q[50]; 418 Arguments args(tc); 419 uint64_t id = args[0]; 420 CopyStringOut(tc, q, args[1], 50); 421 int32_t count = args[2]; 422 System *sys = tc->getSystemPtr(); 423 424 int sysi = getSys(sys); 425 StackId sid = StackId(sysi, getFrame(tc)); 426 if (!smStack[sid].size()) 427 return; 428 int smi = smStack[sid].back(); 429 if (swExpl[sid]) 430 swExpl[sid] = false; 431 int qi = getQ(sysi, q, id); 432 if (count == 0) { 433 //warn("Tried to queue 0 bytes in %s, ignoring\n", q); 434 return; 435 } 436 DPRINTFS(AnnotateQ, sys, 437 "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n", 438 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 439 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count); 440} 441 442void 443CPA::swDq(ThreadContext *tc) 444{ 445 if (!enabled()) 446 return; 447 448 char q[50]; 449 Arguments args(tc); 450 uint64_t id = args[0]; 451 CopyStringOut(tc, q, args[1], 50); 452 int32_t count = args[2]; 453 System *sys = tc->getSystemPtr(); 454 455 int sysi = getSys(sys); 456 StackId sid = StackId(sysi, getFrame(tc)); 457 if (!smStack[sid].size()) 458 return; 459 int smi = smStack[sid].back(); 460 int qi = getQ(sysi, q, id); 461 if (swExpl[sid]) 462 swExpl[sid] = false; 463 DPRINTFS(AnnotateQ, sys, 464 "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n", 465 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 466 assert(count != 0); 467 468 doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count); 469} 470 471void 472CPA::swPq(ThreadContext *tc) 473{ 474 if (!enabled()) 475 return; 476 477 char q[50]; 478 Arguments args(tc); 479 uint64_t id = args[0]; 480 CopyStringOut(tc, q, args[1], 50); 481 System *sys = tc->getSystemPtr(); 482 int32_t count = args[2]; 483 484 int sysi = getSys(sys); 485 StackId sid = StackId(sysi, getFrame(tc)); 486 if (!smStack[sid].size()) 487 return; 488 int smi = smStack[sid].back(); 489 int qi = getQ(sysi, q, id); 490 if (swExpl[sid]) 491 swExpl[sid] = false; 492 DPRINTFS(AnnotateQ, sys, 493 "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n", 494 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 495 496 assert(count != 0); 497 if (qBytes[qi-1] < count) { 498 dump(true); 499 dumpKey(); 500 fatal("Queue %s peeking with not enough bytes available in queue!\n", q); 501 } 502 503 add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count); 504} 505 506void 507CPA::swRq(ThreadContext *tc) 508{ 509 if (!enabled()) 510 return; 511 512 char q[50]; 513 Arguments args(tc); 514 uint64_t id = args[0]; 515 CopyStringOut(tc, q, args[1], 50); 516 System *sys = tc->getSystemPtr(); 517 int32_t count = args[2]; 518 519 int sysi = getSys(sys); 520 StackId sid = StackId(sysi, getFrame(tc)); 521 if (!smStack[sid].size()) 522 return; 523 int smi = smStack[sid].back(); 524 int qi = getQ(sysi, q, id); 525 if (swExpl[sid]) 526 swExpl[sid] = false; 527 DPRINTFS(AnnotateQ, sys, 528 "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n", 529 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 530 531 assert(count != 0); 532 533 add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count); 534} 535 536 537void 538CPA::swWf(ThreadContext *tc) 539{ 540 if (!enabled()) 541 return; 542 543 char q[50]; 544 Arguments args(tc); 545 uint64_t id = args[0]; 546 CopyStringOut(tc, q, args[1], 50); 547 System *sys = tc->getSystemPtr(); 548 int32_t count = args[3]; 549 550 int sysi = getSys(sys); 551 StackId sid = StackId(sysi, getFrame(tc)); 552 if (!smStack[sid].size()) 553 return; 554 int smi = smStack[sid].back(); 555 int qi = getQ(sysi, q, id); 556 add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count); 557 558 if (!!args[2]) { 559 char sm[50]; 560 CopyStringOut(tc, sm, args[2], 50); 561 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc)); 562 } 563} 564 565void 566CPA::swWe(ThreadContext *tc) 567{ 568 if (!enabled()) 569 return; 570 571 char q[50]; 572 Arguments args(tc); 573 uint64_t id = args[0]; 574 CopyStringOut(tc, q, args[1], 50); 575 System *sys = tc->getSystemPtr(); 576 int32_t count = args[3]; 577 578 int sysi = getSys(sys); 579 StackId sid = StackId(sysi, getFrame(tc)); 580 if (!smStack[sid].size()) 581 return; 582 int smi = smStack[sid].back(); 583 int qi = getQ(sysi, q, id); 584 add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count); 585 586 if (!!args[2]) { 587 char sm[50]; 588 CopyStringOut(tc, sm, args[2], 50); 589 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc)); 590 } 591} 592 593void 594CPA::swSq(ThreadContext *tc) 595{ 596 if (!enabled()) 597 return; 598 599 char q[50]; 600 Arguments args(tc); 601 uint64_t id = args[0]; 602 CopyStringOut(tc, q, args[1], 50); 603 System *sys = tc->getSystemPtr(); 604 StringWrap name(sys->name()); 605 int32_t size = args[2]; 606 int flags = args[3]; 607 608 int sysi = getSys(sys); 609 StackId sid = StackId(sysi, getFrame(tc)); 610 if (!smStack[sid].size()) 611 return; 612 int smi = smStack[sid].back(); 613 int qi = getQ(sysi, q, id); 614 DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n", 615 q, id, qSize[qi-1], qBytes[qi-1], size); 616 617 if (FL_RESET & flags) { 618 DPRINTF(AnnotateQ, "Resetting Queue %s\n", q); 619 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0); 620 qData[qi-1].clear(); 621 qSize[qi-1] = 0; 622 qBytes[qi-1] = 0; 623 } 624 625 if (qBytes[qi-1] < size) 626 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]); 627 else if (qBytes[qi-1] > size) { 628 DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q); 629 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size); 630 if (size <= 0) { 631 qData[qi-1].clear(); 632 qSize[qi-1] = 0; 633 qBytes[qi-1] = 0; 634 return; 635 } 636 int need = qBytes[qi-1] - size; 637 qBytes[qi-1] = size; 638 while (need > 0) { 639 int32_t tail_bytes = qData[qi-1].back()->data; 640 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) { 641 dump(true); 642 dumpKey(); 643 fatal("Queue %s had inconsistancy when doing size queue!\n", q); 644 } 645 if (tail_bytes > need) { 646 qData[qi-1].back()->data -= need; 647 need = 0; 648 } else if (tail_bytes == need) { 649 qData[qi-1].pop_back(); 650 qSize[qi-1]--; 651 need = 0; 652 } else { 653 qData[qi-1].pop_back(); 654 qSize[qi-1]--; 655 need -= tail_bytes; 656 } 657 } 658 } 659} 660 661void 662CPA::swAq(ThreadContext *tc) 663{ 664 if (!enabled()) 665 return; 666 667 char q[50]; 668 Arguments args(tc); 669 uint64_t id = args[0]; 670 CopyStringOut(tc, q, args[1], 50); 671 System *sys = tc->getSystemPtr(); 672 StringWrap name(sys->name()); 673 int32_t size = args[2]; 674 675 int sysi = getSys(sys); 676 int qi = getQ(sysi, q, id); 677 if (qBytes[qi-1] != size) { 678 DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id); 679 //dump(true); 680 //dumpKey(); 681 std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin(); 682 int x = 0; 683 while (ai != qData[qi-1].end()) { 684 DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data); 685 ai++; 686 x++; 687 } 688 689 warn("%d: Queue Assert: SW said there should be %d byte(s) in %s," 690 "however there are %d byte(s)\n", 691 curTick, size, q, qBytes[qi-1]); 692 DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d" 693 " byte(s) in %s, however there are %d byte(s)\n", 694 curTick, size, q, qBytes[qi-1]); 695 } 696} 697 698void 699CPA::swLink(ThreadContext *tc) 700{ 701 if (!enabled()) 702 return; 703 704 char lsm[50]; 705 Arguments args(tc); 706 CopyStringOut(tc, lsm, args[0], 50); 707 System *sys = tc->getSystemPtr(); 708 StringWrap name(sys->name()); 709 710 int sysi = getSys(sys); 711 StackId sid = StackId(sysi, getFrame(tc)); 712 if (!smStack[sid].size()) 713 return; 714 int smi = smStack[sid].back(); 715 int lsmi = getSm(sysi, lsm, args[1]); 716 717 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n", 718 smi, lsm, lsmi, args[1]); 719 720 if (lnMap[lsmi]) 721 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n", 722 lsmi, lnMap[lsmi]); 723 assert(lnMap[lsmi] == 0); 724 lnMap[lsmi] = smi; 725 726 add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi); 727 728 if (!!args[2]) { 729 char sm[50]; 730 CopyStringOut(tc, sm, args[2], 50); 731 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc)); 732 } 733} 734 735void 736CPA::swIdentify(ThreadContext *tc) 737{ 738 if (!enabled()) 739 return; 740 741 Arguments args(tc); 742 int sysi = getSys(tc->getSystemPtr()); 743 StackId sid = StackId(sysi, getFrame(tc)); 744 if (!smStack[sid].size()) 745 return; 746 int smi = smStack[sid].back(); 747 748 DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]); 749 750 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]); 751} 752 753uint64_t 754CPA::swGetId(ThreadContext *tc) 755{ 756 if (!enabled()) 757 return 0; 758 759 uint64_t id = ++conId; 760 int sysi = getSys(tc->getSystemPtr()); 761 StackId sid = StackId(sysi, getFrame(tc)); 762 if (!smStack[sid].size()) 763 panic("swGetId called without a state machine stack!"); 764 int smi = smStack[sid].back(); 765 766 DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id); 767 768 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id); 769 return id; 770} 771 772 773void 774CPA::swSyscallLink(ThreadContext *tc) 775{ 776 if (!enabled()) 777 return; 778 779 char lsm[50]; 780 Arguments args(tc); 781 CopyStringOut(tc, lsm, args[0], 50); 782 System *sys = tc->getSystemPtr(); 783 StringWrap name(sys->name()); 784 int sysi = getSys(sys); 785 786 Id id = Id(lsm, getFrame(tc)); 787 StackId sid = StackId(sysi, getFrame(tc)); 788 789 if (!smStack[sid].size()) 790 return; 791 792 int smi = smStack[sid].back(); 793 794 DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n", 795 smi, lsm); 796 797 if (scLinks[sysi-1][id]) 798 DPRINTF(Annotate, 799 "scLinks already contains entry for system %d %s[%x] of %d\n", 800 sysi, lsm, getFrame(tc), scLinks[sysi-1][id]); 801 assert(scLinks[sysi-1][id] == 0); 802 scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF); 803 scLinks[sysi-1][id]->dump = false; 804 805 if (!!args[1]) { 806 char sm[50]; 807 CopyStringOut(tc, sm, args[1], 50); 808 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc)); 809 } 810} 811 812CPA::AnnDataPtr 813CPA::add(int t, int f, int c, int sm, int stq, int32_t d) 814{ 815 AnnDataPtr an = new AnnotateData; 816 an->time = curTick; 817 an->data = d; 818 an->orig_data = d; 819 an->op = t; 820 an->flag = f; 821 an->sm = sm; 822 an->stq = stq; 823 an->cpu = c; 824 an->dump = true; 825 826 data.push_back(an); 827 828 DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n", 829 an->op, an->flag, an->sm, an->stq, an->time, an->data); 830 831 // Don't dump Links because we might be setting no-dump on it 832 if (an->op != OP_LINK) 833 dump(false); 834 835 return an; 836} 837 838void 839CPA::dumpKey() 840{ 841 std::streampos curpos = osbin->tellp(); 842 ah.key_off = curpos; 843 844 // Output the various state machines and their corresponding states 845 *osbin << "# Automatically generated state machine descriptor file" << endl; 846 847 *osbin << "sms = {}" << endl << endl; 848 vector<string> state_machines; 849 state_machines.resize(numSmt+1); 850 851 // State machines, id -> states 852 SCache::iterator i = smtCache.begin(); 853 while (i != smtCache.end()) { 854 state_machines[i->second] = i->first; 855 i++; 856 } 857 858 for (int x = 1; x < state_machines.size(); x++) { 859 vector<string> states; 860 states.resize(numSt[x-1]+1); 861 assert(x-1 < stCache.size()); 862 SCache::iterator i = stCache[x-1].begin(); 863 while (i != stCache[x-1].end()) { 864 states[i->second] = i->first; 865 i++; 866 } 867 *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\""; 868 for (int y = 1; y < states.size(); y++) 869 *osbin << ", \"" << states[y] << "\""; 870 *osbin << "]" << endl; 871 } 872 873 *osbin << endl << endl << endl; 874 875 // state machine number -> system, name, id 876 *osbin << "smNum = [\"NULL\""; 877 for (int x = 0; x < smMap.size(); x++) 878 *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first << 879 "\", " << smMap[x].second.second << ")"; 880 *osbin << "]" << endl; 881 882 *osbin << endl << endl << endl; 883 884 // Output the systems 885 vector<string> systems; 886 systems.resize(numSys+1); 887 NameCache::iterator i2 = nameCache.begin(); 888 while (i2 != nameCache.end()) { 889 systems[i2->second.second] = i2->second.first; 890 i2++; 891 } 892 893 *osbin << "sysNum = [\"NULL\""; 894 for (int x = 1; x < systems.size(); x++) { 895 *osbin << ", \"" << systems[x] << "\""; 896 } 897 *osbin << "]" << endl; 898 899 // queue number -> system, qname, qid 900 *osbin << "queues = [\"NULL\""; 901 for (int x = 0; x < qMap.size(); x++) 902 *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first << 903 "\", " << qMap[x].second.second << ")"; 904 *osbin << "]" << endl; 905 906 *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) " 907 << "for r in xrange (1,len(smNum))]]" << endl; 908 ah.key_len = osbin->tellp() - curpos; 909 910 // output index 911 curpos = osbin->tellp(); 912 ah.idx_off = curpos; 913 914 for (int x = 0; x < annotateIdx.size(); x++) 915 osbin->write((char*)&annotateIdx[x], sizeof(uint64_t)); 916 ah.idx_len = osbin->tellp() - curpos; 917 918 osbin->seekp(0); 919 osbin->write((char*)&ah, sizeof(AnnotateHeader)); 920 osbin->flush(); 921 922} 923 924void 925CPA::dump(bool all) 926{ 927 928 list<AnnDataPtr>::iterator i; 929 930 i = data.begin(); 931 932 if (i == data.end()) 933 return; 934 935 // Dump the data every 936 if (!all && data.size() < 10000) 937 return; 938 939 DPRINTF(Annotate, "Writing %d\n", data.size()); 940 while (i != data.end()) { 941 AnnDataPtr an = *i; 942 943 // If we can't dump this record, hold here 944 if (!an->dump && !all) 945 break; 946 947 ah.num_recs++; 948 if (ah.num_recs % 100000 == 0) 949 annotateIdx.push_back(osbin->tellp()); 950 951 952 osbin->write((char*)&(an->time), sizeof(an->time)); 953 osbin->write((char*)&(an->orig_data), sizeof(an->orig_data)); 954 osbin->write((char*)&(an->sm), sizeof(an->sm)); 955 osbin->write((char*)&(an->stq), sizeof(an->stq)); 956 osbin->write((char*)&(an->op), sizeof(an->op)); 957 osbin->write((char*)&(an->flag), sizeof(an->flag)); 958 osbin->write((char*)&(an->cpu), sizeof(an->cpu)); 959 i++; 960 } 961 if (data.begin() != i) 962 data.erase(data.begin(), i); 963 964 if (all) 965 osbin->flush(); 966} 967 968void 969CPA::doQ(System *sys, int flags, int cpuid, int sm, 970 string q, int qi, int count) 971{ 972 qSize[qi-1]++; 973 qBytes[qi-1] += count; 974 if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000) 975 warn("Queue %s is %d elements/%d bytes, " 976 "maybe things aren't being removed?\n", 977 q, qSize[qi-1], qBytes[qi-1]); 978 if (flags & FL_QOPP) 979 qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count)); 980 else 981 qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count)); 982 DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n", 983 q, qSize[qi-1], qBytes[qi-1]); 984 assert(qSize[qi-1] >= 0); 985 assert(qBytes[qi-1] >= 0); 986} 987 988 989void 990CPA::doDq(System *sys, int flags, int cpuid, int sm, 991 string q, int qi, int count) 992{ 993 994 StringWrap name(sys->name()); 995 if (count == -1) { 996 add(OP_DEQUEUE, flags, cpuid, sm, qi, count); 997 qData[qi-1].clear(); 998 qSize[qi-1] = 0; 999 qBytes[qi-1] = 0; 1000 DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n", 1001 q, qSize[qi-1], qBytes[qi-1]); 1002 return; 1003 } 1004 1005 assert(count > 0); 1006 if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) { 1007 dump(true); 1008 dumpKey(); 1009 fatal("Queue %s dequing with no data available in queue!\n", 1010 q); 1011 } 1012 assert(qSize[qi-1] >= 0); 1013 assert(qBytes[qi-1] >= 0); 1014 assert(qData[qi-1].size()); 1015 1016 int32_t need = count; 1017 qBytes[qi-1] -= count; 1018 if (qBytes[qi-1] < 0) { 1019 dump(true); 1020 dumpKey(); 1021 fatal("Queue %s dequing with no bytes available in queue!\n", 1022 q); 1023 } 1024 1025 while (need > 0) { 1026 int32_t head_bytes = qData[qi-1].front()->data; 1027 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) { 1028 dump(true); 1029 dumpKey(); 1030 fatal("Queue %s dequing with nothing in queue!\n", 1031 q); 1032 } 1033 1034 if (head_bytes > need) { 1035 qData[qi-1].front()->data -= need; 1036 need = 0; 1037 } else if (head_bytes == need) { 1038 qData[qi-1].pop_front(); 1039 qSize[qi-1]--; 1040 need = 0; 1041 } else { 1042 qData[qi-1].pop_front(); 1043 qSize[qi-1]--; 1044 need -= head_bytes; 1045 } 1046 } 1047 1048 add(OP_DEQUEUE, flags, cpuid, sm, qi, count); 1049 DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n", 1050 q, qSize[qi-1], qBytes[qi-1]); 1051} 1052 1053 1054 1055void 1056CPA::serialize(std::ostream &os) 1057{ 1058 1059 SERIALIZE_SCALAR(numSm); 1060 SERIALIZE_SCALAR(numSmt); 1061 arrayParamOut(os, "numSt", numSt); 1062 arrayParamOut(os, "numQ", numQ); 1063 SERIALIZE_SCALAR(numSys); 1064 SERIALIZE_SCALAR(numQs); 1065 SERIALIZE_SCALAR(conId); 1066 arrayParamOut(os, "qSize", qSize); 1067 arrayParamOut(os, "qSize", qSize); 1068 arrayParamOut(os, "qBytes", qBytes); 1069 1070 std::list<AnnDataPtr>::iterator ai; 1071 1072 SCache::iterator i; 1073 int x = 0, y = 0; 1074 1075 // smtCache (SCache) 1076 x = 0; 1077 y = 0; 1078 i = smtCache.begin(); 1079 while (i != smtCache.end()) { 1080 paramOut(os, csprintf("smtCache%d.str", x), i->first); 1081 paramOut(os, csprintf("smtCache%d.int", x), i->second); 1082 x++; i++; 1083 } 1084 1085 // stCache (StCache) 1086 for (x = 0; x < stCache.size(); x++) { 1087 i = stCache[x].begin(); 1088 y = 0; 1089 while (i != stCache[x].end()) { 1090 paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first); 1091 paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second); 1092 y++; i++; 1093 } 1094 } 1095 1096 // qCache (IdCache) 1097 IdHCache::iterator idi; 1098 for (x = 0; x < qCache.size(); x++) { 1099 idi = qCache[x].begin(); 1100 y = 0; 1101 while (idi != qCache[x].end()) { 1102 paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first); 1103 paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second); 1104 paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second); 1105 y++; idi++; 1106 } 1107 } 1108 1109 // smCache (IdCache) 1110 for (x = 0; x < smCache.size(); x++) { 1111 idi = smCache[x].begin(); 1112 y = 0; 1113 paramOut(os, csprintf("smCache%d", x), smCache[x].size()); 1114 while (idi != smCache[x].end()) { 1115 paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first); 1116 paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second); 1117 paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second); 1118 y++; idi++; 1119 } 1120 } 1121 1122 // scLinks (ScCache) -- data not serialize 1123 1124 1125 // namecache (NameCache) 1126 NameCache::iterator ni; 1127 1128 ni = nameCache.begin(); 1129 x = 0; 1130 while (ni != nameCache.end()) { 1131 paramOut(os, csprintf("nameCache%d.name", x), ni->first->name()); 1132 paramOut(os, csprintf("nameCache%d.str", x), ni->second.first); 1133 paramOut(os, csprintf("nameCache%d.int", x), ni->second.second); 1134 x++; ni++; 1135 } 1136 1137 // smStack (SmStack) 1138 SmStack::iterator si; 1139 si = smStack.begin(); 1140 x = 0; 1141 paramOut(os, "smStackIdCount", smStack.size()); 1142 while (si != smStack.end()) { 1143 paramOut(os, csprintf("smStackId%d.sys", x), si->first.first); 1144 paramOut(os, csprintf("smStackId%d.frame", x), si->first.second); 1145 paramOut(os, csprintf("smStackId%d.count", x), si->second.size()); 1146 for (y = 0; y < si->second.size(); y++) 1147 paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]); 1148 x++; si++; 1149 } 1150 1151 // lnMap (LinkMap) 1152 x = 0; 1153 LinkMap::iterator li; 1154 li = lnMap.begin(); 1155 paramOut(os, "lnMapSize", lnMap.size()); 1156 while (li != lnMap.end()) { 1157 paramOut(os, csprintf("lnMap%d.smi", x), li->first); 1158 paramOut(os, csprintf("lnMap%d.lsmi", x), li->second); 1159 x++; li++; 1160 } 1161 1162 // swExpl (vector) 1163 SwExpl::iterator swexpli; 1164 swexpli = swExpl.begin(); 1165 x = 0; 1166 paramOut(os, "swExplCount", swExpl.size()); 1167 while (swexpli != swExpl.end()) { 1168 paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first); 1169 paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second); 1170 paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second); 1171 x++; swexpli++; 1172 } 1173 1174 // lastState (IMap) 1175 x = 0; 1176 IMap::iterator ii; 1177 ii = lastState.begin(); 1178 paramOut(os, "lastStateSize", lastState.size()); 1179 while (ii != lastState.end()) { 1180 paramOut(os, csprintf("lastState%d.smi", x), ii->first); 1181 paramOut(os, csprintf("lastState%d.sti", x), ii->second); 1182 x++; ii++; 1183 } 1184 1185 // smMap (IdMap) 1186 for (x = 0; x < smMap.size(); x++) { 1187 paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first); 1188 paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first); 1189 paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second); 1190 } 1191 1192 // qMap (IdMap) 1193 for (x = 0; x < qMap.size(); x++) { 1194 paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first); 1195 paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first); 1196 paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second); 1197 } 1198 1199 // qData (vector<AnnotateList>) 1200 for(x = 0; x < qData.size(); x++) { 1201 if (!qData[x].size()) 1202 continue; 1203 y = 0; 1204 ai = qData[x].begin(); 1205 while (ai != qData[x].end()) { 1206 nameOut(os, csprintf("%s.Q%d_%d", name(), x, y)); 1207 (*ai)->serialize(os); 1208 ai++; 1209 y++; 1210 } 1211 } 1212} 1213 1214void 1215CPA::unserialize(Checkpoint *cp, const std::string §ion) 1216{ 1217 UNSERIALIZE_SCALAR(numSm); 1218 UNSERIALIZE_SCALAR(numSmt); 1219 arrayParamIn(cp, section, "numSt", numSt); 1220 arrayParamIn(cp, section, "numQ", numQ); 1221 UNSERIALIZE_SCALAR(numSys); 1222 UNSERIALIZE_SCALAR(numQs); 1223 UNSERIALIZE_SCALAR(conId); 1224 arrayParamIn(cp, section, "qSize", qSize); 1225 arrayParamIn(cp, section, "qBytes", qBytes); 1226 1227 1228 // smtCache (SCache 1229 string str; 1230 int smi; 1231 for (int x = 0; x < numSmt; x++) { 1232 paramIn(cp, section, csprintf("smtCache%d.str", x), str); 1233 paramIn(cp, section, csprintf("smtCache%d.int", x), smi); 1234 smtCache[str] = smi; 1235 } 1236 1237 // stCache (StCache) 1238 stCache.resize(numSmt); 1239 for (int x = 0; x < numSmt; x++) { 1240 for (int y = 0; y < numSt[x]; y++) { 1241 paramIn(cp, section, csprintf("stCache%d_%d.str", x,y), str); 1242 paramIn(cp, section, csprintf("stCache%d_%d.int", x,y), smi); 1243 stCache[x][str] = smi; 1244 } 1245 } 1246 1247 // qCache (IdCache) 1248 uint64_t id; 1249 qCache.resize(numSys); 1250 for (int x = 0; x < numSys; x++) { 1251 for (int y = 0; y < numQ[x]; y++) { 1252 paramIn(cp, section, csprintf("qCache%d_%d.str", x,y), str); 1253 paramIn(cp, section, csprintf("qCache%d_%d.id", x,y), id); 1254 paramIn(cp, section, csprintf("qCache%d_%d.int", x,y), smi); 1255 qCache[x][Id(str,id)] = smi; 1256 } 1257 } 1258 1259 // smCache (IdCache) 1260 smCache.resize(numSys); 1261 for (int x = 0; x < numSys; x++) { 1262 int size; 1263 paramIn(cp, section, csprintf("smCache%d", x), size); 1264 for (int y = 0; y < size; y++) { 1265 paramIn(cp, section, csprintf("smCache%d_%d.str", x,y), str); 1266 paramIn(cp, section, csprintf("smCache%d_%d.id", x,y), id); 1267 paramIn(cp, section, csprintf("smCache%d_%d.int", x,y), smi); 1268 smCache[x][Id(str,id)] = smi; 1269 } 1270 } 1271 1272 // scLinks (ScCache) -- data not serialized, just creating one per sys 1273 for (int x = 0; x < numSys; x++) 1274 scLinks.push_back(ScHCache()); 1275 1276 // nameCache (NameCache) 1277 for (int x = 0; x < numSys; x++) { 1278 System *sys; 1279 SimObject *sptr; 1280 string str; 1281 int sysi; 1282 1283 objParamIn(cp, section, csprintf("nameCache%d.name", x), sptr); 1284 sys = dynamic_cast<System*>(sptr); 1285 1286 paramIn(cp, section, csprintf("nameCache%d.str", x), str); 1287 paramIn(cp, section, csprintf("nameCache%d.int", x), sysi); 1288 nameCache[sys] = std::make_pair<std::string,int>(str, sysi); 1289 } 1290 1291 //smStack (SmStack) 1292 int smStack_size; 1293 paramIn(cp, section, "smStackIdCount", smStack_size); 1294 for (int x = 0; x < smStack_size; x++) { 1295 int sysi; 1296 uint64_t frame; 1297 int count; 1298 paramIn(cp, section, csprintf("smStackId%d.sys", x), sysi); 1299 paramIn(cp, section, csprintf("smStackId%d.frame", x), frame); 1300 paramIn(cp, section, csprintf("smStackId%d.count", x), count); 1301 StackId sid = StackId(sysi, frame); 1302 for (int y = 0; y < count; y++) { 1303 paramIn(cp, section, csprintf("smStackId%d_%d", x, y), smi); 1304 smStack[sid].push_back(smi); 1305 } 1306 } 1307 1308 // lnMap (LinkMap) 1309 int lsmi; 1310 int lnMap_size; 1311 paramIn(cp, section, "lnMapSize", lnMap_size); 1312 for (int x = 0; x < lnMap_size; x++) { 1313 paramIn(cp, section, csprintf("lnMap%d.smi", x), smi); 1314 paramIn(cp, section, csprintf("lnMap%d.lsmi", x), lsmi); 1315 lnMap[smi] = lsmi; 1316 } 1317 1318 // swExpl (vector) 1319 int swExpl_size; 1320 paramIn(cp, section, "swExplCount", swExpl_size); 1321 for (int x = 0; x < swExpl_size; x++) { 1322 int sysi; 1323 uint64_t frame; 1324 bool b; 1325 paramIn(cp, section, csprintf("swExpl%d.sys", x), sysi); 1326 paramIn(cp, section, csprintf("swExpl%d.frame", x), frame); 1327 paramIn(cp, section, csprintf("swExpl%d.swexpl", x), b); 1328 StackId sid = StackId(sysi, frame); 1329 swExpl[sid] = b; 1330 } 1331 1332 // lastState (IMap) 1333 int sti; 1334 int lastState_size; 1335 paramIn(cp, section, "lastStateSize", lastState_size); 1336 for (int x = 0; x < lastState_size; x++) { 1337 paramIn(cp, section, csprintf("lastState%d.smi", x), smi); 1338 paramIn(cp, section, csprintf("lastState%d.sti", x), sti); 1339 lastState[smi] = sti; 1340 } 1341 1342 1343 //smMap (IdMap) 1344 smMap.resize(numSm); 1345 for (int x = 0; x < smMap.size(); x++) { 1346 paramIn(cp, section, csprintf("smMap%d.sys", x), smMap[x].first); 1347 paramIn(cp, section, csprintf("smMap%d.smname", x), smMap[x].second.first); 1348 paramIn(cp, section, csprintf("smMap%d.id", x), smMap[x].second.second); 1349 } 1350 1351 //qMap (IdMap) 1352 qMap.resize(numQs); 1353 for (int x = 0; x < qMap.size(); x++) { 1354 paramIn(cp, section, csprintf("qMap%d.sys", x), qMap[x].first); 1355 paramIn(cp, section, csprintf("qMap%d.qname", x), qMap[x].second.first); 1356 paramIn(cp, section, csprintf("qMap%d.id", x), qMap[x].second.second); 1357 } 1358 1359 1360 // qData (vector<AnnotateList>) 1361 qData.resize(qSize.size()); 1362 for (int x = 0; x < qSize.size(); x++) { 1363 if (!qSize[x]) 1364 continue; 1365 for (int y = 0; y < qSize[x]; y++) { 1366 AnnDataPtr a = new AnnotateData; 1367 a->unserialize(cp, csprintf("%s.Q%d_%d", section, x, y)); 1368 data.push_back(a); 1369 qData[x].push_back(a); 1370 } 1371 } 1372} 1373 1374void 1375CPA::AnnotateData::serialize(std::ostream &os) 1376{ 1377 SERIALIZE_SCALAR(time); 1378 SERIALIZE_SCALAR(data); 1379 SERIALIZE_SCALAR(sm); 1380 SERIALIZE_SCALAR(stq); 1381 SERIALIZE_SCALAR(op); 1382 SERIALIZE_SCALAR(flag); 1383 SERIALIZE_SCALAR(cpu); 1384} 1385 1386void 1387CPA::AnnotateData::unserialize(Checkpoint *cp, const std::string §ion) 1388{ 1389 UNSERIALIZE_SCALAR(time); 1390 UNSERIALIZE_SCALAR(data); 1391 orig_data = data; 1392 UNSERIALIZE_SCALAR(sm); 1393 UNSERIALIZE_SCALAR(stq); 1394 UNSERIALIZE_SCALAR(op); 1395 UNSERIALIZE_SCALAR(flag); 1396 UNSERIALIZE_SCALAR(cpu); 1397 dump = true; 1398} 1399 1400CPA* 1401CPAParams::create() 1402{ 1403 return new CPA(this); 1404} 1405 1406