cp_annotate.cc revision 11321
14403Srdreslin@umich.edu/* 21693Sstever@eecs.umich.edu * Copyright (c) 2006-2009 The Regents of The University of Michigan 31693Sstever@eecs.umich.edu * All rights reserved. 41693Sstever@eecs.umich.edu * 51693Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 61693Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 71693Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 81693Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 91693Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 101693Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 111693Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 121693Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 131693Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 141693Sstever@eecs.umich.edu * this software without specific prior written permission. 151693Sstever@eecs.umich.edu * 161693Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171693Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181693Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191693Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201693Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211693Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221693Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231693Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241693Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251693Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261693Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271693Sstever@eecs.umich.edu * 281693Sstever@eecs.umich.edu * Authors: Ali Saidi 293358Srdreslin@umich.edu */ 303358Srdreslin@umich.edu 311516SN/A#include "arch/generic/linux/threadinfo.hh" 323358Srdreslin@umich.edu#include "arch/utility.hh" 333358Srdreslin@umich.edu#include "base/loader/object_file.hh" 343358Srdreslin@umich.edu#include "base/callback.hh" 353358Srdreslin@umich.edu#include "base/cp_annotate.hh" 361516SN/A#include "base/output.hh" 373358Srdreslin@umich.edu#include "base/trace.hh" 383358Srdreslin@umich.edu#include "config/the_isa.hh" 393358Srdreslin@umich.edu#include "cpu/thread_context.hh" 403358Srdreslin@umich.edu#include "debug/Annotate.hh" 413358Srdreslin@umich.edu#include "debug/AnnotateVerbose.hh" 423358Srdreslin@umich.edu#include "sim/arguments.hh" 433358Srdreslin@umich.edu#include "sim/core.hh" 443358Srdreslin@umich.edu#include "sim/sim_exit.hh" 453358Srdreslin@umich.edu#include "sim/system.hh" 463358Srdreslin@umich.edu 473358Srdreslin@umich.edustruct CPAIgnoreSymbol 483358Srdreslin@umich.edu{ 493360Srdreslin@umich.edu const char *symbol; 503358Srdreslin@umich.edu size_t len; 513358Srdreslin@umich.edu}; 523358Srdreslin@umich.edu#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) } 533358Srdreslin@umich.edu 543360Srdreslin@umich.eduCPAIgnoreSymbol ignoreSymbols[] = { 553360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("m5a_"), 563360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("ret_from_sys_call"), 573360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("ret_from_reschedule"), 583360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("_spin_"), 593360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("local_bh_"), 603360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("restore_all"), 613360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("Call_Pal_"), 623358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("pal_post_interrupt"), 634403Srdreslin@umich.edu CPA_IGNORE_SYMBOL("rti_to_"), 643360Srdreslin@umich.edu CPA_IGNORE_SYMBOL("sys_int_2"), 653358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("sys_interrupt"), 663358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("normal_int"), 673358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"), 683358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("Trap_Interrupt"), 693358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("do_entInt"), 703358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("__do_softirq"), 713358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("_end"), 723358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("entInt"), 733358Srdreslin@umich.edu CPA_IGNORE_SYMBOL("entSys"), 743360Srdreslin@umich.edu {0,0} 753360Srdreslin@umich.edu}; 763360Srdreslin@umich.edu#undef CPA_IGNORE_SYMBOL 773360Srdreslin@umich.edu 783358Srdreslin@umich.eduusing namespace std; 793358Srdreslin@umich.eduusing namespace TheISA; 803358Srdreslin@umich.edu 813358Srdreslin@umich.edubool CPA::exists; 824403Srdreslin@umich.eduCPA *CPA::_cpa; 834403Srdreslin@umich.edu 844403Srdreslin@umich.educlass AnnotateDumpCallback : public Callback 854403Srdreslin@umich.edu{ 863358Srdreslin@umich.edu 873358Srdreslin@umich.edu private: 884403Srdreslin@umich.edu CPA *cpa; 894403Srdreslin@umich.edu public: 904403Srdreslin@umich.edu virtual void process(); 913358Srdreslin@umich.edu AnnotateDumpCallback(CPA *_cpa) 923358Srdreslin@umich.edu : cpa(_cpa) 934403Srdreslin@umich.edu {} 944403Srdreslin@umich.edu}; 954403Srdreslin@umich.edu 963358Srdreslin@umich.eduvoid 973358Srdreslin@umich.eduAnnotateDumpCallback::process() 984403Srdreslin@umich.edu{ 994403Srdreslin@umich.edu cpa->dump(true); 1004403Srdreslin@umich.edu cpa->dumpKey(); 1013358Srdreslin@umich.edu} 1023358Srdreslin@umich.edu 1034403Srdreslin@umich.edu 1044403Srdreslin@umich.eduCPA::CPA(Params *p) 1054403Srdreslin@umich.edu : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0) 1063358Srdreslin@umich.edu{ 1073358Srdreslin@umich.edu if (exists) 1084403Srdreslin@umich.edu fatal("Multiple annotation objects found in system"); 1094403Srdreslin@umich.edu exists = true; 1104403Srdreslin@umich.edu 1114403Srdreslin@umich.edu _enabled = p->enabled; 1123358Srdreslin@umich.edu _cpa = this; 1133358Srdreslin@umich.edu 1144403Srdreslin@umich.edu vector<string>::iterator i; 1154403Srdreslin@umich.edu i = p->user_apps.begin(); 1164403Srdreslin@umich.edu 1174403Srdreslin@umich.edu while (i != p->user_apps.end()) { 1184403Srdreslin@umich.edu ObjectFile *of = createObjectFile(*i); 1193360Srdreslin@umich.edu string sf; 1204403Srdreslin@umich.edu if (!of) 1213358Srdreslin@umich.edu fatal("Couldn't load symbols from file: %s\n", *i); 1223358Srdreslin@umich.edu sf = *i; 1234403Srdreslin@umich.edu sf.erase(0, sf.rfind('/') + 1);; 1244403Srdreslin@umich.edu DPRINTFN("file %s short: %s\n", *i, sf); 1254403Srdreslin@umich.edu userApp[sf] = new SymbolTable; 1263358Srdreslin@umich.edu bool result1 = of->loadGlobalSymbols(userApp[sf]); 1273358Srdreslin@umich.edu bool result2 = of->loadLocalSymbols(userApp[sf]); 1284403Srdreslin@umich.edu if (!result1 || !result2) 1294403Srdreslin@umich.edu panic("blah"); 1304403Srdreslin@umich.edu assert(result1 && result2); 1313358Srdreslin@umich.edu i++; 1323358Srdreslin@umich.edu } 1334403Srdreslin@umich.edu} 1344403Srdreslin@umich.edu 1354403Srdreslin@umich.eduvoid 1364403Srdreslin@umich.eduCPA::startup() 1373358Srdreslin@umich.edu{ 1383358Srdreslin@umich.edu osbin = simout.create("annotate.bin", true); 1394403Srdreslin@umich.edu // MAGIC version number 'M''5''A'N' + version/capabilities 1404403Srdreslin@umich.edu ah.version = 0x4D35414E00000101ULL; 1414403Srdreslin@umich.edu ah.num_recs = 0; 1424403Srdreslin@umich.edu ah.key_off = 0; 1434403Srdreslin@umich.edu osbin->write((char*)&ah, sizeof(AnnotateHeader)); 1443360Srdreslin@umich.edu 1454403Srdreslin@umich.edu registerExitCallback(new AnnotateDumpCallback(this)); 1463358Srdreslin@umich.edu} 1473358Srdreslin@umich.edu 1484403Srdreslin@umich.eduuint64_t 1494403Srdreslin@umich.eduCPA::getFrame(ThreadContext *tc) 1504403Srdreslin@umich.edu{ 1514403Srdreslin@umich.edu // This code is ISA specific and will need to be changed 1524403Srdreslin@umich.edu // if the annotation code is used for something other than Alpha 1533360Srdreslin@umich.edu return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) & 1544403Srdreslin@umich.edu ~ULL(0x3FFF)); 1553358Srdreslin@umich.edu 1563358Srdreslin@umich.edu} 1573358Srdreslin@umich.edu 1583358Srdreslin@umich.eduvoid 1593358Srdreslin@umich.eduCPA::swSmBegin(ThreadContext *tc) 1603358Srdreslin@umich.edu{ 1613358Srdreslin@umich.edu if (!enabled()) 1623358Srdreslin@umich.edu return; 1633358Srdreslin@umich.edu 1643358Srdreslin@umich.edu Arguments args(tc); 1653358Srdreslin@umich.edu std::string st; 1663358Srdreslin@umich.edu Addr junk; 1673358Srdreslin@umich.edu char sm[50]; 1683358Srdreslin@umich.edu if (!TheISA::inUserMode(tc)) 1693358Srdreslin@umich.edu debugSymbolTable->findNearestSymbol( 1703358Srdreslin@umich.edu tc->readIntReg(ReturnAddressReg), st, junk); 1713358Srdreslin@umich.edu 1723358Srdreslin@umich.edu CopyStringOut(tc, sm, args[0], 50); 1733358Srdreslin@umich.edu System *sys = tc->getSystemPtr(); 1743358Srdreslin@umich.edu StringWrap name(sys->name()); 1753358Srdreslin@umich.edu 1763358Srdreslin@umich.edu if (!sm[0]) 1773358Srdreslin@umich.edu warn("Got null SM at tick %d\n", curTick()); 1783358Srdreslin@umich.edu 1793358Srdreslin@umich.edu int sysi = getSys(sys); 1803358Srdreslin@umich.edu int smi = getSm(sysi, sm, args[1]); 1813358Srdreslin@umich.edu DPRINTF(Annotate, "Starting machine: %s(%d) sysi: %d id: %#x\n", sm, 1823358Srdreslin@umich.edu smi, sysi, args[1]); 1833358Srdreslin@umich.edu DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi, 1843358Srdreslin@umich.edu smMap[smi-1].first, smMap[smi-1].second.first, 1853358Srdreslin@umich.edu smMap[smi-1].second.second); 1863358Srdreslin@umich.edu 1873358Srdreslin@umich.edu uint64_t frame = getFrame(tc); 1883358Srdreslin@umich.edu StackId sid = StackId(sysi, frame); 1893358Srdreslin@umich.edu 1903358Srdreslin@umich.edu // check if we need to link to the previous state machine 1913358Srdreslin@umich.edu int flags = args[2]; 1921516SN/A if (flags & FL_LINK) { 1933358Srdreslin@umich.edu if (smStack[sid].size()) { 1943358Srdreslin@umich.edu int prev_smi = smStack[sid].back(); 1953358Srdreslin@umich.edu DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n", 1961516SN/A prev_smi, sm, smi, args[1]); 1973358Srdreslin@umich.edu 1983358Srdreslin@umich.edu if (lnMap[smi]) 1993358Srdreslin@umich.edu DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n", 2003358Srdreslin@umich.edu smi, lnMap[smi]); 2013358Srdreslin@umich.edu assert(lnMap[smi] == 0); 2021516SN/A lnMap[smi] = prev_smi; 2033358Srdreslin@umich.edu 2043358Srdreslin@umich.edu add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi); 2053358Srdreslin@umich.edu } else { 2063358Srdreslin@umich.edu DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n", 2073358Srdreslin@umich.edu sm, smi, args[1]); 2083358Srdreslin@umich.edu } 2093358Srdreslin@umich.edu } 2103358Srdreslin@umich.edu 2113358Srdreslin@umich.edu 2123358Srdreslin@umich.edu smStack[sid].push_back(smi); 2133358Srdreslin@umich.edu 2143358Srdreslin@umich.edu DPRINTF(Annotate, "Stack Now (%#X):\n", frame); 2153358Srdreslin@umich.edu for (int x = smStack[sid].size()-1; x >= 0; x--) 2163358Srdreslin@umich.edu DPRINTF(Annotate, "-- %d\n", smStack[sid][x]); 2173358Srdreslin@umich.edu 2183358Srdreslin@umich.edu // reset the sw state exculsion to false 2193358Srdreslin@umich.edu if (swExpl[sid]) 2203358Srdreslin@umich.edu swExpl[sid] = false; 2213358Srdreslin@umich.edu 2223358Srdreslin@umich.edu 2233358Srdreslin@umich.edu Id id = Id(sm, frame); 2243358Srdreslin@umich.edu if (scLinks[sysi-1][id]) { 2253358Srdreslin@umich.edu AnnDataPtr an = scLinks[sysi-1][id]; 2263358Srdreslin@umich.edu scLinks[sysi-1].erase(id); 2273358Srdreslin@umich.edu an->stq = smi; 2283358Srdreslin@umich.edu an->dump = true; 2293358Srdreslin@umich.edu DPRINTF(Annotate, 2303358Srdreslin@umich.edu "Found prev unknown linking from %d to state machine %s(%d)\n", 2313358Srdreslin@umich.edu an->sm, sm, smi); 2323358Srdreslin@umich.edu 2333358Srdreslin@umich.edu if (lnMap[smi]) 2343358Srdreslin@umich.edu DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n", 2353358Srdreslin@umich.edu smi, lnMap[smi]); 2363358Srdreslin@umich.edu assert(lnMap[smi] == 0); 2373358Srdreslin@umich.edu lnMap[smi] = an->sm; 2383358Srdreslin@umich.edu } 2393358Srdreslin@umich.edu 2403358Srdreslin@umich.edu // add a new begin ifwe have that info 2413358Srdreslin@umich.edu if (st != "") { 2423358Srdreslin@umich.edu DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st, 2433358Srdreslin@umich.edu smi, stCache.size()); 2443358Srdreslin@umich.edu int sti = getSt(sm, st); 2453358Srdreslin@umich.edu lastState[smi] = sti; 2463358Srdreslin@umich.edu add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti); 2473358Srdreslin@umich.edu } 2483358Srdreslin@umich.edu} 2493358Srdreslin@umich.edu 2503358Srdreslin@umich.eduvoid 2513358Srdreslin@umich.eduCPA::swSmEnd(ThreadContext *tc) 2523358Srdreslin@umich.edu{ 2533358Srdreslin@umich.edu if (!enabled()) 2543358Srdreslin@umich.edu return; 2553358Srdreslin@umich.edu 2563358Srdreslin@umich.edu Arguments args(tc); 2573358Srdreslin@umich.edu char sm[50]; 2581516SN/A CopyStringOut(tc, sm, args[0], 50); 2593358Srdreslin@umich.edu System *sys = tc->getSystemPtr(); 2601516SN/A doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc)); 2611516SN/A} 2621516SN/A 2633358Srdreslin@umich.eduvoid 2643358Srdreslin@umich.eduCPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame) 2653358Srdreslin@umich.edu{ 2663358Srdreslin@umich.edu int sysi = getSys(sys); 2673358Srdreslin@umich.edu StackId sid = StackId(sysi, frame); 2683358Srdreslin@umich.edu 2693358Srdreslin@umich.edu 2703358Srdreslin@umich.edu // reset the sw state exculsion to false 2713358Srdreslin@umich.edu if (swExpl[sid]) 2723358Srdreslin@umich.edu swExpl[sid] = false; 2733358Srdreslin@umich.edu 2743358Srdreslin@umich.edu 2753358Srdreslin@umich.edu int smib = smStack[sid].back(); 2763358Srdreslin@umich.edu StringWrap name(sys->name()); 2773358Srdreslin@umich.edu DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi, 2783358Srdreslin@umich.edu frame, smib); 2793358Srdreslin@umich.edu 2803358Srdreslin@umich.edu if (!smStack[sid].size() || smMap[smib-1].second.first != sm) { 2813358Srdreslin@umich.edu DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x" 2823358Srdreslin@umich.edu " top of stack: %s Current Stack:\n", 2833358Srdreslin@umich.edu sysi, frame, smMap[smib-1].second.first); 2843358Srdreslin@umich.edu for (int x = smStack[sid].size()-1; x >= 0; x--) 2853646Srdreslin@umich.edu DPRINTF(Annotate, "-- %d\n", smStack[sid][x]); 2863358Srdreslin@umich.edu DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm, 2873358Srdreslin@umich.edu smMap[smib-1].second.first); 2883358Srdreslin@umich.edu 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(CheckpointOut &cp) const 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 SCache::iterator i; 1081 int x = 0, y = 0; 1082 1083 // smtCache (SCache) 1084 x = 0; 1085 y = 0; 1086 i = smtCache.begin(); 1087 while (i != smtCache.end()) { 1088 paramOut(os, csprintf("smtCache%d.str", x), i->first); 1089 paramOut(os, csprintf("smtCache%d.int", x), i->second); 1090 x++; i++; 1091 } 1092 1093 // stCache (StCache) 1094 for (x = 0; x < stCache.size(); x++) { 1095 i = stCache[x].begin(); 1096 y = 0; 1097 while (i != stCache[x].end()) { 1098 paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first); 1099 paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second); 1100 y++; i++; 1101 } 1102 } 1103 1104 // qCache (IdCache) 1105 IdHCache::iterator idi; 1106 for (x = 0; x < qCache.size(); x++) { 1107 idi = qCache[x].begin(); 1108 y = 0; 1109 while (idi != qCache[x].end()) { 1110 paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first); 1111 paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second); 1112 paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second); 1113 y++; idi++; 1114 } 1115 } 1116 1117 // smCache (IdCache) 1118 for (x = 0; x < smCache.size(); x++) { 1119 idi = smCache[x].begin(); 1120 y = 0; 1121 paramOut(os, csprintf("smCache%d", x), smCache[x].size()); 1122 while (idi != smCache[x].end()) { 1123 paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first); 1124 paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second); 1125 paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second); 1126 y++; idi++; 1127 } 1128 } 1129 1130 // scLinks (ScCache) -- data not serialize 1131 1132 1133 // namecache (NameCache) 1134 NameCache::iterator ni; 1135 1136 ni = nameCache.begin(); 1137 x = 0; 1138 while (ni != nameCache.end()) { 1139 paramOut(os, csprintf("nameCache%d.name", x), ni->first->name()); 1140 paramOut(os, csprintf("nameCache%d.str", x), ni->second.first); 1141 paramOut(os, csprintf("nameCache%d.int", x), ni->second.second); 1142 x++; ni++; 1143 } 1144 1145 // smStack (SmStack) 1146 SmStack::iterator si; 1147 si = smStack.begin(); 1148 x = 0; 1149 paramOut(os, "smStackIdCount", smStack.size()); 1150 while (si != smStack.end()) { 1151 paramOut(os, csprintf("smStackId%d.sys", x), si->first.first); 1152 paramOut(os, csprintf("smStackId%d.frame", x), si->first.second); 1153 paramOut(os, csprintf("smStackId%d.count", x), si->second.size()); 1154 for (y = 0; y < si->second.size(); y++) 1155 paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]); 1156 x++; si++; 1157 } 1158 1159 // lnMap (LinkMap) 1160 x = 0; 1161 LinkMap::iterator li; 1162 li = lnMap.begin(); 1163 paramOut(os, "lnMapSize", lnMap.size()); 1164 while (li != lnMap.end()) { 1165 paramOut(os, csprintf("lnMap%d.smi", x), li->first); 1166 paramOut(os, csprintf("lnMap%d.lsmi", x), li->second); 1167 x++; li++; 1168 } 1169 1170 // swExpl (vector) 1171 SwExpl::iterator swexpli; 1172 swexpli = swExpl.begin(); 1173 x = 0; 1174 paramOut(os, "swExplCount", swExpl.size()); 1175 while (swexpli != swExpl.end()) { 1176 paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first); 1177 paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second); 1178 paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second); 1179 x++; swexpli++; 1180 } 1181 1182 // lastState (IMap) 1183 x = 0; 1184 IMap::iterator ii; 1185 ii = lastState.begin(); 1186 paramOut(os, "lastStateSize", lastState.size()); 1187 while (ii != lastState.end()) { 1188 paramOut(os, csprintf("lastState%d.smi", x), ii->first); 1189 paramOut(os, csprintf("lastState%d.sti", x), ii->second); 1190 x++; ii++; 1191 } 1192 1193 // smMap (IdMap) 1194 for (x = 0; x < smMap.size(); x++) { 1195 paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first); 1196 paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first); 1197 paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second); 1198 } 1199 1200 // qMap (IdMap) 1201 for (x = 0; x < qMap.size(); x++) { 1202 paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first); 1203 paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first); 1204 paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second); 1205 } 1206 1207 // qData (vector<AnnotateList>) 1208 for (x = 0; x < qData.size(); x++) { 1209 if (!qData[x].size()) 1210 continue; 1211 y = 0; 1212 for (auto &ann : qData[x]) { 1213 ann->serializeSection(os, csprintf("Q%d_%d", x, y)); 1214 y++; 1215 } 1216 } 1217} 1218 1219void 1220CPA::unserialize(CheckpointIn &cp) 1221{ 1222 UNSERIALIZE_SCALAR(numSm); 1223 UNSERIALIZE_SCALAR(numSmt); 1224 UNSERIALIZE_CONTAINER(numSt); 1225 UNSERIALIZE_CONTAINER(numQ); 1226 UNSERIALIZE_SCALAR(numSys); 1227 UNSERIALIZE_SCALAR(numQs); 1228 UNSERIALIZE_SCALAR(conId); 1229 UNSERIALIZE_CONTAINER(qSize); 1230 UNSERIALIZE_CONTAINER(qBytes); 1231 1232 1233 // smtCache (SCache 1234 string str; 1235 int smi; 1236 for (int x = 0; x < numSmt; x++) { 1237 paramIn(cp, csprintf("smtCache%d.str", x), str); 1238 paramIn(cp, csprintf("smtCache%d.int", x), smi); 1239 smtCache[str] = smi; 1240 } 1241 1242 // stCache (StCache) 1243 stCache.resize(numSmt); 1244 for (int x = 0; x < numSmt; x++) { 1245 for (int y = 0; y < numSt[x]; y++) { 1246 paramIn(cp, csprintf("stCache%d_%d.str", x,y), str); 1247 paramIn(cp, csprintf("stCache%d_%d.int", x,y), smi); 1248 stCache[x][str] = smi; 1249 } 1250 } 1251 1252 // qCache (IdCache) 1253 uint64_t id; 1254 qCache.resize(numSys); 1255 for (int x = 0; x < numSys; x++) { 1256 for (int y = 0; y < numQ[x]; y++) { 1257 paramIn(cp, csprintf("qCache%d_%d.str", x,y), str); 1258 paramIn(cp, csprintf("qCache%d_%d.id", x,y), id); 1259 paramIn(cp, csprintf("qCache%d_%d.int", x,y), smi); 1260 qCache[x][Id(str,id)] = smi; 1261 } 1262 } 1263 1264 // smCache (IdCache) 1265 smCache.resize(numSys); 1266 for (int x = 0; x < numSys; x++) { 1267 int size; 1268 paramIn(cp, csprintf("smCache%d", x), size); 1269 for (int y = 0; y < size; y++) { 1270 paramIn(cp, csprintf("smCache%d_%d.str", x,y), str); 1271 paramIn(cp, csprintf("smCache%d_%d.id", x,y), id); 1272 paramIn(cp, csprintf("smCache%d_%d.int", x,y), smi); 1273 smCache[x][Id(str,id)] = smi; 1274 } 1275 } 1276 1277 // scLinks (ScCache) -- data not serialized, just creating one per sys 1278 for (int x = 0; x < numSys; x++) 1279 scLinks.push_back(ScHCache()); 1280 1281 // nameCache (NameCache) 1282 for (int x = 0; x < numSys; x++) { 1283 System *sys; 1284 SimObject *sptr; 1285 string str; 1286 int sysi; 1287 1288 objParamIn(cp, csprintf("nameCache%d.name", x), sptr); 1289 sys = dynamic_cast<System*>(sptr); 1290 1291 paramIn(cp, csprintf("nameCache%d.str", x), str); 1292 paramIn(cp, csprintf("nameCache%d.int", x), sysi); 1293 nameCache[sys] = std::make_pair(str, sysi); 1294 } 1295 1296 //smStack (SmStack) 1297 int smStack_size; 1298 paramIn(cp, "smStackIdCount", smStack_size); 1299 for (int x = 0; x < smStack_size; x++) { 1300 int sysi; 1301 uint64_t frame; 1302 int count; 1303 paramIn(cp, csprintf("smStackId%d.sys", x), sysi); 1304 paramIn(cp, csprintf("smStackId%d.frame", x), frame); 1305 paramIn(cp, csprintf("smStackId%d.count", x), count); 1306 StackId sid = StackId(sysi, frame); 1307 for (int y = 0; y < count; y++) { 1308 paramIn(cp, csprintf("smStackId%d_%d", x, y), smi); 1309 smStack[sid].push_back(smi); 1310 } 1311 } 1312 1313 // lnMap (LinkMap) 1314 int lsmi; 1315 int lnMap_size; 1316 paramIn(cp, "lnMapSize", lnMap_size); 1317 for (int x = 0; x < lnMap_size; x++) { 1318 paramIn(cp, csprintf("lnMap%d.smi", x), smi); 1319 paramIn(cp, csprintf("lnMap%d.lsmi", x), lsmi); 1320 lnMap[smi] = lsmi; 1321 } 1322 1323 // swExpl (vector) 1324 int swExpl_size; 1325 paramIn(cp, "swExplCount", swExpl_size); 1326 for (int x = 0; x < swExpl_size; x++) { 1327 int sysi; 1328 uint64_t frame; 1329 bool b; 1330 paramIn(cp, csprintf("swExpl%d.sys", x), sysi); 1331 paramIn(cp, csprintf("swExpl%d.frame", x), frame); 1332 paramIn(cp, csprintf("swExpl%d.swexpl", x), b); 1333 StackId sid = StackId(sysi, frame); 1334 swExpl[sid] = b; 1335 } 1336 1337 // lastState (IMap) 1338 int sti; 1339 int lastState_size; 1340 paramIn(cp, "lastStateSize", lastState_size); 1341 for (int x = 0; x < lastState_size; x++) { 1342 paramIn(cp, csprintf("lastState%d.smi", x), smi); 1343 paramIn(cp, csprintf("lastState%d.sti", x), sti); 1344 lastState[smi] = sti; 1345 } 1346 1347 1348 //smMap (IdMap) 1349 smMap.resize(numSm); 1350 for (int x = 0; x < smMap.size(); x++) { 1351 paramIn(cp, csprintf("smMap%d.sys", x), smMap[x].first); 1352 paramIn(cp, csprintf("smMap%d.smname", x), smMap[x].second.first); 1353 paramIn(cp, csprintf("smMap%d.id", x), smMap[x].second.second); 1354 } 1355 1356 //qMap (IdMap) 1357 qMap.resize(numQs); 1358 for (int x = 0; x < qMap.size(); x++) { 1359 paramIn(cp, csprintf("qMap%d.sys", x), qMap[x].first); 1360 paramIn(cp, csprintf("qMap%d.qname", x), qMap[x].second.first); 1361 paramIn(cp, csprintf("qMap%d.id", x), qMap[x].second.second); 1362 } 1363 1364 1365 // qData (vector<AnnotateList>) 1366 qData.resize(qSize.size()); 1367 for (int x = 0; x < qSize.size(); x++) { 1368 if (!qSize[x]) 1369 continue; 1370 for (int y = 0; y < qSize[x]; y++) { 1371 AnnDataPtr a = std::make_shared<AnnotateData>(); 1372 a->unserializeSection(cp, csprintf("Q%d_%d", x, y)); 1373 data.push_back(a); 1374 qData[x].push_back(a); 1375 } 1376 } 1377} 1378 1379void 1380CPA::AnnotateData::serialize(CheckpointOut &cp) const 1381{ 1382 SERIALIZE_SCALAR(time); 1383 SERIALIZE_SCALAR(data); 1384 SERIALIZE_SCALAR(sm); 1385 SERIALIZE_SCALAR(stq); 1386 SERIALIZE_SCALAR(op); 1387 SERIALIZE_SCALAR(flag); 1388 SERIALIZE_SCALAR(cpu); 1389} 1390 1391void 1392CPA::AnnotateData::unserialize(CheckpointIn &cp) 1393{ 1394 UNSERIALIZE_SCALAR(time); 1395 UNSERIALIZE_SCALAR(data); 1396 orig_data = data; 1397 UNSERIALIZE_SCALAR(sm); 1398 UNSERIALIZE_SCALAR(stq); 1399 UNSERIALIZE_SCALAR(op); 1400 UNSERIALIZE_SCALAR(flag); 1401 UNSERIALIZE_SCALAR(cpu); 1402 dump = true; 1403} 1404 1405CPA* 1406CPAParams::create() 1407{ 1408 return new CPA(this); 1409} 1410 1411