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