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