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