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