• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

kcachegrind

  • sources
  • kde-4.12
  • kdesdk
  • kcachegrind
  • libcore
tracedata.cpp
Go to the documentation of this file.
1 /* This file is part of KCachegrind.
2  Copyright (C) 2002 - 2009 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
3 
4  KCachegrind is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public
6  License as published by the Free Software Foundation, version 2.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 
20 #include "tracedata.h"
21 
22 #include <errno.h>
23 #include <stdlib.h>
24 
25 #include <QFile>
26 #include <QDir>
27 #include <QFileInfo>
28 #include <QDebug>
29 
30 #include "logger.h"
31 #include "loader.h"
32 #include "globalconfig.h"
33 #include "utils.h"
34 #include "fixcost.h"
35 
36 
37 #define TRACE_DEBUG 0
38 #define TRACE_ASSERTIONS 0
39 
40 
41 
42 
43 //---------------------------------------------------
44 // TraceJumpCost
45 
46 TraceJumpCost::TraceJumpCost(ProfileContext* c)
47  :CostItem(c)
48 {
49  TraceJumpCost::clear();
50 }
51 
52 TraceJumpCost::~TraceJumpCost()
53 {}
54 
55 SubCost TraceJumpCost::executedCount()
56 {
57  if (_dirty) update();
58 
59  return _executedCount;
60 }
61 
62 SubCost TraceJumpCost::followedCount()
63 {
64  if (_dirty) update();
65 
66  return _followedCount;
67 }
68 
69 QString TraceJumpCost::costString(EventTypeSet*)
70 {
71  if (_dirty) update();
72 
73  return QString("%1/%2")
74  .arg(_followedCount.pretty())
75  .arg(_executedCount.pretty());
76 }
77 
78 void TraceJumpCost::clear()
79 {
80  _followedCount = 0;
81  _executedCount = 0;
82 }
83 
84 void TraceJumpCost::addCost(TraceJumpCost* item)
85 {
86  if (item->_dirty) item->update();
87 
88  _followedCount += item->followedCount();
89  _executedCount += item->executedCount();
90 }
91 
92 
93 
94 //---------------------------------------------------
95 // TraceCallCost
96 
97 TraceCallCost::TraceCallCost(ProfileContext* context)
98  : ProfileCostArray(context)
99 {
100  _callCount = 0;
101 }
102 
103 TraceCallCost::~TraceCallCost()
104 {}
105 
106 
107 QString TraceCallCost::costString(EventTypeSet* m)
108 {
109  return QString("%1, Calls %2")
110  .arg(ProfileCostArray::costString(m))
111  .arg(_callCount.pretty());
112 }
113 
114 QString TraceCallCost::prettyCallCount()
115 {
116  return _callCount.pretty();
117 }
118 
119 void TraceCallCost::clear()
120 {
121  _callCount = 0;
122  ProfileCostArray::clear();
123 }
124 
125 SubCost TraceCallCost::callCount()
126 {
127  if (_dirty) update();
128 
129  return _callCount;
130 }
131 
132 void TraceCallCost::addCallCount(SubCost c)
133 {
134  _callCount += c;
135 
136  invalidate();
137 }
138 
139 
140 //---------------------------------------------------
141 // TraceInclusiveCost
142 
143 TraceInclusiveCost::TraceInclusiveCost(ProfileContext* context)
144  : ProfileCostArray(context), _inclusive(context)
145 {}
146 
147 TraceInclusiveCost::~TraceInclusiveCost()
148 {}
149 
150 QString TraceInclusiveCost::costString(EventTypeSet* m)
151 {
152  return QString("%1, Inclusive %2")
153  .arg(ProfileCostArray::costString(m))
154  .arg(_inclusive.costString(m));
155 }
156 
157 void TraceInclusiveCost::clear()
158 {
159  _inclusive.clear();
160  ProfileCostArray::clear();
161 }
162 
163 ProfileCostArray* TraceInclusiveCost::inclusive()
164 {
165  if (_dirty) update();
166 
167  return &_inclusive;
168 }
169 
170 void TraceInclusiveCost::addInclusive(ProfileCostArray* c)
171 {
172  _inclusive.addCost(c);
173 
174  invalidate();
175 }
176 
177 
178 //---------------------------------------------------
179 // TraceListCost
180 
181 TraceListCost::TraceListCost(ProfileContext* context)
182  : ProfileCostArray(context)
183 {
184  _lastDep = 0;
185 }
186 
187 TraceListCost::~TraceListCost()
188 {}
189 
190 void TraceListCost::addDep(ProfileCostArray* dep)
191 {
192 #if TRACE_ASSERTIONS
193  if (_deps.contains(dep)) {
194  qDebug("addDep: %s already in list!",
195  qPrintable(dep->fullName()));
196  return;
197  }
198 #endif
199 
200  _deps.append(dep);
201  _lastDep = dep;
202  invalidate();
203 
204 #if TRACE_DEBUG
205  qDebug("%s added\n %s (now %d)",
206  qPrintable( fullName() ), qPrintable(dep->fullName()),
207  _deps.count());
208 #endif
209 }
210 
211 ProfileCostArray* TraceListCost::findDepFromPart(TracePart* part)
212 {
213  if (_lastDep && _lastDep->part() == part)
214  return _lastDep;
215 
216  foreach(ProfileCostArray* dep, _deps) {
217  if (dep->part() == part) {
218  _lastDep = dep;
219  return dep;
220  }
221  }
222  return 0;
223 }
224 
225 
226 void TraceListCost::update()
227 {
228  if (!_dirty) return;
229 
230 #if TRACE_DEBUG
231  qDebug("update %s (count %d)",
232  qPrintable( fullName() ), _deps.count());
233 #endif
234 
235  clear();
236  foreach(ProfileCostArray* item, _deps) {
237  if (onlyActiveParts())
238  if (!item->part() || !item->part()->isActive()) continue;
239 
240  addCost(item);
241  }
242 
243  _dirty = false;
244 
245 #if TRACE_DEBUG
246  qDebug(" > %s", qPrintable(costString(0)));
247 #endif
248 }
249 
250 
251 
252 //---------------------------------------------------
253 // TraceJumpListCost
254 
255 TraceJumpListCost::TraceJumpListCost(ProfileContext* context)
256  : TraceJumpCost(context)
257 {
258  _lastDep = 0;
259 }
260 
261 TraceJumpListCost::~TraceJumpListCost()
262 {}
263 
264 void TraceJumpListCost::addDep(TraceJumpCost* dep)
265 {
266 #if TRACE_ASSERTIONS
267  if (_deps.contains(dep)) {
268  qDebug("addDep: %s already in list!",
269  qPrintable(dep->fullName()));
270  return;
271  }
272 #endif
273 
274  _deps.append(dep);
275  _lastDep = dep;
276  invalidate();
277 
278 #if TRACE_DEBUG
279  qDebug("%s added\n %s (now %d)",
280  qPrintable( fullName() ), qPrintable(dep->fullName()),
281  _deps.count());
282 #endif
283 }
284 
285 TraceJumpCost* TraceJumpListCost::findDepFromPart(TracePart* part)
286 {
287  if (_lastDep && _lastDep->part() == part)
288  return _lastDep;
289 
290  foreach(TraceJumpCost* dep, _deps) {
291  if (dep->part() == part) {
292  _lastDep = dep;
293  return dep;
294  }
295  }
296  return 0;
297 }
298 
299 
300 void TraceJumpListCost::update()
301 {
302  if (!_dirty) return;
303 
304 #if TRACE_DEBUG
305  qDebug("update %s (count %d)",
306  qPrintable( fullName() ), _deps.count());
307 #endif
308 
309  clear();
310  foreach(TraceJumpCost* item, _deps) {
311  if (onlyActiveParts())
312  if (!item->part() || !item->part()->isActive()) continue;
313 
314  addCost(item);
315  }
316 
317  _dirty = false;
318 
319 #if TRACE_DEBUG
320  qDebug(" > %s", qPrintable(costString(0)));
321 #endif
322 }
323 
324 
325 
326 //---------------------------------------------------
327 // TraceCallListCost
328 
329 TraceCallListCost::TraceCallListCost(ProfileContext* context)
330  : TraceCallCost(context)
331 {
332  _lastDep = 0;
333 }
334 
335 TraceCallListCost::~TraceCallListCost()
336 {}
337 
338 void TraceCallListCost::addDep(TraceCallCost* dep)
339 {
340 #if TRACE_ASSERTIONS
341  if (_deps.contains(dep)) {
342  qDebug("addDep: %s already in list!",
343  qPrintable(dep->fullName()));
344  return;
345  }
346 #endif
347 
348  _deps.append(dep);
349  _lastDep = dep;
350  invalidate();
351 
352 #if TRACE_DEBUG
353  qDebug("%s added\n %s (now %d)",
354  qPrintable( fullName() ), qPrintable(dep->fullName()),
355  _deps.count());
356 #endif
357 }
358 
359 TraceCallCost* TraceCallListCost::findDepFromPart(TracePart* part)
360 {
361  if (_lastDep && _lastDep->part() == part)
362  return _lastDep;
363 
364  foreach(TraceCallCost* dep, _deps) {
365  if (dep->part() == part) {
366  _lastDep = dep;
367  return dep;
368  }
369  }
370  return 0;
371 }
372 
373 
374 void TraceCallListCost::update()
375 {
376  if (!_dirty) return;
377 
378 #if TRACE_DEBUG
379  qDebug("update %s (count %d)",
380  qPrintable( fullName() ), _deps.count());
381 #endif
382 
383  /* Without dependent cost items, assume fixed costs,
384  * i.e. do not change cost */
385  if (_deps.count()>0) {
386  clear();
387  foreach(TraceCallCost* item, _deps) {
388  if (onlyActiveParts())
389  if (!item->part() || !item->part()->isActive()) continue;
390 
391  addCost(item);
392  addCallCount(item->callCount());
393  }
394  }
395 
396  _dirty = false;
397 
398 #if TRACE_DEBUG
399  qDebug(" > %s", qPrintable(costString(0)));
400 #endif
401 }
402 
403 
404 //---------------------------------------------------
405 // TraceInclusiveListCost
406 
407 TraceInclusiveListCost::TraceInclusiveListCost(ProfileContext* context)
408  : TraceInclusiveCost(context)
409 {
410  _lastDep = 0;
411 }
412 
413 TraceInclusiveListCost::~TraceInclusiveListCost()
414 {}
415 
416 
417 void TraceInclusiveListCost::addDep(TraceInclusiveCost* dep)
418 {
419 #if TRACE_ASSERTIONS
420  if (_deps.contains(dep)) {
421  qDebug("addDep: %s already in list!",
422  qPrintable(dep->fullName()));
423  return;
424  }
425 #endif
426 
427  _deps.append(dep);
428  _lastDep = dep;
429  invalidate();
430 
431 #if TRACE_DEBUG
432  qDebug("%s added\n %s (now %d)",
433  qPrintable( fullName() ), qPrintable(dep->fullName()),
434  _deps.count());
435 #endif
436 }
437 
438 TraceInclusiveCost* TraceInclusiveListCost::findDepFromPart(TracePart* part)
439 {
440  if (_lastDep && _lastDep->part() == part)
441  return _lastDep;
442 
443  foreach(TraceInclusiveCost* dep, _deps) {
444  if (dep->part() == part) {
445  _lastDep = dep;
446  return dep;
447  }
448  }
449  return 0;
450 }
451 
452 void TraceInclusiveListCost::update()
453 {
454  if (!_dirty) return;
455 
456 #if TRACE_DEBUG
457  qDebug("update %s (count %d)",
458  qPrintable( fullName() ), _deps.count());
459 #endif
460 
461  clear();
462  foreach(TraceInclusiveCost* item, _deps) {
463  if (onlyActiveParts())
464  if (!item->part() || !item->part()->isActive()) continue;
465 
466  addCost(item);
467  addInclusive(item->inclusive());
468  }
469 
470  _dirty = false;
471 
472 #if TRACE_DEBUG
473  qDebug(" > %s", qPrintable(costString(0)));
474 #endif
475 }
476 
477 
478 
479 //---------------------------------------------------
480 // TracePartInstrJump
481 
482 TracePartInstrJump::TracePartInstrJump(TraceInstrJump* instrJump,
483  TracePartInstrJump* next)
484  : TraceJumpCost(ProfileContext::context(ProfileContext::PartInstrJump))
485 {
486  _dep = instrJump;
487  _next = next;
488 }
489 
490 TracePartInstrJump::~TracePartInstrJump()
491 {}
492 
493 
494 //---------------------------------------------------
495 // TracePartInstrCall
496 
497 TracePartInstrCall::TracePartInstrCall(TraceInstrCall* instrCall)
498  : TraceCallCost(ProfileContext::context(ProfileContext::PartInstrCall))
499 {
500  _dep = instrCall;
501 }
502 
503 TracePartInstrCall::~TracePartInstrCall()
504 {}
505 
506 
507 
508 //---------------------------------------------------
509 // TracePartInstr
510 
511 TracePartInstr::TracePartInstr(TraceInstr* instr)
512  : ProfileCostArray(ProfileContext::context(ProfileContext::PartInstr))
513 {
514  _dep = instr;
515 }
516 
517 TracePartInstr::~TracePartInstr()
518 {}
519 
520 
521 
522 //---------------------------------------------------
523 // TracePartLineJump
524 
525 TracePartLineJump::TracePartLineJump(TraceLineJump* lineJump)
526  : TraceJumpCost(ProfileContext::context(ProfileContext::PartLineJump))
527 {
528  _dep = lineJump;
529 }
530 
531 TracePartLineJump::~TracePartLineJump()
532 {}
533 
534 
535 //---------------------------------------------------
536 // TracePartLineCall
537 
538 TracePartLineCall::TracePartLineCall(TraceLineCall* lineCall)
539  : TraceCallCost(ProfileContext::context(ProfileContext::PartLineCall))
540 {
541  _dep = lineCall;
542 }
543 
544 TracePartLineCall::~TracePartLineCall()
545 {}
546 
547 
548 //---------------------------------------------------
549 // TracePartLine
550 
551 TracePartLine::TracePartLine(TraceLine* line)
552  : ProfileCostArray(ProfileContext::context(ProfileContext::PartLine))
553 {
554  _dep = line;
555 }
556 
557 TracePartLine::~TracePartLine()
558 {}
559 
560 
561 
562 
563 //---------------------------------------------------
564 // TracePartCall
565 
566 TracePartCall::TracePartCall(TraceCall* call)
567  : TraceCallListCost(ProfileContext::context(ProfileContext::PartCall))
568 {
569  _dep = call;
570 
571  _firstFixCallCost = 0;
572 }
573 
574 TracePartCall::~TracePartCall()
575 {}
576 
577 bool TracePartCall::isRecursion()
578 {
579  return call()->isRecursion();
580 }
581 
582 void TracePartCall::update()
583 {
584 #if !USE_FIXCOST
585  TraceCallListCost::update();
586 #else
587 
588  if (!_dirty) return;
589 
590 #if TRACE_DEBUG
591  qDebug("update %s", qPrintable( fullName() ));
592 #endif
593 
594  /* Without dependent cost items, assume fixed costs,
595  * i.e. do not change cost */
596  if (_firstFixCallCost) {
597  clear();
598  FixCallCost* item;
599  for (item = _firstFixCallCost; item; item = item->nextCostOfPartCall())
600  item->addTo(this);
601  }
602 
603  _dirty = false;
604 
605 #if TRACE_DEBUG
606  qDebug(" > %s", qPrintable(costString(0)));
607 #endif
608 
609 #endif // USE_FIXCOST
610 }
611 
612 
613 //---------------------------------------------------
614 // TracePartFunction
615 
616 TracePartFunction::TracePartFunction(TraceFunction* function,
617  TracePartObject* partObject,
618  TracePartFile *partFile)
619  : TraceInclusiveCost(ProfileContext::context(ProfileContext::PartFunction))
620 {
621  _dep = function;
622  _partObject = partObject;
623  _partFile = partFile;
624  _partClass = 0;
625 
626  _calledCount = 0;
627  _callingCount = 0;
628  _calledContexts = 0;
629  _callingContexts = 0;
630 
631  _firstFixCost = 0;
632  _firstFixJump = 0;
633 }
634 
635 TracePartFunction::~TracePartFunction()
636 {}
637 
638 QString TracePartFunction::prettyCalledCount()
639 {
640  return _calledCount.pretty();
641 }
642 
643 QString TracePartFunction::prettyCallingCount()
644 {
645  return _callingCount.pretty();
646 }
647 
648 QString TracePartFunction::costString(EventTypeSet* m)
649 {
650  update();
651 
652  QString res = TraceInclusiveCost::costString(m);
653  res += QString(", called from %1: %2")
654  .arg(_calledContexts).arg(prettyCalledCount());
655  res += QString(", calling from %1: %2")
656  .arg(_callingContexts).arg(prettyCallingCount());
657 
658  return res;
659 }
660 
661 
662 void TracePartFunction::addPartInstr(TracePartInstr* ref)
663 {
664 #if TRACE_ASSERTIONS
665  if (_partInstr.contains(ref)) {
666  qDebug("TracePartFunction::addPartInstr: %s already in list!",
667  qPrintable(ref->name()));
668  return;
669  }
670 #endif
671 
672  _partInstr.append(ref);
673  invalidate();
674 
675 #if TRACE_DEBUG
676  qDebug("%s added\n %s (now %d)",
677  qPrintable( fullName() ), qPrintable(ref->fullName()),
678  _partInstr.count());
679 #endif
680 }
681 
682 
683 void TracePartFunction::addPartLine(TracePartLine* ref)
684 {
685 #if TRACE_ASSERTIONS
686  if (_partLines.contains(ref)) {
687  qDebug("TracePartFunction::addPartLine: %s already in list!",
688  qPrintable(ref->name()));
689  return;
690  }
691 #endif
692 
693  _partLines.append(ref);
694  invalidate();
695 
696 #if TRACE_DEBUG
697  qDebug("%s added\n %s (now %d)",
698  qPrintable( fullName() ), qPrintable(ref->fullName()),
699  _partLines.count());
700 #endif
701 }
702 
703 
704 void TracePartFunction::addPartCaller(TracePartCall* ref)
705 {
706 #if TRACE_ASSERTIONS
707  if (_partCallers.contains(ref)) {
708  qDebug("TracePartFunction::addPartCaller: %s already in list!",
709  qPrintable(ref->name()));
710  return;
711  }
712 #endif
713 
714  _partCallers.append(ref);
715  invalidate();
716 
717 #if TRACE_DEBUG
718  qDebug("%s added Caller\n %s (now %d)",
719  qPrintable( fullName() ), qPrintable(ref->fullName()),
720  _partCallers.count());
721 #endif
722 }
723 
724 
725 void TracePartFunction::addPartCalling(TracePartCall* ref)
726 {
727 #if TRACE_ASSERTIONS
728  if (_partCallings.contains(ref)) {
729  qDebug("TracePartFunction::addPartCalling: %s already in list!",
730  qPrintable(ref->name()));
731  return;
732  }
733 #endif
734 
735  _partCallings.append(ref);
736  invalidate();
737 
738 #if TRACE_DEBUG
739  qDebug("%s added Calling\n %s (now %d)",
740  qPrintable( fullName() ), qPrintable(ref->fullName()),
741  _partCallings.count());
742 #endif
743 }
744 
745 SubCost TracePartFunction::calledCount()
746 {
747  if (_dirty) update();
748 
749  return _calledCount;
750 }
751 
752 int TracePartFunction::calledContexts()
753 {
754  if (_dirty) update();
755 
756  return _calledContexts;
757 }
758 
759 SubCost TracePartFunction::callingCount()
760 {
761  if (_dirty) update();
762 
763  return _callingCount;
764 }
765 
766 
767 int TracePartFunction::callingContexts()
768 {
769  if (_dirty) update();
770 
771  return _callingContexts;
772 }
773 
774 
775 void TracePartFunction::update()
776 {
777  if (!_dirty) return;
778 
779 #if TRACE_DEBUG
780  qDebug("TracePartFunction::update %s (Callers %d, Callings %d, lines %d)",
781  qPrintable(name()), _partCallers.count(), _partCallings.count(),
782  _partLines.count());
783 #endif
784 
785  _calledCount = 0;
786  _callingCount = 0;
787  _calledContexts = 0;
788  _callingContexts = 0;
789 
790  // To calculate context counts, we just use first real event type (FIXME?)
791  EventType* e = data() ? data()->eventTypes()->realType(0) : 0;
792 
793  // calculate additional cost metrics
794  foreach(TracePartCall* caller, _partCallers) {
795  if (e && (caller->subCost(e) >0))
796  _calledContexts++;
797 
798  SubCost c = caller->callCount();
799  if (c>0) {
800  _calledCount += c;
801  }
802  }
803  foreach(TracePartCall* calling, _partCallings) {
804  if (e && (calling->subCost(e)>0))
805  _callingContexts++;
806 
807  SubCost c = calling->callCount();
808  if (c>0) {
809  _callingCount += c;
810  }
811  }
812 
813  // self cost
814 #if !USE_FIXCOST
815  if (_partLines.count()>0) {
816  ProfileCostArray::clear();
817 
818  foreach(TracePartLine* line, _partLines)
819  addCost(line);
820  }
821 #else
822  if (_firstFixCost) {
823  ProfileCostArray::clear();
824 
825  FixCost* item;
826  for (item = _firstFixCost; item; item = item->nextCostOfPartFunction())
827  item->addTo(this);
828  }
829 #endif
830 
831 
832  /* There are two possibilities to calculate inclusive cost:
833  * 1) sum of call costs to this function
834  * 2) sum of call costs from this function + self cost
835  *
836  * 1) is wrong if a function was called spontaneous, but also by a call.
837  * This eventually can happen with thread/process startup functions,
838  * and signal handlers.
839  *
840  * 2) is wrong with "skipped PLT" and the calltree skin, because
841  * cost of PLT is attributed to called function (?)
842  *
843  * For now, do 1) if there are callers, otherwise 2).
844  * Should this be fixed to take the maximum of 1) and 2) ?
845  */
846  _inclusive.clear();
847  if (_calledCount>0) {
848  // inclusive cost: if possible, use caller sums
849  foreach(TracePartCall* caller, _partCallers) {
850  // detect simple recursion (no cycle)
851  if (caller->isRecursion()) continue;
852 
853  addInclusive(caller);
854  }
855  }
856  else {
857  // without caller info, use calling sum + line costs
858  foreach(TracePartCall* calling, _partCallings) {
859  // detect simple recursion (no cycle)
860  if (calling->isRecursion()) continue;
861 
862  addInclusive(calling);
863  }
864  _dirty = false; // do not recurse!
865  addInclusive(this);
866  }
867 
868  _dirty = false;
869 
870 #if TRACE_DEBUG
871  qDebug(" > %s", qPrintable(costString(0)));
872 #endif
873 }
874 
875 
876 
877 //---------------------------------------------------
878 // TracePartClass
879 
880 TracePartClass::TracePartClass(TraceClass* cls)
881  : TraceInclusiveListCost(ProfileContext::context(ProfileContext::PartClass))
882 {
883  _dep = cls;
884 }
885 
886 TracePartClass::~TracePartClass()
887 {}
888 
889 QString TracePartClass::prettyName() const
890 {
891  return QString("%1 from %2")
892  .arg( _dep->name().isEmpty() ? QString("(global)") : _dep->name())
893  .arg(part()->name());
894 }
895 
896 //---------------------------------------------------
897 // TracePartFile
898 
899 TracePartFile::TracePartFile(TraceFile* file)
900  : TraceInclusiveListCost(ProfileContext::context(ProfileContext::PartFile))
901 {
902  _dep = file;
903 }
904 
905 TracePartFile::~TracePartFile()
906 {}
907 
908 
909 //---------------------------------------------------
910 // TracePartObject
911 
912 TracePartObject::TracePartObject(TraceObject* object)
913  : TraceInclusiveListCost(ProfileContext::context(ProfileContext::PartObject))
914 {
915  _dep = object;
916 }
917 
918 TracePartObject::~TracePartObject()
919 {}
920 
921 
922 
923 
924 //---------------------------------------------------
925 // TraceInstrJump
926 
927 TraceInstrJump::TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo,
928  bool isCondJump)
929  : TraceJumpCost(ProfileContext::context(ProfileContext::InstrJump))
930 {
931  _first = 0;
932 
933  _instrFrom = instrFrom;
934  _instrTo = instrTo;
935  _isCondJump = isCondJump;
936 }
937 
938 TraceInstrJump::~TraceInstrJump()
939 {
940  // we are the owner of the TracePartInstrJump's generated in our factory
941  TracePartInstrJump* item = _first, *next;
942  while(item) {
943  next = item->next();
944  delete item;
945  item = next;
946  }
947 }
948 
949 TracePartInstrJump* TraceInstrJump::partInstrJump(TracePart* part)
950 {
951  static TracePartInstrJump* item = 0;
952 
953  // shortcut if recently used
954  if (item &&
955  (item->instrJump()==this) &&
956  (item->part() == part)) return item;
957 
958  for(item = _first; item; item = item->next())
959  if (item->part() == part)
960  return item;
961 
962  item = new TracePartInstrJump(this, _first);
963  item->setPosition(part);
964  _first = item;
965  return item;
966 }
967 
968 void TraceInstrJump::update()
969 {
970  if (!_dirty) return;
971 
972  clear();
973  TracePartInstrJump* item;
974  for (item = _first; item; item = item->next()) {
975  if (!item->part() || !item->part()->isActive()) continue;
976 
977  addCost(item);
978  }
979  _dirty = false;
980 
981 #if TRACE_DEBUG
982  qDebug("updated %s", qPrintable( fullName() ));
983 #endif
984 
985 #if TRACE_DEBUG
986  qDebug(" > %s", qPrintable(costString(0)));
987 #endif
988 }
989 
990 QString TraceInstrJump::name() const
991 {
992  return QString("jump at 0x%1 to 0x%2")
993  .arg(_instrFrom->addr().toString())
994  .arg(_instrTo->addr().toString());
995 }
996 
997 
998 //---------------------------------------------------
999 // TraceLineJump
1000 
1001 TraceLineJump::TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo,
1002  bool isCondJump)
1003  : TraceJumpListCost(ProfileContext::context(ProfileContext::LineJump))
1004 {
1005  _lineFrom = lineFrom;
1006  _lineTo = lineTo;
1007  _isCondJump = isCondJump;
1008 }
1009 
1010 TraceLineJump::~TraceLineJump()
1011 {
1012  // we are the owner of TracePartLineJump's generated in our factory
1013  qDeleteAll(_deps);
1014 }
1015 
1016 
1017 TracePartLineJump* TraceLineJump::partLineJump(TracePart* part)
1018 {
1019  TracePartLineJump* item = (TracePartLineJump*) findDepFromPart(part);
1020  if (!item) {
1021  item = new TracePartLineJump(this);
1022  item->setPosition(part);
1023  addDep(item);
1024  }
1025  return item;
1026 }
1027 
1028 
1029 QString TraceLineJump::name() const
1030 {
1031  return QString("jump at %1 to %2")
1032  .arg(_lineFrom->prettyName())
1033  .arg(_lineTo->prettyName());
1034 }
1035 
1036 
1037 //---------------------------------------------------
1038 // TraceInstrCall
1039 
1040 TraceInstrCall::TraceInstrCall(TraceCall* call, TraceInstr* instr)
1041  : TraceCallListCost(ProfileContext::context(ProfileContext::InstrCall))
1042 {
1043  _call = call;
1044  _instr = instr;
1045 }
1046 
1047 TraceInstrCall::~TraceInstrCall()
1048 {
1049  // we are the owner of TracePartInstrCall's generated in our factory
1050  qDeleteAll(_deps);
1051 }
1052 
1053 
1054 TracePartInstrCall* TraceInstrCall::partInstrCall(TracePart* part,
1055  TracePartCall*)
1056 {
1057  TracePartInstrCall* item = (TracePartInstrCall*) findDepFromPart(part);
1058  if (!item) {
1059  item = new TracePartInstrCall(this);
1060  item->setPosition(part);
1061  addDep(item);
1062  // instruction calls are not registered in function calls
1063  // as together with line calls calls are duplicated
1064  //partCall->addDep(item);
1065  }
1066  return item;
1067 }
1068 
1069 
1070 QString TraceInstrCall::name() const
1071 {
1072  return QString("%1 at %2").arg(_call->name()).arg(_instr->name());
1073 }
1074 
1075 
1076 //---------------------------------------------------
1077 // TraceLineCall
1078 
1079 TraceLineCall::TraceLineCall(TraceCall* call, TraceLine* line)
1080  : TraceCallListCost(ProfileContext::context(ProfileContext::LineCall))
1081 {
1082  _call = call;
1083 
1084  _line = line;
1085 }
1086 
1087 TraceLineCall::~TraceLineCall()
1088 {
1089  // we are the owner of TracePartLineCall's generated in our factory
1090  qDeleteAll(_deps);
1091 }
1092 
1093 
1094 TracePartLineCall* TraceLineCall::partLineCall(TracePart* part,
1095  TracePartCall* partCall)
1096 {
1097  TracePartLineCall* item = (TracePartLineCall*) findDepFromPart(part);
1098  if (!item) {
1099  item = new TracePartLineCall(this);
1100  item->setPosition(part);
1101  addDep(item);
1102  partCall->addDep(item);
1103  }
1104  return item;
1105 }
1106 
1107 
1108 QString TraceLineCall::name() const
1109 {
1110  return QString("%1 at %2").arg(_call->name()).arg(_line->name());
1111 }
1112 
1113 
1114 //---------------------------------------------------
1115 // TraceCall
1116 
1117 TraceCall::TraceCall(TraceFunction* caller, TraceFunction* called)
1118  : TraceCallListCost(ProfileContext::context(ProfileContext::Call))
1119 {
1120  _caller = caller;
1121  _called = called;
1122 }
1123 
1124 
1125 TraceCall::~TraceCall()
1126 {
1127  // we are the owner of all items generated in our factories
1128  qDeleteAll(_deps);
1129  qDeleteAll(_lineCalls);
1130 }
1131 
1132 TracePartCall* TraceCall::partCall(TracePart* part,
1133  TracePartFunction* partCaller,
1134  TracePartFunction* partCalling)
1135 {
1136  TracePartCall* item = (TracePartCall*) findDepFromPart(part);
1137  if (!item) {
1138  item = new TracePartCall(this);
1139  item->setPosition(part);
1140  addDep(item);
1141  partCaller->addPartCalling(item);
1142  partCalling->addPartCaller(item);
1143  }
1144  return item;
1145 }
1146 
1147 TraceInstrCall* TraceCall::instrCall(TraceInstr* i)
1148 {
1149  foreach(TraceInstrCall* icall, _instrCalls)
1150  if (icall->instr() == i)
1151  return icall;
1152 
1153  TraceInstrCall* icall = new TraceInstrCall(this, i);
1154  _instrCalls.append(icall);
1155  invalidate();
1156 
1157 #if TRACE_DEBUG
1158  qDebug("Created %s [TraceCall::instrCall]", qPrintable(icall->fullName()));
1159 #endif
1160  i->addInstrCall(icall);
1161  return icall;
1162 }
1163 
1164 
1165 TraceLineCall* TraceCall::lineCall(TraceLine* l)
1166 {
1167  foreach(TraceLineCall* lcall, _lineCalls)
1168  if (lcall->line() == l)
1169  return lcall;
1170 
1171  TraceLineCall* lcall = new TraceLineCall(this, l);
1172  _lineCalls.append(lcall);
1173  invalidate();
1174 
1175 #if TRACE_DEBUG
1176  qDebug("Created %s [TraceCall::lineCall]", qPrintable(lcall->fullName()));
1177 #endif
1178  l->addLineCall(lcall);
1179  return lcall;
1180 }
1181 
1182 
1183 void TraceCall::invalidateDynamicCost()
1184 {
1185  foreach(TraceLineCall* lc, _lineCalls)
1186  lc->invalidate();
1187 
1188  foreach(TraceInstrCall* ic, _instrCalls)
1189  ic->invalidate();
1190 
1191  invalidate();
1192 }
1193 
1194 
1195 QString TraceCall::name() const
1196 {
1197  return QString("%1 => %2")
1198  .arg(_caller->name())
1199  .arg(_called->name());
1200 }
1201 
1202 int TraceCall::inCycle()
1203 {
1204  if (!_caller || !_called) return 0;
1205  if (!_caller->cycle()) return 0;
1206  if (_caller == _caller->cycle()) return 0;
1207  if (_caller->cycle() != _called->cycle()) return 0;
1208 
1209  return _caller->cycle()->cycleNo();
1210 }
1211 
1212 void TraceCall::update()
1213 {
1214  if (!_dirty) return;
1215 
1216  // special handling for cycles
1217  if (_caller && _caller->cycle() && _caller==_caller->cycle()) {
1218 
1219  // we have no part calls: use inclusive cost of called function
1220  clear();
1221  if (_called)
1222  addCost(_called->inclusive());
1223  _dirty = false;
1224  return;
1225  }
1226 
1227  TraceCallListCost::update();
1228 }
1229 
1230 TraceFunction* TraceCall::caller(bool /*skipCycle*/) const
1231 {
1232  return _caller;
1233 }
1234 
1235 TraceFunction* TraceCall::called(bool skipCycle) const
1236 {
1237  if (!skipCycle && _called) {
1238  // if this is a call to a cycle member from outside of the cycle,
1239  // fake it to be a call to the whole cycle
1240  if (_called->cycle() && _caller &&
1241  (_caller->cycle() != _called->cycle()))
1242  return _called->cycle();
1243  }
1244 
1245  return _called;
1246 }
1247 
1248 QString TraceCall::callerName(bool skipCycle) const
1249 {
1250  if (!_caller) return QObject::tr("(no caller)");
1251 
1252  if (!skipCycle) {
1253  // if this call goes into a cycle, add the entry function
1254  TraceFunctionCycle* c = _called->cycle();
1255  if (c && _caller && (_caller->cycle() != c)) {
1256  QString via = _called->prettyName();
1257  return QObject::tr("%1 via %2").arg(_caller->prettyName()).arg(via);
1258  }
1259  }
1260 
1261  return _caller->prettyName();
1262 }
1263 
1264 QString TraceCall::calledName(bool skipCycle) const
1265 {
1266  if (!_called) return QObject::tr("(no callee)");
1267 
1268  if (!skipCycle) {
1269  // if this call goes into a cycle, add the entry function
1270  TraceFunctionCycle* c = _called->cycle();
1271  if (c && _caller && (_caller->cycle() != c)) {
1272  // HACK to get rid of cycle postfix...
1273  _called->setCycle(0);
1274  QString via = _called->prettyName();
1275  _called->setCycle(c);
1276  return QObject::tr("%1 via %2").arg(c->name()).arg(via);
1277  }
1278  }
1279  return _called->prettyName();
1280 }
1281 
1282 
1283 //---------------------------------------------------
1284 // TraceInstr
1285 
1286 TraceInstr::TraceInstr()
1287  : TraceListCost(ProfileContext::context(ProfileContext::Instr))
1288 {
1289  _addr = 0;
1290  _line = 0;
1291  _function = 0;
1292 }
1293 
1294 TraceInstr::~TraceInstr()
1295 {
1296  // we are the owner of items generated in our factories
1297  qDeleteAll(_deps);
1298  qDeleteAll(_instrJumps);
1299 }
1300 
1301 bool TraceInstr::hasCost(EventType* ct)
1302 {
1303  if (subCost(ct) >0)
1304  return true;
1305 
1306  foreach(TraceInstrCall* ic, _instrCalls)
1307  if (ic->subCost(ct) >0)
1308  return true;
1309 
1310  foreach(TraceInstrJump* ij, _instrJumps)
1311  if (ij->executedCount() >0)
1312  return true;
1313 
1314  return false;
1315 }
1316 
1317 TracePartInstr* TraceInstr::partInstr(TracePart* part,
1318  TracePartFunction* partFunction)
1319 {
1320  TracePartInstr* item = (TracePartInstr*) findDepFromPart(part);
1321  if (!item) {
1322  item = new TracePartInstr(this);
1323  item->setPosition(part);
1324  addDep(item);
1325  //part->addDep(item);
1326  partFunction->addPartInstr(item);
1327  }
1328  return item;
1329 }
1330 
1331 TraceInstrJump* TraceInstr::instrJump(TraceInstr* to, bool isJmpCond)
1332 {
1333  foreach(TraceInstrJump* jump, _instrJumps)
1334  if (jump->instrTo() == to)
1335  return jump;
1336 
1337  TraceInstrJump* jump = new TraceInstrJump(this, to, isJmpCond);
1338  _instrJumps.append(jump);
1339  return jump;
1340 }
1341 
1342 
1343 
1344 void TraceInstr::addInstrCall(TraceInstrCall* instrCall)
1345 {
1346 #if TRACE_ASSERTIONS
1347  if (_instrCalls.contains(instrCall)) return;
1348 
1349  if (instrCall->instr() != this) {
1350  qDebug("Can not add instruction call to another instruction!");
1351  return;
1352  }
1353 #endif
1354 
1355  _instrCalls.append(instrCall);
1356  invalidate();
1357 
1358 #if TRACE_DEBUG
1359  qDebug("%s added\n %s (now %d)",
1360  qPrintable( fullName() ),
1361  qPrintable(instrCall->fullName()), _instrCalls.count());
1362 #endif
1363 }
1364 
1365 
1366 QString TraceInstr::name() const
1367 {
1368  return QString("0x%1").arg(_addr.toString());
1369 }
1370 
1371 QString TraceInstr::prettyName() const
1372 {
1373  return QString("0x%1").arg(_addr.toString());
1374 }
1375 
1376 
1377 //---------------------------------------------------
1378 // TraceLine
1379 
1380 TraceLine::TraceLine()
1381  : TraceListCost(ProfileContext::context(ProfileContext::Line))
1382 {
1383  _lineno = 0;
1384  _sourceFile = 0;
1385 }
1386 
1387 TraceLine::~TraceLine()
1388 {
1389  // we are the owner of items generated in our factories
1390  qDeleteAll(_deps);
1391  qDeleteAll(_lineJumps);
1392 }
1393 
1394 bool TraceLine::hasCost(EventType* ct)
1395 {
1396  if (subCost(ct) >0)
1397  return true;
1398 
1399  foreach(TraceLineCall* lc, _lineCalls)
1400  if (lc->subCost(ct) >0)
1401  return true;
1402 
1403  foreach(TraceLineJump* lj, _lineJumps)
1404  if (lj->executedCount() >0)
1405  return true;
1406 
1407  return false;
1408 }
1409 
1410 TracePartLine* TraceLine::partLine(TracePart* part,
1411  TracePartFunction* partFunction)
1412 {
1413  TracePartLine* item = (TracePartLine*) findDepFromPart(part);
1414  if (!item) {
1415  item = new TracePartLine(this);
1416  item->setPosition(part);
1417  addDep(item);
1418 #if !USE_FIXCOST
1419  part->addDep(item);
1420 #endif
1421  partFunction->addPartLine(item);
1422  }
1423  return item;
1424 }
1425 
1426 TraceLineJump* TraceLine::lineJump(TraceLine* to, bool isJmpCond)
1427 {
1428  foreach(TraceLineJump* jump, _lineJumps)
1429  if (jump->lineTo() == to)
1430  return jump;
1431 
1432  TraceLineJump* jump = new TraceLineJump(this, to, isJmpCond);
1433  _lineJumps.append(jump);
1434  return jump;
1435 }
1436 
1437 
1438 void TraceLine::addLineCall(TraceLineCall* lineCall)
1439 {
1440 #if TRACE_ASSERTIONS
1441  if (_lineCalls.contains(lineCall)) return;
1442 
1443  if (lineCall->line() != this) {
1444  qDebug("Can not add line call to another line!");
1445  return;
1446  }
1447 #endif
1448 
1449  TraceFunction* caller = lineCall->call()->caller();
1450  TraceFunction* function = _sourceFile->function();
1451  if (caller != function) {
1452  // We regard 2 functions as the same if they have
1453  // same class, name, object
1454  if ((caller->cls() != function->cls()) ||
1455  (caller->name() != function->name()) ||
1456  (caller->object() != function->object())) {
1457 
1458  qDebug("ERROR: Adding line call, line %d\n of %s to\n %s ?!",
1459  lineCall->line()->lineno(),
1460  qPrintable(caller->info()), qPrintable(function->info()));
1461  }
1462  }
1463 
1464  _lineCalls.append(lineCall);
1465  invalidate();
1466 
1467 #if TRACE_DEBUG
1468  qDebug("%s added\n %s (now %d)",
1469  qPrintable( fullName() ),
1470  qPrintable(lineCall->fullName()), _lineCalls.count());
1471 #endif
1472 }
1473 
1474 
1475 QString TraceLine::name() const
1476 {
1477  QString fileShortName = _sourceFile->file()->shortName();
1478  if (fileShortName.isEmpty())
1479  return TraceFile::prettyEmptyName();
1480 
1481  return QString("%1:%2")
1482  .arg(fileShortName).arg(_lineno);
1483 }
1484 
1485 QString TraceLine::prettyName() const
1486 {
1487  return QString("%1 [%2]")
1488  .arg(name()).arg(_sourceFile->function()->prettyName());
1489 }
1490 
1491 //---------------------------------------------------
1492 // TraceCostItem
1493 
1494 TraceCostItem::TraceCostItem(ProfileContext* context)
1495  : TraceInclusiveListCost(context)
1496 {
1497 }
1498 
1499 TraceCostItem::~TraceCostItem()
1500 {}
1501 
1502 
1503 //---------------------------------------------------
1504 // TraceFunctionSource
1505 
1506 TraceFunctionSource::TraceFunctionSource(TraceFunction* function,
1507  TraceFile* file)
1508  : ProfileCostArray(ProfileContext::context(ProfileContext::FunctionSource))
1509 {
1510  _file = file;
1511  _function = function;
1512 
1513  // the function is dependent from our cost sum
1514  _dep = _function;
1515 
1516  _lineMap = 0;
1517  _lineMapFilled = false;
1518  _line0 = 0;
1519 }
1520 
1521 TraceFunctionSource::~TraceFunctionSource()
1522 {
1523  delete _lineMap;
1524  delete _line0;
1525 }
1526 
1527 QString TraceFunctionSource::name() const
1528 {
1529  return QString("%1 for %2").arg(_file->name()).arg(_function->name());
1530 }
1531 
1532 uint TraceFunctionSource::firstLineno()
1533 {
1534  // lazy generate the map if not done up to now
1535  TraceLineMap* map = lineMap();
1536  // ignore line 0 here
1537  if (!map || map->count() == 0) return 0;
1538  TraceLineMap::Iterator it = map->begin();
1539  return (*it).lineno();
1540 }
1541 
1542 uint TraceFunctionSource::lastLineno()
1543 {
1544  // lazy generate the map if not done up to now
1545  TraceLineMap* map = lineMap();
1546  // ignore line 0 here
1547  if (!map || map->count() == 0) return 0;
1548  TraceLineMap::Iterator it = map->end();
1549  --it;
1550  return (*it).lineno();
1551 }
1552 
1553 /* factory */
1554 TraceLine* TraceFunctionSource::line(uint lineno, bool createNew)
1555 {
1556  if (lineno == 0) {
1557  if (!_line0) {
1558  if (!createNew) return 0;
1559  _line0 = new TraceLine;
1560  _line0->setSourceFile(this);
1561  _line0->setLineno(0);
1562  }
1563  return _line0;
1564  }
1565 
1566  if (!createNew) {
1567  if (!_lineMap) return 0;
1568  TraceLineMap::Iterator it = _lineMap->find(lineno);
1569  if (it == _lineMap->end()) return 0;
1570  return &(it.value());
1571  }
1572 
1573  if (!_lineMap) _lineMap = new TraceLineMap;
1574 
1575  TraceLine& l = (*_lineMap)[lineno];
1576  if (!l.isValid()) {
1577  l.setSourceFile(this);
1578  l.setLineno(lineno);
1579 
1580 #if TRACE_DEBUG
1581  qDebug("Created %s [TraceFunctionSource::line]",
1582  qPrintable(l.fullName()));
1583 #endif
1584  }
1585  return &l;
1586 }
1587 
1588 void TraceFunctionSource::update()
1589 {
1590  if (!_dirty) return;
1591 
1592  clear();
1593 
1594  // no need to create lineMap if not already created
1595  if (_lineMap) {
1596  TraceLineMap::Iterator lit;
1597  for ( lit = _lineMap->begin();
1598  lit != _lineMap->end(); ++lit )
1599  addCost( &(*lit) );
1600  }
1601 
1602  _dirty = false;
1603 }
1604 
1605 void TraceFunctionSource::invalidateDynamicCost()
1606 {
1607  // no need to create lineMap if not already created
1608  if (_lineMap) {
1609  TraceLineMap::Iterator lit;
1610  for ( lit = _lineMap->begin();
1611  lit != _lineMap->end(); ++lit )
1612  (*lit).invalidate();
1613  }
1614 
1615  invalidate();
1616 }
1617 
1618 TraceLineMap* TraceFunctionSource::lineMap()
1619 {
1620 #if USE_FIXCOST
1621 
1622  if (_lineMapFilled) return _lineMap;
1623  _lineMapFilled = true;
1624  if (!_lineMap)
1625  _lineMap = new TraceLineMap;
1626 
1627  TraceLine* l = 0;
1628  TracePartLine* pl = 0;
1629  TraceLineCall* lc = 0;
1630  TracePartLineCall* plc = 0;
1631 
1632  /* go over all part objects for this function, and
1633  * - build TraceLines (the line map) using FixCost objects
1634  * - build TraceJumpLines using FixJump objects
1635  */
1636  foreach(TraceInclusiveCost* ic, _function->deps()) {
1637  TracePartFunction* pf = (TracePartFunction*) ic;
1638 
1639  if (0) qDebug("PartFunction %s:%d",
1640  qPrintable(pf->function()->name()),
1641  pf->part()->partNumber());
1642 
1643  FixCost* fc = pf->firstFixCost();
1644  for(; fc; fc = fc->nextCostOfPartFunction()) {
1645  if (fc->line() == 0) continue;
1646  if (fc->functionSource() != this) continue;
1647 
1648  if (!l || l->lineno() != fc->line()) {
1649  l = &(*_lineMap)[fc->line()];
1650  if (!l->isValid()) {
1651  l->setSourceFile(this);
1652  l->setLineno(fc->line());
1653  }
1654  pl = 0;
1655  }
1656  if (!pl || pl->part() != fc->part())
1657  pl = l->partLine(fc->part(), pf);
1658  fc->addTo(pl);
1659  }
1660 
1661  TraceLine* to = 0;
1662  TraceLineJump* lj;
1663  TracePartLineJump* plj;
1664  FixJump* fj = pf->firstFixJump();
1665  for(; fj; fj = fj->nextJumpOfPartFunction()) {
1666  if (fj->line() == 0) continue;
1667  if (fj->source() != this) continue;
1668  if (!fj->targetSource()) {
1669  // be robust against buggy loaders
1670  continue;
1671  }
1672 
1673  // do not display jumps to same or following line
1674  if ((fj->line() == fj->targetLine()) ||
1675  (fj->line()+1 == fj->targetLine())) continue;
1676 
1677  if (!l || l->lineno() != fj->line()) {
1678  l = &(*_lineMap)[fj->line()];
1679  if (!l->isValid()) {
1680  l->setSourceFile(this);
1681  l->setLineno(fj->line());
1682  }
1683  }
1684 
1685  to = fj->targetSource()->line(fj->targetLine(), true);
1686 
1687  lj = l->lineJump(to, fj->isCondJump());
1688  plj = lj->partLineJump(fj->part());
1689 
1690  fj->addTo(plj);
1691  }
1692 
1693  foreach(TracePartCall* pc, pf->partCallings()) {
1694 
1695  if (0) qDebug("PartCall %s:%d",
1696  qPrintable(pc->call()->name()),
1697  pf->part()->partNumber());
1698 
1699  FixCallCost* fcc = pc->firstFixCallCost();
1700  for(; fcc; fcc = fcc->nextCostOfPartCall()) {
1701  if (fcc->line() == 0) continue;
1702  if (fcc->functionSource() != this) continue;
1703 
1704  if (!l || l->lineno() != fcc->line()) {
1705  l = &(*_lineMap)[fcc->line()];
1706  if (!l->isValid()) {
1707  l->setSourceFile(this);
1708  l->setLineno(fcc->line());
1709  }
1710  }
1711  if (!lc || lc->call() != pc->call() || lc->line() != l) {
1712  lc = pc->call()->lineCall(l);
1713  plc = 0;
1714  }
1715  if (!plc || plc->part() != fcc->part())
1716  plc = lc->partLineCall(fcc->part(), pc);
1717 
1718  fcc->addTo(plc);
1719  if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s",
1720  qPrintable(fcc->functionSource()->file()->shortName()),
1721  fcc->line(), qPrintable(fcc->addr().toString()),
1722  qPrintable(fcc->callCount().pretty()));
1723  }
1724  }
1725  }
1726 
1727 #endif
1728 
1729  return _lineMap;
1730 }
1731 
1732 
1733 
1734 //---------------------------------------------------
1735 // TraceAssoziation
1736 
1737 TraceAssoziation::TraceAssoziation()
1738 {
1739  _function = 0;
1740  _valid = false;
1741 }
1742 
1743 TraceAssoziation::~TraceAssoziation()
1744 {
1745  // do not delete from TraceFunction
1746  if (_function) _function->removeAssoziation(this);
1747 }
1748 
1749 bool TraceAssoziation::isAssoziated()
1750 {
1751  if (!_function) return false;
1752 
1753  return _function->assoziation(rtti())==this;
1754 }
1755 
1756 bool TraceAssoziation::setFunction(TraceFunction* f)
1757 {
1758  if (_function == f)
1759  return isAssoziated();
1760 
1761  if (_function) {
1762  // do not delete ourself
1763  _function->removeAssoziation(this);
1764  }
1765 
1766  _function = f;
1767  if (f && f->assoziation(rtti()) == 0) {
1768  f->addAssoziation(this);
1769  return true;
1770  }
1771  return false;
1772 }
1773 
1774 void TraceAssoziation::clear(TraceData* d, int rtti)
1775 {
1776  TraceFunctionMap::Iterator it;
1777  for ( it = d->functionMap().begin();
1778  it != d->functionMap().end(); ++it )
1779  (*it).removeAssoziation(rtti);
1780 }
1781 
1782 void TraceAssoziation::invalidate(TraceData* d, int rtti)
1783 {
1784  TraceFunctionMap::Iterator it;
1785  for ( it = d->functionMap().begin();
1786  it != d->functionMap().end(); ++it )
1787  (*it).invalidateAssoziation(rtti);
1788 }
1789 
1790 
1791 //---------------------------------------------------
1792 // TraceFunction
1793 
1794 TraceFunction::TraceFunction()
1795  : TraceCostItem(ProfileContext::context(ProfileContext::Function))
1796 {
1797  _object = 0;
1798  _file = 0;
1799  _cls = 0;
1800  _cycle = 0;
1801 
1802  _calledCount = 0;
1803  _callingCount = 0;
1804  _calledContexts = 0;
1805  _callingContexts = 0;
1806 
1807  _instrMap = 0;
1808  _instrMapFilled = false;
1809 }
1810 
1811 
1812 TraceFunction::~TraceFunction()
1813 {
1814  qDeleteAll(_assoziations);
1815 
1816  // we are the owner of items generated in our factories
1817  qDeleteAll(_deps);
1818  qDeleteAll(_callings);
1819  qDeleteAll(_sourceFiles);
1820 
1821  delete _instrMap;
1822 }
1823 
1824 // no unique check is done!
1825 void TraceFunction::addAssoziation(TraceAssoziation* a)
1826 {
1827  if (!a) return;
1828  _assoziations.append(a);
1829 }
1830 
1831 void TraceFunction::removeAssoziation(TraceAssoziation* a)
1832 {
1833  _assoziations.removeAll(a);
1834 }
1835 
1836 void TraceFunction::removeAssoziation(int rtti, bool reallyDelete)
1837 {
1838  if (rtti==0) {
1839  if (reallyDelete)
1840  qDeleteAll(_assoziations);
1841  _assoziations.clear();
1842  return;
1843  }
1844 
1845  foreach(TraceAssoziation* a, _assoziations) {
1846  if (a->rtti() == rtti) {
1847  if (reallyDelete) delete a;
1848  _assoziations.removeAll(a);
1849  return;
1850  }
1851  }
1852 }
1853 
1854 void TraceFunction::invalidateAssoziation(int rtti)
1855 {
1856  foreach(TraceAssoziation* a, _assoziations) {
1857  if ((rtti==0) || (a->rtti() == rtti))
1858  a->invalidate();
1859  }
1860 }
1861 
1862 TraceAssoziation* TraceFunction::assoziation(int rtti)
1863 {
1864  foreach(TraceAssoziation* a, _assoziations) {
1865  if (a->rtti() == rtti)
1866  return a;
1867  }
1868  return 0;
1869 }
1870 
1871 #if 0
1872 // helper for prettyName
1873 bool TraceFunction::isUniquePrefix(const QString& prefix) const
1874 {
1875  TraceFunctionMap::ConstIterator it, it2;
1876  it = it2 = _myMapIterator;
1877  if (it != data()->functionBeginIterator()) {
1878  it2--;
1879  if ((*it2).name().startsWith(prefix)) return false;
1880  }
1881  if (it != data()->functionEndIterator()) {
1882  it++;
1883  if ((*it).name().startsWith(prefix)) return false;
1884  }
1885  return true;
1886 }
1887 #endif
1888 
1889 QString TraceFunction::prettyName() const
1890 {
1891  QString res = _name;
1892 
1893  if (_name.isEmpty())
1894  return prettyEmptyName();
1895 
1896  if (GlobalConfig::hideTemplates()) {
1897 
1898  res = QString();
1899  int d = 0;
1900  for(int i=0;i<_name.length();i++) {
1901  switch(_name[i].toLatin1()) {
1902  case '<':
1903  if (d<=0) res.append(_name[i]);
1904  d++;
1905  break;
1906  case '>':
1907  d--;
1908  // fall trough
1909  default:
1910  if (d<=0) res.append(_name[i]);
1911  break;
1912  }
1913  }
1914  }
1915 #if 0
1916  // TODO: make it a configuration, but disabled by default.
1917  //
1918  // Stripping parameter signature of C++ symbols is fine
1919  // if the function name is unique in the whole program.
1920  // However, we only can detect if it is unique in the profile,
1921  // which makes this "beautification" potentially confusing
1922  int p = _name.indexOf('(');
1923  if (p>0) {
1924  // handle C++ "operator()" correct
1925  if ( (p+2 < _name.size()) && (_name[p+1] == ')') && (_name[p+2] == '(')) p+=2;
1926 
1927  // we have a C++ symbol with argument types:
1928  // check for unique function name (inclusive '(' !)
1929  if (isUniquePrefix(_name.left(p+1)))
1930  res = _name.left(p);
1931  }
1932 #endif
1933 
1934  // cycle members
1935  if (_cycle) {
1936  if (_cycle != this)
1937  res = QString("%1 <cycle %2>").arg(res).arg(_cycle->cycleNo());
1938  else
1939  res = QString("<cycle %2>").arg(_cycle->cycleNo());
1940  }
1941 
1942 
1943  return res;
1944 }
1945 
1946 QString TraceFunction::formattedName() const
1947 {
1948  // produce a "rich" name only if templates are hidden
1949  if (!GlobalConfig::hideTemplates() || _name.isEmpty()) return QString();
1950 
1951  // bold, but inside template parameters normal, function arguments italic
1952  QString rich("<b>");
1953  int d = 0;
1954  for(int i=0;i<_name.length();i++) {
1955  switch(_name[i].toLatin1()) {
1956  case '&':
1957  rich.append("&amp;");
1958  break;
1959  case '<':
1960  d++;
1961  rich.append("&lt;");
1962  if (d==1)
1963  rich.append("</b>");
1964  break;
1965  case '>':
1966  d--;
1967  if (d==0)
1968  rich.append("<b>");
1969  rich.append("&gt; "); // add space to allow for line break
1970  break;
1971  case '(':
1972  rich.append("</b>(<i><b>");
1973  break;
1974  case ')':
1975  rich.append("</b></i>)<b>");
1976  break;
1977  default:
1978  rich.append(_name[i]);
1979  break;
1980  }
1981  }
1982  rich.append("</b>");
1983  return rich;
1984 }
1985 
1986 QString TraceFunction::prettyEmptyName()
1987 {
1988  return QObject::tr("(unknown)");
1989 }
1990 
1991 /*
1992  * Returns location string: ELF object and source file(s).
1993  */
1994 QString TraceFunction::location(int maxFiles) const
1995 {
1996  QString loc;
1997 
1998  // add object file with address range
1999  if (_object) {
2000  loc = _object->shortName();
2001 
2002 #if 0
2003  uint from = firstAddress();
2004  uint to = lastAddress();
2005  if (from != 0 && to != 0) {
2006  if (from == to)
2007  loc += QString(" (0x%1)").arg(to, 0, 16);
2008  else
2009  loc += QString(" (0x%1-0x%2)").arg(from, 0, 16).arg(to, 0, 16);
2010  }
2011 #endif
2012  }
2013 
2014  // add all source files
2015  int filesAdded = 0;
2016  foreach(TraceFunctionSource* sourceFile, _sourceFiles) {
2017  if (!sourceFile->file() ||
2018  (sourceFile->file()->name().isEmpty()) )
2019  continue;
2020 
2021  if (!loc.isEmpty())
2022  loc += (filesAdded>0) ? ", " : ": ";
2023  filesAdded++;
2024 
2025  if ((maxFiles>0) && (filesAdded>maxFiles)) {
2026  loc += "...";
2027  break;
2028  }
2029  loc += sourceFile->file()->shortName();
2030 
2031 #if 0
2032  from = sourceFile->firstLineno();
2033  to = sourceFile->lastLineno();
2034  if (from != 0 && to != 0) {
2035  if (from == to)
2036  loc += QString(" (%1)").arg(to);
2037  else
2038  loc += QString(" (%1-%2)").arg(from).arg(to);
2039  }
2040 #endif
2041  }
2042 
2043  return loc;
2044 }
2045 
2046 // pretty version is allowed to mangle the string...
2047 QString TraceFunction::prettyLocation(int maxFiles) const
2048 {
2049  QString l = location(maxFiles);
2050  if (l.isEmpty()) return QObject::tr("(unknown)");
2051 
2052  return l;
2053 }
2054 
2055 void TraceFunction::addPrettyLocation(QString& s, int maxFiles) const
2056 {
2057  QString l = location(maxFiles);
2058  if (l.isEmpty()) return;
2059 
2060  s += QString(" (%1)").arg(l);
2061 }
2062 
2063 QString TraceFunction::prettyNameWithLocation(int maxFiles) const
2064 {
2065  QString l = location(maxFiles);
2066  if (l.isEmpty()) return prettyName();
2067 
2068  return QString("%1 (%2)").arg(prettyName()).arg(l);
2069 }
2070 
2071 QString TraceFunction::info() const
2072 {
2073  QString l = location();
2074  if (l.isEmpty())
2075  return QString("Function %1").arg(name());
2076 
2077  return QString("Function %1 (location %2)")
2078  .arg(name()).arg(l);
2079 }
2080 
2081 
2082 Addr TraceFunction::firstAddress() const
2083 {
2084  // ignore address 0 here
2085  if (!_instrMap || _instrMap->count() == 0) return 0;
2086  TraceInstrMap::ConstIterator it = _instrMap->constBegin();
2087  return (*it).addr();
2088 }
2089 
2090 Addr TraceFunction::lastAddress() const
2091 {
2092  // ignore address 0 here
2093  if (!_instrMap || _instrMap->count() == 0) return 0;
2094  TraceInstrMap::ConstIterator it = _instrMap->constEnd();
2095  --it;
2096  return (*it).addr();
2097 }
2098 
2099 /* factory */
2100 TraceInstr* TraceFunction::instr(Addr addr, bool createNew)
2101 {
2102  // address 0 not allowed
2103  if (addr == Addr(0)) return 0;
2104 
2105  if (!createNew) {
2106  if (!_instrMap) return 0;
2107  TraceInstrMap::Iterator it = _instrMap->find(addr);
2108  if (it == _instrMap->end())
2109  return 0;
2110  return &(it.value());
2111  }
2112 
2113  if (!_instrMap) _instrMap = new TraceInstrMap;
2114 
2115  TraceInstr& i = (*_instrMap)[addr];
2116  if (!i.isValid()) {
2117  i.setAddr(addr);
2118  i.setFunction(this);
2119 
2120 #if TRACE_DEBUG
2121  qDebug("Created %s [TraceFunction::instr]",
2122  qPrintable(i.fullName()));
2123 #endif
2124  }
2125  return &i;
2126 }
2127 
2128 void TraceFunction::addCaller(TraceCall* caller)
2129 {
2130 #if TRACE_ASSERTIONS
2131  if (caller->called() != this) {
2132  qDebug("Can not add call to another line!\n");
2133  return;
2134  }
2135 
2136  if (_callers.contains(caller)) return;
2137 #endif
2138 
2139  _callers.append(caller);
2140  invalidate();
2141 
2142 #if TRACE_DEBUG
2143  qDebug("%s added Caller\n %s (now %d)",
2144  qPrintable( fullName() ), qPrintable(caller->fullName()), _callers.count());
2145 #endif
2146 }
2147 
2148 
2149 
2150 TraceCall* TraceFunction::calling(TraceFunction* called)
2151 {
2152  foreach(TraceCall* calling, _callings)
2153  if (calling->called() == called)
2154  return calling;
2155 
2156  TraceCall* calling = new TraceCall(this, called);
2157  _callings.append(calling);
2158 
2159  // we have to invalidate ourself so invalidations from item propagate up
2160  invalidate();
2161 
2162 #if TRACE_DEBUG
2163  qDebug("Created %s [TraceFunction::calling]", qPrintable(calling->fullName()));
2164 #endif
2165  called->addCaller(calling);
2166  return calling;
2167 }
2168 
2169 TraceFunctionSource* TraceFunction::sourceFile(TraceFile* file,
2170  bool createNew)
2171 {
2172  if (!file) file = _file;
2173 
2174  foreach(TraceFunctionSource* sourceFile, _sourceFiles)
2175  if (sourceFile->file() == file)
2176  return sourceFile;
2177 
2178  if (!createNew) return 0;
2179 
2180  TraceFunctionSource* sourceFile = new TraceFunctionSource(this, file);
2181  _sourceFiles.append(sourceFile);
2182 
2183  // we have to invalidate ourself so invalidations from item propagate up
2184  invalidate();
2185 
2186 #if TRACE_DEBUG
2187  qDebug("Created SourceFile %s [TraceFunction::line]",
2188  qPrintable(file->name()));
2189 #endif
2190  file->addSourceFile(sourceFile);
2191  return sourceFile;
2192 }
2193 
2194 TraceLine* TraceFunction::line(TraceFile* file, uint lineno,
2195  bool createNew)
2196 {
2197  Q_ASSERT(file!=0);
2198 
2199  TraceFunctionSource* sf = sourceFile(file, createNew);
2200  if (!sf)
2201  return 0;
2202  else
2203  return sf->line(lineno, createNew);
2204 }
2205 
2206 
2207 TracePartFunction* TraceFunction::partFunction(TracePart* part,
2208  TracePartFile* partFile,
2209  TracePartObject* partObject)
2210 {
2211  TracePartFunction* item = (TracePartFunction*) findDepFromPart(part);
2212  if (!item) {
2213  item = new TracePartFunction(this, partObject, partFile);
2214  item->setPosition(part);
2215  addDep(item);
2216 #if USE_FIXCOST
2217  part->addDep(item);
2218 #endif
2219 
2220  if (_cls) {
2221  TracePartClass* partClass = _cls->partClass(part);
2222  partClass->addPartFunction(item);
2223  item->setPartClass(partClass);
2224  }
2225 
2226  partFile->addPartFunction(item);
2227  if (partObject)
2228  partObject->addPartFunction(item);
2229  }
2230  else if (item->partObject()==0 && partObject) {
2231  item->setPartObject(partObject);
2232  partObject->addPartFunction(item);
2233  }
2234 
2235  return item;
2236 }
2237 
2238 
2239 SubCost TraceFunction::calledCount()
2240 {
2241  if (_dirty) update();
2242 
2243  return _calledCount;
2244 }
2245 
2246 int TraceFunction::calledContexts()
2247 {
2248  if (_dirty) update();
2249 
2250  return _calledContexts;
2251 }
2252 
2253 SubCost TraceFunction::callingCount()
2254 {
2255  if (_dirty) update();
2256 
2257  return _callingCount;
2258 }
2259 
2260 int TraceFunction::callingContexts()
2261 {
2262  if (_dirty) update();
2263 
2264  return _callingContexts;
2265 }
2266 
2267 QString TraceFunction::prettyCalledCount()
2268 {
2269  return _calledCount.pretty();
2270 }
2271 
2272 QString TraceFunction::prettyCallingCount()
2273 {
2274  return _callingCount.pretty();
2275 }
2276 
2277 
2278 TraceCallList TraceFunction::callers(bool skipCycle) const
2279 {
2280  if (skipCycle) return _callers;
2281 
2282  // fake the callers for cycle members
2283  if (_cycle && (_cycle != this)) {
2284  TraceCallList l;
2285 
2286  // inner-cycle-callers
2287  foreach(TraceCall* c, _callers)
2288  if (c->caller()->cycle() == _cycle)
2289  l.append(c);
2290 
2291  // call from cycle itself
2292  foreach(TraceCall* c, _cycle->_callings)
2293  if (c->called() == this) {
2294  l.append(c);
2295  return l;
2296  }
2297  }
2298 
2299  return _callers;
2300 }
2301 
2302 const TraceCallList& TraceFunction::callings(bool /* skipCycle */) const
2303 {
2304  return _callings;
2305 }
2306 
2307 void TraceFunction::invalidateDynamicCost()
2308 {
2309  foreach(TraceCall* c, _callings)
2310  c->invalidateDynamicCost();
2311 
2312  foreach(TraceFunctionSource* sf, _sourceFiles)
2313  sf->invalidateDynamicCost();
2314 
2315  if (_instrMap) {
2316  TraceInstrMap::Iterator iit;
2317  for ( iit = _instrMap->begin();
2318  iit != _instrMap->end(); ++iit )
2319  (*iit).invalidate();
2320  }
2321 
2322  invalidate();
2323 }
2324 
2325 void TraceFunction::update()
2326 {
2327  if (!_dirty) return;
2328 
2329 #if TRACE_DEBUG
2330  qDebug("Update %s (Callers %d, sourceFiles %d, instrs %d)",
2331  qPrintable(_name), _callers.count(),
2332  _sourceFiles.count(), _instrMap ? _instrMap->count():0);
2333 #endif
2334 
2335  _calledCount = 0;
2336  _callingCount = 0;
2337  _calledContexts = 0;
2338  _callingContexts = 0;
2339  clear();
2340 
2341  // To calculate context counts, we just use first real event type (FIXME?)
2342  EventType* e = data() ? data()->eventTypes()->realType(0) : 0;
2343 
2344  // context count is NOT the sum of part contexts
2345  foreach(TraceCall *caller, _callers) {
2346  if (e && (caller->subCost(e) >0))
2347  _calledContexts++;
2348  _calledCount += caller->callCount();
2349  }
2350 
2351  foreach(TraceCall* callee, _callings) {
2352  if (e && (callee->subCost(e) >0))
2353  _callingContexts++;
2354  _callingCount += callee->callCount();
2355  }
2356 
2357  if (data()->inFunctionCycleUpdate() || !_cycle) {
2358  // usual case (no cycle member)
2359  foreach(TraceInclusiveCost* item, _deps) {
2360  if (!item->part() || !item->part()->isActive()) continue;
2361 
2362  addCost(item);
2363  addInclusive(item->inclusive());
2364  }
2365  }
2366  else {
2367  // this is a cycle or cycle member
2368  foreach(TraceCall* callee, _callings) {
2369 
2370  // ignore inner-cycle member calls for inclusive cost
2371  if ((_cycle != this) &&
2372  (callee->inCycle()>0)) continue;
2373 
2374  addInclusive(callee);
2375  }
2376 
2377  // self cost
2378  if (type() == ProfileContext::FunctionCycle) {
2379  // cycle: self cost is sum of cycle member self costs, but
2380  // does not add to inclusive cost
2381  foreach(TraceFunction* m, ((TraceFunctionCycle*)this)->members())
2382  addCost(m);
2383  }
2384  else {
2385  // cycle member
2386  foreach(TraceInclusiveCost* item, _deps) {
2387  if (!item->part() || !item->part()->isActive()) continue;
2388 
2389  addCost(item);
2390  }
2391  _dirty = false; // do not recurse
2392  addInclusive(this);
2393  }
2394  }
2395  _dirty = false;
2396 
2397 #if TRACE_DEBUG
2398  qDebug("> %s", qPrintable(costString(0)));
2399 #endif
2400 }
2401 
2402 bool TraceFunction::isCycle()
2403 {
2404  return _cycle == this;
2405 }
2406 
2407 bool TraceFunction::isCycleMember()
2408 {
2409  return _cycle && (_cycle != this);
2410 }
2411 
2412 void TraceFunction::cycleReset()
2413 {
2414  _cycle = 0;
2415  _cycleStackDown = 0;
2416  _cycleLow = 0;
2417 }
2418 
2419 // this does not mark functions calling themself !
2420 void TraceFunction::cycleDFS(int d, int& pNo, TraceFunction** pTop)
2421 {
2422  if (_cycleLow != 0) return;
2423 
2424  // initialize with prefix order
2425  pNo++;
2426  int prefixNo = pNo;
2427  _cycleLow = prefixNo;
2428 
2429  // put myself on stack
2430  _cycleStackDown = *pTop;
2431  *pTop = this;
2432 
2433  /* cycle cut heuristic:
2434  * skip calls for cycle detection if they make less than _cycleCut
2435  * percent of the cost of the function.
2436  * FIXME: Which cost type to use for this heuristic ?!
2437  */
2438  Q_ASSERT((data() != 0) && (data()->eventTypes()->realCount()>0));
2439  EventType* e = data()->eventTypes()->realType(0);
2440 
2441  SubCost base = 0;
2442  if (_callers.count()>0) {
2443  foreach(TraceCall* caller, _callers)
2444  if (caller->subCost(e) > base)
2445  base = caller->subCost(e);
2446  }
2447  else base = inclusive()->subCost(e);
2448 
2449  SubCost cutLimit = SubCost(base * GlobalConfig::cycleCut());
2450 
2451  if (0) {
2452  qDebug("%s (%d) Visiting %s",
2453  qPrintable(QString().fill(' ', d)),
2454  pNo, qPrintable(prettyName()));
2455  qDebug("%s Cum. %s, Max Caller %s, cut limit %s",
2456  qPrintable(QString().fill(' ', d)),
2457  qPrintable(inclusive()->subCost(e).pretty()),
2458  qPrintable(base.pretty()),
2459  qPrintable(cutLimit.pretty()));
2460  }
2461 
2462  foreach(TraceCall *callee, _callings) {
2463  TraceFunction* called = callee->called();
2464 
2465  // cycle cut heuristic
2466  if (callee->subCost(e) < cutLimit) {
2467  if (0) qDebug("%s Cut call to %s (cum. %s)",
2468  qPrintable(QString().fill(' ', d)),
2469  qPrintable(called->prettyName()),
2470  qPrintable(callee->subCost(e).pretty()));
2471 
2472  continue;
2473  }
2474 
2475  if (called->_cycleLow==0) {
2476  // not visited yet
2477  called->cycleDFS(d+1, pNo, pTop);
2478  if (called->_cycleLow < _cycleLow)
2479  _cycleLow = called->_cycleLow;
2480  }
2481  else if (called->_cycleStackDown) {
2482  // backlink to same SCC (still in stack)
2483  if (called->_cycleLow < _cycleLow)
2484  _cycleLow = called->_cycleLow;
2485 
2486  if (0) qDebug("%s (low %d) Back to %s",
2487  qPrintable(QString().fill(' ', d)),
2488  _cycleLow, qPrintable(called->prettyName()));
2489  }
2490  }
2491 
2492  if (prefixNo == _cycleLow) {
2493  // this is the base of a SCC.
2494 
2495  if (*pTop == this) {
2496  *pTop = _cycleStackDown;
2497  _cycleStackDown = 0;
2498  }
2499  else {
2500  // a SCC with >1 members
2501 
2502  TraceFunctionCycle* cycle = data()->functionCycle(this);
2503  if (0) qDebug("Found Cycle %d with base %s:",
2504  cycle->cycleNo(), qPrintable(prettyName()));
2505  while(*pTop) {
2506  TraceFunction* top = *pTop;
2507  cycle->add(top);
2508 
2509  // remove from stack
2510  *pTop = top->_cycleStackDown;
2511  top->_cycleStackDown = 0;
2512 
2513  if (0) qDebug(" %s", qPrintable(top->prettyName()));
2514  if (top == this) break;
2515  }
2516  }
2517  }
2518 }
2519 
2520 
2521 TraceInstrMap* TraceFunction::instrMap()
2522 {
2523 #if USE_FIXCOST
2524 
2525  if (_instrMapFilled) return _instrMap;
2526  _instrMapFilled = true;
2527  if (!_instrMap)
2528  _instrMap = new TraceInstrMap;
2529 
2530  TraceLine* l = 0;
2531  TraceInstr* i = 0;
2532  TracePartInstr* pi = 0;
2533  TraceInstrCall* ic = 0;
2534  TracePartInstrCall* pic = 0;
2535 
2536  foreach(TraceInclusiveCost* icost, deps()) {
2537  TracePartFunction* pf = (TracePartFunction*) icost;
2538 
2539  if (0) qDebug("PartFunction %s:%d",
2540  qPrintable(pf->function()->name()),
2541  pf->part()->partNumber());
2542 
2543  FixCost* fc = pf->firstFixCost();
2544  for(; fc; fc = fc->nextCostOfPartFunction()) {
2545  if (fc->addr() == 0) continue;
2546 
2547  if (!l || (l->lineno() != fc->line()) ||
2548  (l->functionSource() != fc->functionSource()))
2549  l = fc->functionSource()->line(fc->line(),true);
2550 
2551  if (!i || i->addr() != fc->addr()) {
2552  i = &(*_instrMap)[fc->addr()];
2553  if (!i->isValid()) {
2554  i->setFunction(this);
2555  i->setAddr(fc->addr());
2556  i->setLine(l);
2557  }
2558  pi = 0;
2559  }
2560  if (!pi || pi->part() != fc->part())
2561  pi = i->partInstr(fc->part(), pf);
2562  fc->addTo(pi);
2563  }
2564 
2565  TraceInstr* to = 0;
2566  TraceInstrJump* ij;
2567  TracePartInstrJump* pij;
2568  FixJump* fj = pf->firstFixJump();
2569  for(; fj; fj = fj->nextJumpOfPartFunction()) {
2570  if (fj->addr() == 0) continue;
2571 
2572  if (!l || (l->lineno() != fj->line()) ||
2573  (l->functionSource() != fj->source()))
2574  l = fj->source()->line(fj->line(),true);
2575 
2576  if (!i || i->addr() != fj->addr()) {
2577  i = &(*_instrMap)[fj->addr()];
2578  if (!i->isValid()) {
2579  i->setFunction(this);
2580  i->setAddr(fj->addr());
2581  i->setLine(l);
2582  }
2583  }
2584 
2585  to = fj->targetFunction()->instr(fj->targetAddr(), true);
2586 
2587  ij = i->instrJump(to, fj->isCondJump());
2588  pij = ij->partInstrJump(fj->part());
2589 
2590  fj->addTo(pij);
2591  }
2592 
2593  foreach(TracePartCall* pc, pf->partCallings()) {
2594 
2595  if (0) qDebug("PartCall %s:%d",
2596  qPrintable(pc->call()->name()),
2597  pf->part()->partNumber());
2598 
2599  FixCallCost* fcc = pc->firstFixCallCost();
2600  for(; fcc; fcc = fcc->nextCostOfPartCall()) {
2601  if (fcc->addr() == 0) continue;
2602 
2603  if (!l || (l->lineno() != fcc->line()) ||
2604  (l->functionSource() != fcc->functionSource()))
2605  l = fcc->functionSource()->line(fcc->line(),true);
2606 
2607  if (!i || i->addr() != fcc->addr()) {
2608  i = &(*_instrMap)[fcc->addr()];
2609  if (!i->isValid()) {
2610  i->setFunction(this);
2611  i->setAddr(fcc->addr());
2612  i->setLine(l);
2613  }
2614  }
2615  if (!ic || ic->call() != pc->call() || ic->instr() != i) {
2616  ic = pc->call()->instrCall(i);
2617  pic = 0;
2618  }
2619  if (!pic || pic->part() != fcc->part())
2620  pic = ic->partInstrCall(fcc->part(), pc);
2621 
2622  fcc->addTo(pic);
2623  if (0) qDebug("Add FixCallCost %s:%d/0x%s, CallCount %s",
2624  qPrintable(fcc->functionSource()->file()->shortName()),
2625  fcc->line(), qPrintable(fcc->addr().toString()),
2626  qPrintable(fcc->callCount().pretty()));
2627  }
2628  }
2629  }
2630 
2631 #endif
2632 
2633  return _instrMap;
2634 }
2635 
2636 
2637 
2638 //---------------------------------------------------
2639 // TraceFunctionCycle
2640 
2641 TraceFunctionCycle::TraceFunctionCycle(TraceFunction* f, int n)
2642 {
2643  _base = f;
2644  _cycleNo = n;
2645  _cycle = this;
2646 
2647  setContext(ProfileContext::context(ProfileContext::FunctionCycle));
2648 
2649  setPosition(f->data());
2650  setName(QString("<cycle %1>").arg(n));
2651 
2652  // reset to attributes of base function
2653  setFile(_base->file());
2654  setClass(_base->cls());
2655  setObject(_base->object());
2656 }
2657 
2658 void TraceFunctionCycle::init()
2659 {
2660  _members.clear();
2661  _callers.clear();
2662  // this deletes all TraceCall's to members
2663  _callings.clear();
2664 
2665  invalidate();
2666 }
2667 
2668 void TraceFunctionCycle::add(TraceFunction* f)
2669 {
2670  _members.append(f);
2671 }
2672 
2673 void TraceFunctionCycle::setup()
2674 {
2675  if (_members.count()==0) return;
2676 
2677  foreach(TraceFunction* f, _members) {
2678 
2679  // the cycle takes all outside callers from its members
2680  foreach(TraceCall* call, f->callers()) {
2681  if (_members.contains(call->caller())) continue;
2682  _callers.append(call);
2683  }
2684 
2685  // the cycle has a call to each member
2686  TraceCall* call = new TraceCall(this, f);
2687  call->invalidate();
2688  _callings.append(call);
2689 
2690  // now do some faking...
2691  f->setCycle(this);
2692  }
2693  invalidate();
2694 }
2695 
2696 
2697 //---------------------------------------------------
2698 // TraceClass
2699 
2700 TraceClass::TraceClass()
2701  : TraceCostItem(ProfileContext::context(ProfileContext::Class))
2702 {}
2703 
2704 TraceClass::~TraceClass()
2705 {
2706  // we are the owner of items generated in our factory
2707  qDeleteAll(_deps);
2708 }
2709 
2710 QString TraceClass::prettyName() const
2711 {
2712  if (_name.isEmpty())
2713  return prettyEmptyName();
2714  return _name;
2715 }
2716 
2717 QString TraceClass::prettyEmptyName()
2718 {
2719  return QObject::tr("(global)");
2720 }
2721 
2722 TracePartClass* TraceClass::partClass(TracePart* part)
2723 {
2724  TracePartClass* item = (TracePartClass*) findDepFromPart(part);
2725  if (!item) {
2726  item = new TracePartClass(this);
2727  item->setPosition(part);
2728  addDep(item);
2729  }
2730  return item;
2731 }
2732 
2733 void TraceClass::addFunction(TraceFunction* function)
2734 {
2735 #if TRACE_ASSERTIONS
2736  if (function->cls() != this) {
2737  qDebug("Can not add function to a class not enclosing this function\n");
2738  return;
2739  }
2740 
2741  if (_functions.contains(function)) return;
2742 #endif
2743 
2744  _functions.append(function);
2745 
2746  invalidate();
2747 
2748 #if TRACE_DEBUG
2749  qDebug("%s added\n %s (now %d)",
2750  qPrintable( fullName() ),
2751  qPrintable(function->fullName()), _functions.count());
2752 #endif
2753 }
2754 
2755 
2756 
2757 //---------------------------------------------------
2758 // TraceFile
2759 
2760 TraceFile::TraceFile()
2761  : TraceCostItem(ProfileContext::context(ProfileContext::File))
2762 {}
2763 
2764 TraceFile::~TraceFile()
2765 {
2766  // we are the owner of items generated in our factory
2767  qDeleteAll(_deps);
2768 }
2769 
2770 TracePartFile* TraceFile::partFile(TracePart* part)
2771 {
2772  TracePartFile* item = (TracePartFile*) findDepFromPart(part);
2773  if (!item) {
2774  item = new TracePartFile(this);
2775  item->setPosition(part);
2776  addDep(item);
2777  }
2778  return item;
2779 }
2780 
2781 void TraceFile::addFunction(TraceFunction* function)
2782 {
2783 #if TRACE_ASSERTIONS
2784  if (function->file() != this) {
2785  qDebug("Can not add function to a file not enclosing this function\n");
2786  return;
2787  }
2788 
2789  if (_functions.contains(function)) return;
2790 #endif
2791 
2792  _functions.append(function);
2793 
2794  invalidate();
2795 
2796 #if TRACE_DEBUG
2797  qDebug("%s added\n %s (now %d)",
2798  qPrintable( fullName() ),
2799  qPrintable(function->fullName()), _functions.count());
2800 #endif
2801 }
2802 
2803 
2804 void TraceFile::addSourceFile(TraceFunctionSource* sourceFile)
2805 {
2806 #if TRACE_ASSERTIONS
2807  if (sourceFile->file() != this) {
2808  qDebug("Can not add sourceFile to a file not having lines for it\n");
2809  return;
2810  }
2811 #endif
2812 
2813  _sourceFiles.append(sourceFile);
2814  // not truly needed, as we do not use the sourceFiles for cost update
2815  invalidate();
2816 
2817 #if TRACE_DEBUG
2818  qDebug("%s \n added SourceFile %s (now %d)",
2819  qPrintable( fullName() ), qPrintable(sourceFile->fullName()),
2820  _sourceFiles.count());
2821 #endif
2822 }
2823 
2824 
2825 
2826 void TraceFile::setDirectory(const QString& dir)
2827 {
2828  if (dir.endsWith('/'))
2829  _dir = dir.left(dir.length()-1);
2830  else
2831  _dir = dir;
2832 }
2833 
2834 QString TraceFile::directory()
2835 {
2836  if (!_dir.isEmpty()) return _dir;
2837 
2838  int lastIndex = 0, index;
2839  while ( (index=_name.indexOf("/", lastIndex)) >=0)
2840  lastIndex = index+1;
2841 
2842  if (lastIndex==0) return QString();
2843 
2844  // without ending "/"
2845  return _name.left(lastIndex-1);
2846 }
2847 
2848 
2849 QString TraceFile::shortName() const
2850 {
2851  int lastIndex = 0, index;
2852  while ( (index=_name.indexOf("/", lastIndex)) >=0)
2853  lastIndex = index+1;
2854 
2855  return _name.mid(lastIndex);
2856 }
2857 
2858 QString TraceFile::prettyName() const
2859 {
2860  QString sn = shortName();
2861 
2862  if (sn.isEmpty())
2863  return prettyEmptyName();
2864 
2865  return sn;
2866 }
2867 
2868 QString TraceFile::prettyEmptyName()
2869 {
2870  return QObject::tr("(unknown)");
2871 }
2872 
2873 QString TraceFile::prettyLongName() const
2874 {
2875  if (_name.isEmpty())
2876  return prettyEmptyName();
2877  return _name;
2878 }
2879 
2880 
2881 //---------------------------------------------------
2882 // TraceObject
2883 
2884 TraceObject::TraceObject()
2885  : TraceCostItem(ProfileContext::context(ProfileContext::Object))
2886 {}
2887 
2888 TraceObject::~TraceObject()
2889 {
2890  // we are the owner of items generated in our factory
2891  qDeleteAll(_deps);
2892 }
2893 
2894 TracePartObject* TraceObject::partObject(TracePart* part)
2895 {
2896  TracePartObject* item = (TracePartObject*) findDepFromPart(part);
2897  if (!item) {
2898  item = new TracePartObject(this);
2899  item->setPosition(part);
2900  addDep(item);
2901  }
2902  return item;
2903 }
2904 
2905 void TraceObject::addFunction(TraceFunction* function)
2906 {
2907 #if TRACE_ASSERTIONS
2908  if (function->object() != this) {
2909  qDebug("Can not add function to an object not enclosing this function\n");
2910  return;
2911  }
2912 
2913  if (_functions.contains(function)) return;
2914 #endif
2915 
2916  _functions.append(function);
2917 
2918  invalidate();
2919 
2920 #if TRACE_DEBUG
2921  qDebug("%s added\n %s (now %d)",
2922  qPrintable( fullName() ),
2923  qPrintable(function->fullName()), _functions.count());
2924 #endif
2925 }
2926 
2927 void TraceObject::setDirectory(const QString& dir)
2928 {
2929  if (dir.endsWith('/'))
2930  _dir = dir.left(dir.length()-1);
2931  else
2932  _dir = dir;
2933 }
2934 
2935 QString TraceObject::directory()
2936 {
2937  if (!_dir.isEmpty()) return _dir;
2938 
2939  int lastIndex = 0, index;
2940  while ( (index=_name.indexOf("/", lastIndex)) >=0)
2941  lastIndex = index+1;
2942 
2943  if (lastIndex==0) return QString();
2944 
2945  // without ending "/"
2946  return _name.left(lastIndex-1);
2947 }
2948 
2949 
2950 QString TraceObject::shortName() const
2951 {
2952  int lastIndex = 0, index;
2953  while ( (index=_name.indexOf("/", lastIndex)) >=0)
2954  lastIndex = index+1;
2955 
2956  return _name.mid(lastIndex);
2957 }
2958 
2959 QString TraceObject::prettyName() const
2960 {
2961  QString sn = shortName();
2962 
2963  if (sn.isEmpty())
2964  return prettyEmptyName();
2965 
2966  return sn;
2967 }
2968 
2969 QString TraceObject::prettyEmptyName()
2970 {
2971  return QObject::tr("(unknown)");
2972 }
2973 
2974 //---------------------------------------------------
2975 // TracePart
2976 
2977 TracePart::TracePart(TraceData* data)
2978  : TraceListCost(ProfileContext::context(ProfileContext::Part))
2979 {
2980  setPosition(data);
2981 
2982  _dep = data;
2983  _active = true;
2984  _number = 0;
2985  _tid = 0;
2986  _pid = 0;
2987 
2988  _eventTypeMapping = 0;
2989 }
2990 
2991 TracePart::~TracePart()
2992 {
2993  delete _eventTypeMapping;
2994 }
2995 
2996 void TracePart::setPartNumber(int n)
2997 {
2998  if (data()->maxPartNumber() <n) data()->setMaxPartNumber(n);
2999  _number = n;
3000 }
3001 
3002 void TracePart::setThreadID(int tid)
3003 {
3004  if (data()->maxThreadID() <tid) data()->setMaxThreadID(tid);
3005  _tid = tid;
3006 }
3007 
3008 void TracePart::setProcessID(int pid)
3009 {
3010  _pid = pid;
3011 }
3012 
3013 
3014 
3015 // strip path
3016 QString TracePart::shortName() const
3017 {
3018  int lastIndex = 0, index;
3019  while ( (index=_name.indexOf("/", lastIndex)) >=0)
3020  lastIndex = index+1;
3021 
3022  return _name.mid(lastIndex);
3023 }
3024 
3025 QString TracePart::prettyName() const
3026 {
3027  if (_pid==0) return shortName();
3028  QString name = QString("PID %1").arg(_pid);
3029  if (_number>0)
3030  name += QString(", section %2").arg(_number);
3031  if ((data()->maxThreadID()>1) && (_tid>0))
3032  name += QString(", thread %3").arg(_tid);
3033  return name;
3034 }
3035 
3036 bool TracePart::activate(bool active)
3037 {
3038  if (_active == active) return false;
3039  _active = active;
3040 
3041  // to be done by the client of this function
3042  // data()->invalidateDynamicCost();
3043  // So better use the TraceData functions...
3044 
3045  return true;
3046 }
3047 
3048 bool TracePart::operator<(const TracePart& p2) const
3049 {
3050  if (processID() < p2.processID()) return true;
3051 
3052  if (processID() == p2.processID()) {
3053  if (partNumber() < p2.partNumber()) return true;
3054 
3055  if (partNumber() == p2.partNumber())
3056  return (threadID() < p2.threadID());
3057  }
3058  return false;
3059 }
3060 
3061 
3062 //---------------------------------------------------
3063 // TraceData
3064 
3065 
3066 // create vectors with reasonable default sizes, but not wasting memory
3067 TraceData::TraceData(Logger* l)
3068  : ProfileCostArray(ProfileContext::context(ProfileContext::Data))
3069 {
3070  _logger = l;
3071  init();
3072 }
3073 
3074 void TraceData::init()
3075 {
3076  _functionCycleCount = 0;
3077  _inFunctionCycleUpdate = false;
3078 
3079  _maxThreadID = 0;
3080  _maxPartNumber = 0;
3081  _fixPool = 0;
3082  _dynPool = 0;
3083 }
3084 
3085 TraceData::~TraceData()
3086 {
3087  qDeleteAll(_parts);
3088 
3089  delete _fixPool;
3090  delete _dynPool;
3091 }
3092 
3093 QString TraceData::shortTraceName() const
3094 {
3095  int lastIndex = 0, index;
3096  while ( (index=_traceName.indexOf("/", lastIndex)) >=0)
3097  lastIndex = index+1;
3098 
3099  return _traceName.mid(lastIndex);
3100 }
3101 
3102 FixPool* TraceData::fixPool()
3103 {
3104  if (!_fixPool)
3105  _fixPool = new FixPool();
3106 
3107  return _fixPool;
3108 }
3109 
3110 DynPool* TraceData::dynPool()
3111 {
3112  if (!_dynPool)
3113  _dynPool = new DynPool();
3114 
3115  return _dynPool;
3116 }
3117 
3118 bool partLessThan(const TracePart* p1, const TracePart* p2)
3119 {
3120  return *p1 < *p2;
3121 }
3122 
3130 int TraceData::load(QStringList files)
3131 {
3132  if (files.isEmpty()) return 0;
3133 
3134  _traceName = files[0];
3135  if (files.count() == 1) {
3136  QFileInfo finfo(_traceName);
3137  QString prefix = finfo.fileName();
3138  QDir dir = finfo.dir();
3139  if (finfo.isDir()) {
3140  prefix = "callgrind.out";
3141  _traceName += "/callgrind.out";
3142  }
3143 
3144  files = dir.entryList(QStringList() << prefix + "*", QDir::Files);
3145  QStringList::Iterator it = files.begin();
3146  for (; it != files.end(); ++it ) {
3147  *it = dir.path() + "/" + *it;
3148  }
3149  }
3150 
3151  if (files.isEmpty()) {
3152  _traceName += ' ' + QObject::tr("(not found)");
3153  return 0;
3154  }
3155 
3156  QStringList::const_iterator it;
3157  int partsLoaded = 0;
3158  for (it = files.constBegin(); it != files.constEnd(); ++it ) {
3159  QFile file(*it);
3160  partsLoaded += internalLoad(&file, *it);
3161  }
3162  if (partsLoaded == 0) return 0;
3163 
3164  qSort(_parts.begin(), _parts.end(), partLessThan);
3165  invalidateDynamicCost();
3166  updateFunctionCycles();
3167 
3168  return partsLoaded;
3169 }
3170 
3171 int TraceData::load(QString file)
3172 {
3173  return load(QStringList(file));
3174 }
3175 
3176 int TraceData::load(QIODevice* file, const QString& filename)
3177 {
3178  _traceName = filename;
3179  int partsLoaded = internalLoad(file, filename);
3180  if (partsLoaded>0) {
3181  invalidateDynamicCost();
3182  updateFunctionCycles();
3183  }
3184  return partsLoaded;
3185 }
3186 
3187 int TraceData::internalLoad(QIODevice* device, const QString& filename)
3188 {
3189  if (!device->open( QIODevice::ReadOnly ) ) {
3190  _logger->loadStart(filename);
3191  _logger->loadFinished(QString(strerror( errno )));
3192  return 0;
3193  }
3194 
3195  Loader* l = Loader::matchingLoader(device);
3196  if (!l) {
3197  // special case emtpy file: ignore...
3198  if (device->size() == 0) return 0;
3199 
3200  _logger->loadStart(filename);
3201  _logger->loadFinished(QString("Unknown file format"));
3202  return 0;
3203  }
3204  l->setLogger(_logger);
3205 
3206  int partsLoaded = l->load(this, device, filename);
3207 
3208  l->setLogger(0);
3209 
3210  return partsLoaded;
3211 }
3212 
3213 bool TraceData::activateParts(const TracePartList& l)
3214 {
3215  bool changed = false;
3216 
3217  foreach(TracePart* part, _parts)
3218  if (part->activate(l.contains(part)))
3219  changed = true;
3220 
3221  if (changed) {
3222  // because active parts have changed, throw away calculated
3223  // costs...
3224  invalidateDynamicCost();
3225  updateFunctionCycles();
3226  }
3227 
3228  return changed;
3229 }
3230 
3231 
3232 bool TraceData::activateParts(TracePartList l, bool active)
3233 {
3234  bool changed = false;
3235 
3236  foreach(TracePart* part, l) {
3237  if (_parts.contains(part))
3238  if (part->activate(active))
3239  changed = true;
3240  }
3241 
3242  if (changed) {
3243  invalidateDynamicCost();
3244  updateFunctionCycles();
3245  }
3246 
3247  return changed;
3248 }
3249 
3250 bool TraceData::activatePart(TracePart* p, bool active)
3251 {
3252  return p->activate(active);
3253 }
3254 
3255 bool TraceData::activateAll(bool active)
3256 {
3257  return activateParts(_parts, active);
3258 }
3259 
3260 void TraceData::addPart(TracePart* part)
3261 {
3262  if (_parts.contains(part)>0) return;
3263 
3264  if ((part->partNumber()==0) &&
3265  (part->processID()==0)) {
3266  _maxPartNumber++;
3267  part->setPartNumber(_maxPartNumber);
3268  }
3269  _parts.append(part);
3270 }
3271 
3272 TracePart* TraceData::partWithName(const QString& name)
3273 {
3274  foreach(TracePart* part, _parts)
3275  if (part->name() == name)
3276  return part;
3277  return 0;
3278 }
3279 
3280 QString TraceData::activePartRange()
3281 {
3282  QString res;
3283  int r1=-1, r2=-1, count=0;
3284  foreach(TracePart* part, _parts) {
3285  count++;
3286  if (part->isActive()) {
3287  if (r1<0) { r1 = r2 = count; }
3288  else if (r2 == count-1) { r2 = count; }
3289  else {
3290  if (!res.isEmpty()) res += ';';
3291  if (r1==r2) res += QString::number(r1);
3292  else res += QString("%1-%2").arg(r1).arg(r2);
3293  r1 = r2 = count;
3294  }
3295  }
3296  }
3297  if (r1>=0) {
3298  if (!res.isEmpty()) res += ';';
3299  if (r1==r2) res += QString::number(r1);
3300  else res += QString("%1-%2").arg(r1).arg(r2);
3301  }
3302 
3303  return res;
3304 }
3305 
3306 void TraceData::invalidateDynamicCost()
3307 {
3308  // invalidate all dynamic costs
3309 
3310  TraceObjectMap::Iterator oit;
3311  for ( oit = _objectMap.begin();
3312  oit != _objectMap.end(); ++oit )
3313  (*oit).invalidate();
3314 
3315  TraceClassMap::Iterator cit;
3316  for ( cit = _classMap.begin();
3317  cit != _classMap.end(); ++cit )
3318  (*cit).invalidate();
3319 
3320  TraceFileMap::Iterator fit;
3321  for ( fit = _fileMap.begin();
3322  fit != _fileMap.end(); ++fit )
3323  (*fit).invalidate();
3324 
3325  TraceFunctionMap::Iterator it;
3326  for ( it = _functionMap.begin();
3327  it != _functionMap.end(); ++it ) {
3328  (*it).invalidateDynamicCost();
3329  }
3330 
3331  invalidate();
3332 
3333 }
3334 
3335 
3336 TraceObject* TraceData::object(const QString& name)
3337 {
3338  TraceObject& o = _objectMap[name];
3339  if (!o.data()) {
3340  // was created
3341  o.setPosition(this);
3342  o.setName(name);
3343 
3344 #if TRACE_DEBUG
3345  qDebug("Created %s [TraceData::object]",
3346  qPrintable(o.fullName()));
3347 #endif
3348  }
3349  return &o;
3350 }
3351 
3352 
3353 TraceFile* TraceData::file(const QString& name)
3354 {
3355  TraceFile& f = _fileMap[name];
3356  if (!f.data()) {
3357  // was created
3358  f.setPosition(this);
3359  f.setName(name);
3360 
3361 #if TRACE_DEBUG
3362  qDebug("Created %s [TraceData::file]",
3363  qPrintable(f.fullName()));
3364 #endif
3365  }
3366  return &f;
3367 }
3368 
3369 
3370 // usually only called by function()
3371 TraceClass* TraceData::cls(const QString& fnName, QString& shortName)
3372 {
3373  int lastIndex = 0, index, pIndex;
3374 
3375  // we ignore any "::" after a '(' or a space
3376  pIndex=fnName.indexOf('(', 0);
3377 
3378 #if 0
3379  int sIndex=fnName.find(" ", 0);
3380  if (sIndex>=0)
3381  if ((pIndex == -1) || (sIndex < pIndex))
3382  pIndex = sIndex;
3383 #endif
3384 
3385  while ((index=fnName.indexOf("::", lastIndex)) >=0) {
3386  if (pIndex>=0 && pIndex<index) break;
3387  lastIndex = index+2;
3388  }
3389 
3390  QString clsName = (lastIndex < 3) ? QString::null : //krazy:exclude=nullstrassign for old broken gcc
3391  fnName.left(lastIndex-2);
3392  shortName = fnName.mid(lastIndex);
3393 
3394  TraceClass& c = _classMap[clsName];
3395  if (!c.data()) {
3396  // was created
3397  c.setPosition(this);
3398  c.setName(clsName);
3399 
3400 #if TRACE_DEBUG
3401  qDebug("Created %s [TraceData::cls]",
3402  qPrintable(c.fullName()));
3403 #endif
3404  }
3405  return &c;
3406 }
3407 
3408 
3409 // name is inclusive class/namespace prefix
3410 TraceFunction* TraceData::function(const QString& name,
3411  TraceFile* file, TraceObject* object)
3412 {
3413  // strip class name
3414  QString shortName;
3415  TraceClass* c = cls(name, shortName);
3416 
3417  if (!file || !object || !c) {
3418  qDebug("ERROR - no file/object/class for %s ?!", qPrintable(name));
3419  return 0;
3420  }
3421 
3422  // Use object name and file name as part of key, to get distinct
3423  // function objects for functions with same name but defined in
3424  // different ELF objects or different files (this is possible e.g.
3425  // in C by using "static").
3426  //
3427  // Note about usage of this factory method by the Cachegrind loader:
3428  // that dump format does not explicitly specify the attribution
3429  // of functions to ELF objects and files. Rather, cost is attributed
3430  // to ELF object, source file and function. We use the first cost
3431  // seen for a function to bind an ELF object and source file to that
3432  // function. Callgrind always prints the cost of the instruction at
3433  // function entry first, so there, this strategy works.
3434  // But such an order is not enforced by the format. If the cost of
3435  // an inlined function from another source file would be printed first,
3436  // the attribution would go wrong. The format also allows cost of
3437  // the same function to be spreaded over the dump. With wrong
3438  // attributions, it can happen that cost of the same function is
3439  // interpreted as being from distinct functions.
3440  // For a correct solution, the format needs to be more expressive,
3441  // or the ordering of costs specified.
3442  // Previously, the file name was left out from the key.
3443  // The change was motivated by bug ID 3014067 (on SourceForge).
3444  QString key = name + file->shortName() + object->shortName();
3445 
3446  TraceFunctionMap::Iterator it;
3447  it = _functionMap.find(key);
3448  if (it == _functionMap.end()) {
3449  it = _functionMap.insert(key, TraceFunction());
3450  TraceFunction& f = it.value();
3451 
3452  f.setPosition(this);
3453  f.setName(name);
3454  f.setClass(c);
3455  f.setObject(object);
3456  f.setFile(file);
3457  //f.setMapIterator(it);
3458 
3459 #if TRACE_DEBUG
3460  qDebug("Created %s [TraceData::function]\n for %s, %s, %s",
3461  qPrintable(f.fullName()),
3462  qPrintable(c->fullName()), qPrintable(file->fullName()),
3463  object ? qPrintable(object->fullName()) : "(unknown object)");
3464 #endif
3465 
3466  c->addFunction(&f);
3467  object->addFunction(&f);
3468  file->addFunction(&f);
3469  }
3470 
3471  return &(it.value());
3472 }
3473 
3474 TraceFunctionMap::Iterator TraceData::functionIterator(TraceFunction* f)
3475 {
3476 
3477  // IMPORTANT: build as SAME key as used in function() above !!
3478  QString key;
3479 
3480  if (f->cls()) key = f->cls()->name() + "::";
3481  key += f->name();
3482  key += f->object()->shortName();
3483 
3484  return _functionMap.find(key);
3485 }
3486 
3487 TraceFunctionMap::ConstIterator TraceData::functionBeginIterator() const
3488 {
3489  return _functionMap.begin();
3490 }
3491 
3492 TraceFunctionMap::ConstIterator TraceData::functionEndIterator() const
3493 {
3494  return _functionMap.end();
3495 }
3496 
3497 
3498 void TraceData::resetSourceDirs()
3499 {
3500  TraceFileMap::Iterator fit;
3501  for ( fit = _fileMap.begin();
3502  fit != _fileMap.end(); ++fit )
3503  (*fit).resetDirectory();
3504 }
3505 
3506 void TraceData::update()
3507 {
3508  if (!_dirty) return;
3509 
3510  clear();
3511  _totals.clear();
3512 
3513  foreach(TracePart* part, _parts) {
3514  _totals.addCost(part->totals());
3515  if (part->isActive())
3516  addCost(part->totals());
3517  }
3518 
3519  _dirty = false;
3520 }
3521 
3522 ProfileCostArray* TraceData::search(ProfileContext::Type t, QString name,
3523  EventType* ct, ProfileCostArray* parent)
3524 {
3525  ProfileCostArray* result = 0;
3526  ProfileContext::Type pt;
3527  SubCost sc, scTop = 0;
3528 
3529  pt = parent ? parent->type() : ProfileContext::InvalidType;
3530  switch(t) {
3531  case ProfileContext::Function:
3532  {
3533  TraceFunction *f;
3534  TraceFunctionMap::Iterator it;
3535  for ( it = _functionMap.begin();
3536  it != _functionMap.end(); ++it ) {
3537  f = &(*it);
3538 
3539  if (f->name() != name) continue;
3540 
3541  if ((pt == ProfileContext::Class) && (parent != f->cls())) continue;
3542  if ((pt == ProfileContext::File) && (parent != f->file())) continue;
3543  if ((pt == ProfileContext::Object) && (parent != f->object())) continue;
3544 
3545  if (ct) {
3546  sc = f->inclusive()->subCost(ct);
3547  if (sc <= scTop) continue;
3548  scTop = sc;
3549  }
3550 
3551  result = f;
3552  }
3553  }
3554  break;
3555 
3556  case ProfileContext::File:
3557  {
3558  TraceFile *f;
3559  TraceFileMap::Iterator it;
3560  for ( it = _fileMap.begin();
3561  it != _fileMap.end(); ++it ) {
3562  f = &(*it);
3563  if (f->name() != name) continue;
3564  if (ct) {
3565  sc = f->subCost(ct);
3566  if (sc <= scTop) continue;
3567  scTop = sc;
3568  }
3569  result = f;
3570  }
3571  }
3572  break;
3573 
3574  case ProfileContext::Class:
3575  {
3576  TraceClass *c;
3577  TraceClassMap::Iterator it;
3578  for ( it = _classMap.begin();
3579  it != _classMap.end(); ++it ) {
3580  c = &(*it);
3581  if (c->name() != name) continue;
3582  if (ct) {
3583  sc = c->subCost(ct);
3584  if (sc <= scTop) continue;
3585  scTop = sc;
3586  }
3587  result = c;
3588  }
3589  }
3590  break;
3591 
3592  case ProfileContext::Object:
3593  {
3594  TraceObject *o;
3595  TraceObjectMap::Iterator it;
3596  for ( it = _objectMap.begin();
3597  it != _objectMap.end(); ++it ) {
3598  o = &(*it);
3599  if (o->name() != name) continue;
3600  if (ct) {
3601  sc = o->subCost(ct);
3602  if (sc <= scTop) continue;
3603  scTop = sc;
3604  }
3605  result = o;
3606  }
3607  }
3608  break;
3609 
3610  case ProfileContext::Instr:
3611  if (pt == ProfileContext::Function) {
3612  TraceInstrMap* instrMap = ((TraceFunction*)parent)->instrMap();
3613  if (!instrMap) break;
3614 
3615  TraceInstr *instr;
3616  TraceInstrMap::Iterator it;
3617  for ( it = instrMap->begin();
3618  it != instrMap->end(); ++it ) {
3619  instr = &(*it);
3620  if (instr->name() != name) continue;
3621  result = instr;
3622  }
3623  }
3624  break;
3625 
3626  case ProfileContext::Line:
3627  {
3628  TraceFunctionSourceList sList;
3629  if (pt == ProfileContext::Function)
3630  sList = ((TraceFunction*)parent)->sourceFiles();
3631  else if (pt == ProfileContext::FunctionSource)
3632  sList.append((TraceFunctionSource*) parent);
3633  else break;
3634 
3635  TraceLineMap* lineMap;
3636  TraceLine* line;
3637  TraceLineMap::Iterator it;
3638  foreach(TraceFunctionSource* fs, sList) {
3639  lineMap = fs->lineMap();
3640  if (!lineMap) continue;
3641 
3642  for ( it = lineMap->begin();
3643  it != lineMap->end(); ++it ) {
3644  line = &(*it);
3645  if (line->name() != name) continue;
3646  result = line;
3647  }
3648  }
3649  }
3650  break;
3651 
3652  default:
3653  break;
3654  }
3655 
3656  return result;
3657 }
3658 
3659 
3660 TraceFunctionCycle* TraceData::functionCycle(TraceFunction* f)
3661 {
3662  TraceFunctionCycle* cycle;
3663  foreach(cycle, _functionCycles)
3664  if (cycle->base() == f)
3665  return cycle;
3666 
3667  _functionCycleCount++;
3668  cycle = new TraceFunctionCycle(f, _functionCycleCount);
3669 
3670  _functionCycles.append(cycle);
3671  return cycle;
3672 }
3673 
3674 
3675 void TraceData::updateFunctionCycles()
3676 {
3677  //qDebug("Updating cycles...");
3678 
3679  // init cycle info
3680  foreach(TraceFunctionCycle* cycle, _functionCycles)
3681  cycle->init();
3682 
3683  TraceFunctionMap::Iterator it;
3684  for ( it = _functionMap.begin(); it != _functionMap.end(); ++it )
3685  (*it).cycleReset();
3686 
3687  if (!GlobalConfig::showCycles()) return;
3688 
3689  _inFunctionCycleUpdate = true;
3690 
3691 
3692 #if 0
3693  int fCount = _functionMap.size(), fNo = 0, progress=0, p;
3694  QString msg = tr("Recalculating Function Cycles...");
3695  if (_topLevel) _topLevel->showStatus(msg,0);
3696 #endif
3697 
3698  // DFS and collapse strong connected components (Tarjan)
3699  int pNo = 0;
3700  TraceFunction* stackTop;
3701  for ( it = _functionMap.begin(); it != _functionMap.end(); ++it ) {
3702 
3703 #if 0
3704  if (_topLevel) {
3705  fNo++;
3706  p = 100*fNo/fCount;
3707  if (p> progress) {
3708  progress = p;
3709  _topLevel->showStatus(msg, p);
3710  }
3711  }
3712 #endif
3713 
3714  stackTop = 0;
3715  (*it).cycleDFS(1, pNo, &stackTop);
3716  }
3717 
3718  // postprocess cycles
3719  foreach(TraceFunctionCycle* cycle, _functionCycles)
3720  cycle->setup();
3721 
3722  _inFunctionCycleUpdate = false;
3723  // we have to invalidate costs because cycles are now taken into account
3724  invalidateDynamicCost();
3725 
3726 #if 0
3727  if (0) if (_topLevel) _topLevel->showStatus(QString(), 0);
3728 #endif
3729 }
3730 
3731 void TraceData::updateObjectCycles()
3732 {
3733 }
3734 
3735 
3736 void TraceData::updateClassCycles()
3737 {
3738 }
3739 
3740 
3741 void TraceData::updateFileCycles()
3742 {
3743 }
3744 
Logger
Definition: logger.h:32
TracePartCall::TracePartCall
TracePartCall(TraceCall *call)
Definition: tracedata.cpp:566
TraceCallListCost
Call Cost Item depends on a list of Call cost items.
Definition: tracedata.h:334
TraceCallCost::TraceCallCost
TraceCallCost(ProfileContext *)
Definition: tracedata.cpp:97
FixCallCost::nextCostOfPartCall
FixCallCost * nextCostOfPartCall() const
Definition: fixcost.h:117
TraceInclusiveListCost::deps
TraceInclusiveCostList deps()
Definition: tracedata.h:371
TraceJumpCost::addCost
void addCost(TraceJumpCost *)
Definition: tracedata.cpp:84
TraceCall::isRecursion
bool isRecursion()
Definition: tracedata.h:844
CostItem::part
virtual TracePart * part()
Definition: costitem.cpp:101
TraceFunction::setFile
void setFile(TraceFile *file)
Definition: tracedata.h:1186
TraceFunction::addCaller
void addCaller(TraceCall *)
Definition: tracedata.cpp:2128
TraceFile
A source file containing function definitions.
Definition: tracedata.h:1295
TracePartClass::TracePartClass
TracePartClass(TraceClass *)
Definition: tracedata.cpp:880
TraceData::TraceData
TraceData(Logger *l=0)
Definition: tracedata.cpp:3067
TraceCallListCost::TraceCallListCost
TraceCallListCost(ProfileContext *)
Definition: tracedata.cpp:329
TraceInstr::isValid
bool isValid()
Definition: tracedata.h:896
TraceInstr::setAddr
void setAddr(const Addr addr)
Definition: tracedata.h:913
TracePartInstrJump::~TracePartInstrJump
virtual ~TracePartInstrJump()
Definition: tracedata.cpp:490
TracePart::name
QString name() const
Definition: tracedata.h:667
TraceFile::TraceFile
TraceFile()
Definition: tracedata.cpp:2760
TraceLine::addLineCall
void addLineCall(TraceLineCall *)
Definition: tracedata.cpp:1438
ProfileCostArray::subCost
SubCost subCost(EventType *)
Returns a sub cost.
Definition: costitem.cpp:591
TraceData::activatePart
bool activatePart(TracePart *, bool active)
Definition: tracedata.cpp:3250
TraceFunctionSource::line
TraceLine * line(uint lineno, bool createNew=true)
Definition: tracedata.cpp:1554
globalconfig.h
TracePart::processID
int processID() const
Definition: tracedata.h:674
ProfileContext::Line
Definition: context.h:39
ProfileContext::FunctionCycle
Definition: context.h:46
TraceData::cls
TraceClass * cls(const QString &fnName, QString &shortName)
Definition: tracedata.cpp:3371
partLessThan
bool partLessThan(const TracePart *p1, const TracePart *p2)
Definition: tracedata.cpp:3118
CostItem::_dep
CostItem * _dep
Definition: costitem.h:127
TraceData::object
TraceObject * object(const QString &name)
Definition: tracedata.cpp:3336
TraceCallListCost::onlyActiveParts
virtual bool onlyActiveParts()
Definition: tracedata.h:349
TraceFunctionCycle::cycleNo
int cycleNo() const
Definition: tracedata.h:1253
DynPool
DynPool.
Definition: pool.h:77
TracePartCall::call
TraceCall * call() const
Definition: tracedata.h:528
TraceInclusiveCost
Cost item with additional inclusive metric.
Definition: tracedata.h:251
TracePartFunction::function
TraceFunction * function()
Definition: tracedata.h:558
TraceData::activateAll
bool activateAll(bool active=true)
Definition: tracedata.cpp:3255
TraceFunction::~TraceFunction
virtual ~TraceFunction()
Definition: tracedata.cpp:1812
TracePartClass::~TracePartClass
virtual ~TracePartClass()
Definition: tracedata.cpp:886
TraceFunction::callingContexts
int callingContexts()
Definition: tracedata.cpp:2260
TracePartLineCall
Cost of a call at a line from a trace file.
Definition: tracedata.h:467
TraceInclusiveListCost::onlyActiveParts
virtual bool onlyActiveParts()
Definition: tracedata.h:377
TracePartLineCall::lineCall
TraceLineCall * lineCall() const
Definition: tracedata.h:475
TraceLine::hasCost
bool hasCost(EventType *)
Definition: tracedata.cpp:1394
TracePartInstrCall::~TracePartInstrCall
virtual ~TracePartInstrCall()
Definition: tracedata.cpp:503
FixJump::isCondJump
bool isCondJump() const
Definition: fixcost.h:161
TracePartFunction::addPartInstr
void addPartInstr(TracePartInstr *)
Definition: tracedata.cpp:662
TraceLineMap
QMap< uint, TraceLine > TraceLineMap
Definition: tracedata.h:194
ProfileContext::File
Definition: context.h:48
TraceFunction::callings
const TraceCallList & callings(bool skipCycle=false) const
Definition: tracedata.cpp:2302
TraceObject::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:2959
TraceFunction::setCycle
void setCycle(TraceFunctionCycle *c)
Definition: tracedata.h:1199
TraceFunctionCycle
A cycle of recursive calling functions.
Definition: tracedata.h:1241
TraceData::search
ProfileCostArray * search(ProfileContext::Type, QString, EventType *ct=0, ProfileCostArray *parent=0)
Search for item with given name and highest subcost of given cost type.
Definition: tracedata.cpp:3522
TracePartObject::~TracePartObject
virtual ~TracePartObject()
Definition: tracedata.cpp:918
TraceLineJump::lineTo
TraceLine * lineTo() const
Definition: tracedata.h:764
TraceInstrJump::TraceInstrJump
TraceInstrJump(TraceInstr *instrFrom, TraceInstr *instrTo, bool isCondJump)
Definition: tracedata.cpp:927
TraceInstrJump::instrTo
TraceInstr * instrTo() const
Definition: tracedata.h:737
TraceData::partWithName
TracePart * partWithName(const QString &name)
Definition: tracedata.cpp:3272
CostItem::update
virtual void update()
Updates cost attributes.
Definition: costitem.cpp:96
TraceCall::caller
TraceFunction * caller(bool skipCycle=false) const
Definition: tracedata.cpp:1230
CostItem::type
ProfileContext::Type type() const
Definition: costitem.h:45
TraceListCost::findDepFromPart
ProfileCostArray * findDepFromPart(TracePart *)
Definition: tracedata.cpp:211
TracePartFunction::partObject
TracePartObject * partObject()
Definition: tracedata.h:559
TraceCostItem::TraceCostItem
TraceCostItem(ProfileContext *)
Definition: tracedata.cpp:1494
TraceInstr::~TraceInstr
virtual ~TraceInstr()
Definition: tracedata.cpp:1294
TraceFunction::line
TraceLine * line(TraceFile *, uint lineno, bool createNew=true)
Definition: tracedata.cpp:2194
TracePart::totals
ProfileCostArray * totals()
Definition: tracedata.h:683
TracePartInstrJump::instrJump
TraceInstrJump * instrJump() const
Definition: tracedata.h:406
TraceFunction::lastAddress
Addr lastAddress() const
Definition: tracedata.cpp:2090
TraceFunctionSource::invalidateDynamicCost
void invalidateDynamicCost()
Definition: tracedata.cpp:1605
TraceCallCost::costString
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
Definition: tracedata.cpp:107
TracePart::partNumber
int partNumber() const
Definition: tracedata.h:672
TraceInstr::setFunction
void setFunction(TraceFunction *f)
Definition: tracedata.h:914
TracePartLineJump::~TracePartLineJump
virtual ~TracePartLineJump()
Definition: tracedata.cpp:531
TracePartLineJump::lineJump
TraceLineJump * lineJump() const
Definition: tracedata.h:459
TraceFunction
A traced function.
Definition: tracedata.h:1122
TraceCostItem
Definition: tracedata.h:980
TraceJumpCost::executedCount
SubCost executedCount()
Definition: tracedata.cpp:55
Logger::loadStart
virtual void loadStart(const QString &filename)
Definition: logger.cpp:33
Loader::setLogger
void setLogger(Logger *)
Definition: loader.cpp:87
TraceJumpCost::clear
virtual void clear()
Set all cost counters to zero.
Definition: tracedata.cpp:78
TraceFile::setDirectory
void setDirectory(const QString &dir)
Definition: tracedata.cpp:2826
TraceFunctionSource::function
TraceFunction * function() const
Definition: tracedata.h:1041
TraceInstrMap
QMap< Addr, TraceInstr > TraceInstrMap
Definition: tracedata.h:195
TraceCostItem::_name
QString _name
Definition: tracedata.h:993
TraceJumpListCost::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:300
TraceCallCost::addCallCount
void addCallCount(SubCost c)
Definition: tracedata.cpp:132
TraceCallCost::callCount
SubCost callCount()
Definition: tracedata.cpp:125
TraceFunction::formattedName
QString formattedName() const
A HTMLified version of name, can return empty string.
Definition: tracedata.cpp:1946
TraceFunction::object
TraceObject * object() const
Definition: tracedata.h:1164
TraceInclusiveCost::~TraceInclusiveCost
virtual ~TraceInclusiveCost()
Definition: tracedata.cpp:147
CostItem::setContext
void setContext(ProfileContext *context)
Redefine the context after construction.
Definition: costitem.h:108
TracePartLine::~TracePartLine
virtual ~TracePartLine()
Definition: tracedata.cpp:557
TraceFunction::prettyCallingCount
QString prettyCallingCount()
Definition: tracedata.cpp:2272
TraceFunctionCycle::add
void add(TraceFunction *)
Definition: tracedata.cpp:2668
TraceLine::isValid
bool isValid()
Definition: tracedata.h:952
TracePartFunction::callingCount
SubCost callingCount()
Definition: tracedata.cpp:759
TraceLineJump::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1029
TraceJumpListCost::onlyActiveParts
virtual bool onlyActiveParts()
Definition: tracedata.h:318
TraceFunction::cycle
TraceFunctionCycle * cycle()
Definition: tracedata.h:1200
ProfileCostArray::invalidate
virtual void invalidate()
Invalidate the cost attributes.
Definition: costitem.cpp:562
TraceLine::lineJump
TraceLineJump * lineJump(TraceLine *to, bool isCondJump)
Definition: tracedata.cpp:1426
TraceFunctionSource::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:1588
CostItem
Base class for cost items.
Definition: costitem.h:37
TraceData::function
TraceFunction * function(const QString &name, TraceFile *, TraceObject *)
Definition: tracedata.cpp:3410
TraceCallListCost::_deps
TraceCallCostList _deps
Definition: tracedata.h:351
TracePartFunction::addPartLine
void addPartLine(TracePartLine *)
Definition: tracedata.cpp:683
TraceInstrCall
A call from an instruction of one function to another function.
Definition: tracedata.h:782
TracePart::shortName
QString shortName() const
Definition: tracedata.cpp:3016
Loader
To implement a new loader, inherit from the Loader class and and reimplement canLoad() and load()...
Definition: loader.h:51
TraceLineCall
A call from a line of one function to another function.
Definition: tracedata.h:808
ProfileContext::Instr
Definition: context.h:38
TracePartCall::isRecursion
bool isRecursion()
Definition: tracedata.cpp:577
TracePartObject::addPartFunction
void addPartFunction(TracePartFunction *f)
Definition: tracedata.h:646
TraceFunctionSource::firstLineno
uint firstLineno()
Definition: tracedata.cpp:1532
FixCost::nextCostOfPartFunction
FixCost * nextCostOfPartFunction() const
Definition: fixcost.h:78
TraceData::eventTypes
EventTypeSet * eventTypes()
Definition: tracedata.h:1407
TraceCostItem::~TraceCostItem
virtual ~TraceCostItem()
Definition: tracedata.cpp:1499
TraceData::activePartRange
QString activePartRange()
Definition: tracedata.cpp:3280
TraceInstr::hasCost
bool hasCost(EventType *)
Definition: tracedata.cpp:1301
TracePart::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:3025
ProfileCostArray::costString
virtual QString costString(EventTypeSet *)
Returns text of all cost metrics.
Definition: costitem.cpp:545
TraceInstrJump::partInstrJump
TracePartInstrJump * partInstrJump(TracePart *)
Definition: tracedata.cpp:949
TracePartFunction::calledContexts
int calledContexts()
Definition: tracedata.cpp:752
FixJump::line
unsigned int line() const
Definition: fixcost.h:154
TraceInclusiveCost::TraceInclusiveCost
TraceInclusiveCost(ProfileContext *)
Definition: tracedata.cpp:143
TracePart::operator<
bool operator<(const TracePart &) const
Definition: tracedata.cpp:3048
TracePart::TracePart
TracePart(TraceData *)
Definition: tracedata.cpp:2977
TraceObject::prettyEmptyName
static QString prettyEmptyName()
Definition: tracedata.cpp:2969
TraceInclusiveListCost::~TraceInclusiveListCost
virtual ~TraceInclusiveListCost()
Definition: tracedata.cpp:413
TracePart::part
virtual TracePart * part()
Definition: tracedata.h:661
Addr
Addresses are 64bit values like costs to be able to always load profile data produced on 64bit archit...
Definition: addr.h:31
TracePartLineCall::~TracePartLineCall
virtual ~TracePartLineCall()
Definition: tracedata.cpp:544
TraceFunction::callers
TraceCallList callers(bool skipCycle=false) const
Definition: tracedata.cpp:2278
FixJump::source
TraceFunctionSource * source() const
Definition: fixcost.h:156
EventType
A cost type, e.g.
Definition: eventtype.h:43
ProfileContext::Class
Definition: context.h:47
TraceCostItem::setName
virtual void setName(const QString &name)
Definition: tracedata.h:987
TraceData::activateParts
bool activateParts(const TracePartList &)
returns true if something changed.
Definition: tracedata.cpp:3213
TracePartFile::TracePartFile
TracePartFile(TraceFile *)
Definition: tracedata.cpp:899
TracePartFunction::callingContexts
int callingContexts()
Definition: tracedata.cpp:767
TraceAssoziation::TraceAssoziation
TraceAssoziation()
Creates an invalid assoziation.
Definition: tracedata.cpp:1737
TraceFunction::invalidateDynamicCost
void invalidateDynamicCost()
Definition: tracedata.cpp:2307
TracePart::setThreadID
void setThreadID(int t)
Definition: tracedata.cpp:3002
TraceInstrJump::isCondJump
bool isCondJump() const
Definition: tracedata.h:738
Logger::loadFinished
virtual void loadFinished(const QString &msg)
Definition: logger.cpp:62
TraceFunction::assoziation
TraceAssoziation * assoziation(int rtti)
Definition: tracedata.cpp:1862
TraceInclusiveCost::costString
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
Definition: tracedata.cpp:150
TraceFunctionCycle::TraceFunctionCycle
TraceFunctionCycle(TraceFunction *, int n)
Definition: tracedata.cpp:2641
TraceInclusiveListCost::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:452
TraceFunction::invalidateAssoziation
void invalidateAssoziation(int rtti)
Definition: tracedata.cpp:1854
TraceObject
A object containing a text segment (shared lib/executable) with defined functions.
Definition: tracedata.h:1331
TraceInstrCall::instr
TraceInstr * instr() const
Definition: tracedata.h:790
ProfileCostArray::update
virtual void update()
Updates cost attributes.
Definition: costitem.cpp:572
TraceLine::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1485
TraceCall::instrCall
TraceInstrCall * instrCall(TraceInstr *)
Definition: tracedata.cpp:1147
TraceCall::update
void update()
Updates cost attributes.
Definition: tracedata.cpp:1212
TracePartClass::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:889
TraceObject::setDirectory
void setDirectory(const QString &dir)
Definition: tracedata.cpp:2927
TraceFunction::cls
TraceClass * cls() const
Definition: tracedata.h:1162
TracePartInstrCall
Cost of a call at a instruction code address from a trace file.
Definition: tracedata.h:419
TraceFunction::_callers
TraceCallList _callers
Definition: tracedata.h:1207
TraceCall::callerName
QString callerName(bool skipCycle=false) const
Definition: tracedata.cpp:1248
TraceInstrCall::~TraceInstrCall
virtual ~TraceInstrCall()
Definition: tracedata.cpp:1047
utils.h
TraceData::setMaxThreadID
void setMaxThreadID(int tid)
Definition: tracedata.h:1450
Addr::toString
QString toString() const
Definition: addr.cpp:50
TracePartInstrCall::TracePartInstrCall
TracePartInstrCall(TraceInstrCall *)
Definition: tracedata.cpp:497
TraceFile::~TraceFile
virtual ~TraceFile()
Definition: tracedata.cpp:2764
TraceInclusiveListCost::findDepFromPart
TraceInclusiveCost * findDepFromPart(TracePart *)
Definition: tracedata.cpp:438
TracePartFunction::firstFixJump
FixJump * firstFixJump() const
Definition: tracedata.h:574
TraceInclusiveCost::clear
virtual void clear()
Set all cost counters to zero.
Definition: tracedata.cpp:157
FixCost
A class holding an unchangable cost item of an input file.
Definition: fixcost.h:53
TraceListCost::onlyActiveParts
virtual bool onlyActiveParts()
Definition: tracedata.h:289
TraceObject::addFunction
void addFunction(TraceFunction *)
Definition: tracedata.cpp:2905
tracedata.h
FixPool
FixPool.
Definition: pool.h:34
ProfileCostArray
An array of basic cost metrics for a trace item.
Definition: costitem.h:144
TraceFunction::cycleDFS
void cycleDFS(int d, int &pNo, TraceFunction **pTop)
Definition: tracedata.cpp:2420
TraceJumpCost::~TraceJumpCost
virtual ~TraceJumpCost()
Definition: tracedata.cpp:52
TraceInstrCall::partInstrCall
TracePartInstrCall * partInstrCall(TracePart *, TracePartCall *)
Definition: tracedata.cpp:1054
TraceCallCost::~TraceCallCost
virtual ~TraceCallCost()
Definition: tracedata.cpp:103
TraceInstrJump::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:990
ProfileContext
Base class for source contexts which event costs contained in a ProfileData instance, ie.
Definition: context.h:32
TraceJumpCost::_followedCount
SubCost _followedCount
Definition: tracedata.h:220
TraceFunction::partFunction
TracePartFunction * partFunction(TracePart *, TracePartFile *, TracePartObject *)
Definition: tracedata.cpp:2207
TraceInstr
A code instruction address of the program.
Definition: tracedata.h:887
TraceData::updateObjectCycles
void updateObjectCycles()
Definition: tracedata.cpp:3731
TraceClass::addFunction
void addFunction(TraceFunction *)
Definition: tracedata.cpp:2733
TracePartLine::TracePartLine
TracePartLine(TraceLine *)
Definition: tracedata.cpp:551
TraceInstrJump::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:968
TraceInstr::TraceInstr
TraceInstr()
Definition: tracedata.cpp:1286
TraceFunction::prettyNameWithLocation
QString prettyNameWithLocation(int maxFiles=1) const
Definition: tracedata.cpp:2063
loader.h
CostItem::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: costitem.cpp:53
TraceClass::prettyName
virtual QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:2710
TraceListCost::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:226
TraceData::updateFunctionCycles
void updateFunctionCycles()
Definition: tracedata.cpp:3675
TracePartFunction::costString
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
Definition: tracedata.cpp:648
TracePart::setProcessID
void setProcessID(int p)
Definition: tracedata.cpp:3008
TraceFunction::prettyEmptyName
static QString prettyEmptyName()
Definition: tracedata.cpp:1986
TraceFunction::setClass
void setClass(TraceClass *cls)
Definition: tracedata.h:1188
TracePartClass
Cost of a class, from a single trace file.
Definition: tracedata.h:607
TraceLineCall::call
TraceCall * call() const
Definition: tracedata.h:817
TracePartFunction::partFile
TracePartFile * partFile()
Definition: tracedata.h:561
TraceData::load
int load(QStringList files)
Loads profile data files.
Definition: tracedata.cpp:3130
TraceFunction::setObject
void setObject(TraceObject *object)
Definition: tracedata.h:1187
TraceFile::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:2858
TraceInclusiveListCost::TraceInclusiveListCost
TraceInclusiveListCost(ProfileContext *)
Definition: tracedata.cpp:407
TracePartFile::~TracePartFile
virtual ~TracePartFile()
Definition: tracedata.cpp:905
TraceCall::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1195
TraceAssoziation
For temporary assoziation of objects with TraceFunctions.
Definition: tracedata.h:1068
CostItem::fullName
QString fullName() const
Returns type name + dynamic name.
Definition: costitem.cpp:76
TraceFunction::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:2325
TraceInstr::addInstrCall
void addInstrCall(TraceInstrCall *)
Definition: tracedata.cpp:1344
GlobalConfig::showCycles
static bool showCycles()
Definition: globalconfig.cpp:338
TraceFunctionCycle::init
void init()
Definition: tracedata.cpp:2658
TraceFunction::_callings
TraceCallList _callings
Definition: tracedata.h:1208
TraceAssoziation::clear
static void clear(TraceData *data, int rtti)
Delete all assoziations in TraceFunctions of data with rtti runtime info.
Definition: tracedata.cpp:1774
TraceObject::~TraceObject
virtual ~TraceObject()
Definition: tracedata.cpp:2888
TraceJumpCost::costString
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
Definition: tracedata.cpp:69
TraceCall::partCall
TracePartCall * partCall(TracePart *, TracePartFunction *, TracePartFunction *)
Definition: tracedata.cpp:1132
TraceCallCost::prettyCallCount
QString prettyCallCount()
Definition: tracedata.cpp:114
TraceFunctionSource
A container helper class for TraceFunction for source lines where a function is implemented in...
Definition: tracedata.h:1029
TraceLineCall::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1108
TracePart::threadID
int threadID() const
Definition: tracedata.h:673
TraceLine::TraceLine
TraceLine()
Definition: tracedata.cpp:1380
TraceInclusiveCost::addInclusive
void addInclusive(ProfileCostArray *)
Definition: tracedata.cpp:170
TraceInclusiveListCost::addDep
void addDep(TraceInclusiveCost *)
Definition: tracedata.cpp:417
TraceInstrJump::~TraceInstrJump
virtual ~TraceInstrJump()
Definition: tracedata.cpp:938
TracePartFunction::addPartCaller
void addPartCaller(TracePartCall *)
Definition: tracedata.cpp:704
TracePartLine
Cost of a line from a trace file.
Definition: tracedata.h:484
TraceCostItem::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.h:986
TraceFunction::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1889
TracePartFile::file
TraceFile * file()
Definition: tracedata.h:630
TraceCallCost::_callCount
SubCost _callCount
Definition: tracedata.h:244
FixCallCost::addTo
void addTo(TraceCallCost *)
Definition: fixcost.cpp:114
CostItem::setPosition
void setPosition(CostItem *p)
If this item is from a single profile data file, position points to a TracePart, otherwise to a Trace...
Definition: costitem.h:103
CostItem::data
virtual TraceData * data()
Definition: costitem.cpp:111
TraceAssoziation::_valid
bool _valid
Definition: tracedata.h:1110
TraceData::functionEndIterator
TraceFunctionMap::ConstIterator functionEndIterator() const
Definition: tracedata.cpp:3492
TraceListCost
Cost Item depends on a list of cost items.
Definition: tracedata.h:274
TraceLine::lineno
uint lineno() const
Definition: tracedata.h:955
TraceInstrCall::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1070
TraceInstr::partInstr
TracePartInstr * partInstr(TracePart *part, TracePartFunction *partFunction)
Definition: tracedata.cpp:1317
TraceJumpListCost::_deps
TraceJumpCostList _deps
Definition: tracedata.h:320
FixCost::addTo
void addTo(ProfileCostArray *)
Definition: fixcost.cpp:58
TracePartFunction::TracePartFunction
TracePartFunction(TraceFunction *, TracePartObject *, TracePartFile *)
Definition: tracedata.cpp:616
CostItem::invalidate
virtual void invalidate()
Invalidate the cost attributes.
Definition: costitem.cpp:87
TraceInclusiveCost::_inclusive
ProfileCostArray _inclusive
Definition: tracedata.h:266
TraceListCost::_deps
TraceCostList _deps
Definition: tracedata.h:291
fixcost.h
TraceLine
A source line of the program.
Definition: tracedata.h:935
TraceLineJump::isCondJump
bool isCondJump()
Definition: tracedata.h:765
TraceFunction::addAssoziation
void addAssoziation(TraceAssoziation *a)
Definition: tracedata.cpp:1825
TraceCall::inCycle
int inCycle()
Definition: tracedata.cpp:1202
TracePartFunction
Cost of a function, from a single trace file.
Definition: tracedata.h:543
TraceAssoziation::_function
TraceFunction * _function
Definition: tracedata.h:1109
TraceFunction::file
TraceFile * file() const
Definition: tracedata.h:1163
TraceLineCall::TraceLineCall
TraceLineCall(TraceCall *call, TraceLine *line)
Definition: tracedata.cpp:1079
TracePartClass::addPartFunction
void addPartFunction(TracePartFunction *f)
Definition: tracedata.h:616
TracePart::activate
bool activate(bool)
Definition: tracedata.cpp:3036
TraceLine::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1475
TraceLine::partLine
TracePartLine * partLine(TracePart *part, TracePartFunction *partFunction)
Definition: tracedata.cpp:1410
TraceFunction::_cycle
TraceFunctionCycle * _cycle
Definition: tracedata.h:1209
TraceClass::prettyEmptyName
static QString prettyEmptyName()
Definition: tracedata.cpp:2717
TraceListCost::TraceListCost
TraceListCost(ProfileContext *)
Definition: tracedata.cpp:181
TraceData::functionIterator
TraceFunctionMap::Iterator functionIterator(TraceFunction *)
Definition: tracedata.cpp:3474
TraceData::updateClassCycles
void updateClassCycles()
Definition: tracedata.cpp:3736
TraceFunctionSource::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1527
TraceCallListCost::~TraceCallListCost
virtual ~TraceCallListCost()
Definition: tracedata.cpp:335
TraceFunctionSource::file
TraceFile * file() const
Definition: tracedata.h:1040
TraceData::setMaxPartNumber
void setMaxPartNumber(int n)
Definition: tracedata.h:1452
TraceInstr::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1371
TracePartInstr::instr
TraceInstr * instr() const
Definition: tracedata.h:444
TraceJumpListCost
Jump Cost Item depends on a list of Jump cost items.
Definition: tracedata.h:303
TraceCallListCost::findDepFromPart
TraceCallCost * findDepFromPart(TracePart *)
Definition: tracedata.cpp:359
TraceLine::functionSource
TraceFunctionSource * functionSource() const
Definition: tracedata.h:954
ProfileContext::FunctionSource
Definition: context.h:46
TraceClass::partClass
TracePartClass * partClass(TracePart *)
Definition: tracedata.cpp:2722
TraceAssoziation::~TraceAssoziation
virtual ~TraceAssoziation()
Definition: tracedata.cpp:1743
TraceFunctionSourceList
QList< TraceFunctionSource * > TraceFunctionSourceList
Definition: tracedata.h:187
TracePartFunction::setPartClass
void setPartClass(TracePartClass *c)
Definition: tracedata.h:565
TracePartCall
Cost of a call at a function to another function, from a single trace file.
Definition: tracedata.h:516
TraceCallListCost::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:374
TraceFile::prettyLongName
QString prettyLongName() const
Definition: tracedata.cpp:2873
TraceFunction::TraceFunction
TraceFunction()
Definition: tracedata.cpp:1794
TraceLineCall::line
TraceLine * line() const
Definition: tracedata.h:816
TraceCall::lineCall
TraceLineCall * lineCall(TraceLine *)
Definition: tracedata.cpp:1165
TracePartLineCall::TracePartLineCall
TracePartLineCall(TraceLineCall *)
Definition: tracedata.cpp:538
TraceClass::~TraceClass
virtual ~TraceClass()
Definition: tracedata.cpp:2704
TraceCall::invalidateDynamicCost
void invalidateDynamicCost()
Definition: tracedata.cpp:1183
TraceJumpListCost::findDepFromPart
TraceJumpCost * findDepFromPart(TracePart *)
Definition: tracedata.cpp:285
TraceFunction::instrMap
TraceInstrMap * instrMap()
Definition: tracedata.cpp:2521
TracePartFunction::calledCount
SubCost calledCount()
Definition: tracedata.cpp:745
TracePart::isActive
bool isActive() const
Definition: tracedata.h:690
EventTypeSet::realType
EventType * realType(int)
Definition: eventtype.cpp:462
TracePartFunction::setPartObject
void setPartObject(TracePartObject *o)
Definition: tracedata.h:564
TracePartFunction::~TracePartFunction
virtual ~TracePartFunction()
Definition: tracedata.cpp:635
TracePartInstr
Cost of a code instruction address from a trace file.
Definition: tracedata.h:435
TraceCallCost::clear
virtual void clear()
Set all cost counters to zero.
Definition: tracedata.cpp:119
TraceInclusiveListCost
Inclusive Cost Item depends on a list of inclusive cost items.
Definition: tracedata.h:362
TraceLineJump::lineFrom
TraceLine * lineFrom() const
Definition: tracedata.h:763
TraceJumpCost::_executedCount
SubCost _executedCount
Definition: tracedata.h:220
TracePart::~TracePart
virtual ~TracePart()
Definition: tracedata.cpp:2991
TraceAssoziation::invalidate
void invalidate()
Definition: tracedata.h:1093
TraceFunctionCycle::base
TraceFunction * base() const
Definition: tracedata.h:1252
Loader::matchingLoader
static Loader * matchingLoader(QIODevice *file)
Definition: loader.cpp:52
TracePart
A Trace Part: All data read from a trace file, containing all costs that happened in a specified time...
Definition: tracedata.h:655
TracePartInstr::~TracePartInstr
virtual ~TracePartInstr()
Definition: tracedata.cpp:517
TraceFile::addFunction
void addFunction(TraceFunction *)
Definition: tracedata.cpp:2781
ProfileCostArray::clear
virtual void clear()
Set all cost counters to zero.
Definition: costitem.cpp:154
TraceInstrJump
A jump from an instruction to another inside of a function.
Definition: tracedata.h:725
TraceFunction::calledContexts
int calledContexts()
Definition: tracedata.cpp:2246
CostItem::_dirty
bool _dirty
Definition: costitem.h:124
TraceData::file
TraceFile * file(const QString &name)
Definition: tracedata.cpp:3353
TracePartCall::~TracePartCall
virtual ~TracePartCall()
Definition: tracedata.cpp:574
TracePartFunction::prettyCalledCount
QString prettyCalledCount()
Definition: tracedata.cpp:638
TraceFile::addSourceFile
void addSourceFile(TraceFunctionSource *)
Definition: tracedata.cpp:2804
TracePartFunction::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:775
TraceInstr::instrJump
TraceInstrJump * instrJump(TraceInstr *to, bool isCondJump)
Definition: tracedata.cpp:1331
TraceData::shortTraceName
QString shortTraceName() const
Definition: tracedata.cpp:3093
TraceListCost::~TraceListCost
virtual ~TraceListCost()
Definition: tracedata.cpp:187
FixJump::addTo
void addTo(TraceJumpCost *)
Definition: fixcost.cpp:182
TraceLine::setSourceFile
void setSourceFile(TraceFunctionSource *sf)
Definition: tracedata.h:960
TracePartLine::line
TraceLine * line() const
Definition: tracedata.h:493
TracePartInstrJump::next
TracePartInstrJump * next() const
Definition: tracedata.h:407
TraceFunction::isCycleMember
bool isCycleMember()
Definition: tracedata.cpp:2407
logger.h
TraceFunction::info
QString info() const
Definition: tracedata.cpp:2071
TraceFunctionSource::~TraceFunctionSource
virtual ~TraceFunctionSource()
Definition: tracedata.cpp:1521
TraceInstr::name
virtual QString name() const
Returns dynamic name info (without type)
Definition: tracedata.cpp:1366
ProfileContext::Type
Type
Definition: context.h:36
TracePartCall::firstFixCallCost
FixCallCost * firstFixCallCost() const
Definition: tracedata.h:532
TraceFile::partFile
TracePartFile * partFile(TracePart *)
Definition: tracedata.cpp:2770
FixJump
A class holding a jump (mostly) inside of a function.
Definition: fixcost.h:135
TracePartInstrJump
Cost of jump at a instruction code address from a trace file.
Definition: tracedata.h:398
SubCost
Cost event counter, simple wrapper around a 64bit entity.
Definition: subcost.h:32
TracePartObject::object
TraceObject * object() const
Definition: tracedata.h:645
TraceFunction::sourceFile
TraceFunctionSource * sourceFile(TraceFile *file=0, bool createNew=false)
Definition: tracedata.cpp:2169
GlobalConfig::hideTemplates
static bool hideTemplates()
Definition: globalconfig.cpp:343
FixJump::part
TracePart * part() const
Definition: fixcost.h:153
TracePartFile
Cost of a source file, from a single trace file.
Definition: tracedata.h:624
TraceListCost::addDep
void addDep(ProfileCostArray *)
Definition: tracedata.cpp:190
TraceFunction::calledCount
SubCost calledCount()
Definition: tracedata.cpp:2239
TracePartLineJump::TracePartLineJump
TracePartLineJump(TraceLineJump *)
Definition: tracedata.cpp:525
TraceData::functionCycle
TraceFunctionCycle * functionCycle(TraceFunction *)
Definition: tracedata.cpp:3660
FixJump::targetLine
unsigned int targetLine() const
Definition: fixcost.h:158
TraceJumpListCost::TraceJumpListCost
TraceJumpListCost(ProfileContext *)
Definition: tracedata.cpp:255
TracePartFunction::firstFixCost
FixCost * firstFixCost() const
Definition: tracedata.h:571
TraceData::resetSourceDirs
void resetSourceDirs()
Definition: tracedata.cpp:3498
TraceFunction::firstAddress
Addr firstAddress() const
Definition: tracedata.cpp:2082
TraceCallCost
Cost item with additional call count metric.
Definition: tracedata.h:228
TraceCall::called
TraceFunction * called(bool skipCycle=false) const
Definition: tracedata.cpp:1235
TraceFunction::addPrettyLocation
void addPrettyLocation(QString &, int maxFiles=1) const
Definition: tracedata.cpp:2055
TracePartLineJump
Cost of jump at a source line from a trace file.
Definition: tracedata.h:451
TraceInstrCall::TraceInstrCall
TraceInstrCall(TraceCall *call, TraceInstr *instr)
Definition: tracedata.cpp:1040
TracePartCall::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:582
ProfileCostArray::addCost
void addCost(EventTypeMapping *, const char *)
Definition: costitem.cpp:252
TracePartList
QList< TracePart * > TracePartList
Definition: tracedata.h:176
SubCost::pretty
QString pretty(char sep= ' ') const
Convert SubCost value into a QString, spaced every 3 digits.
Definition: subcost.cpp:46
EventTypeSet
A class for managing a set of event types.
Definition: eventtype.h:117
TraceLineJump::TraceLineJump
TraceLineJump(TraceLine *lineFrom, TraceLine *lineTo, bool isCondJump)
Definition: tracedata.cpp:1001
Loader::load
virtual int load(TraceData *, QIODevice *file, const QString &filename)
Definition: loader.cpp:47
FixJump::targetSource
TraceFunctionSource * targetSource() const
Definition: fixcost.h:160
TracePartObject::TracePartObject
TracePartObject(TraceObject *)
Definition: tracedata.cpp:912
TraceFunctionSource::lastLineno
uint lastLineno()
Definition: tracedata.cpp:1542
TraceLineJump::~TraceLineJump
virtual ~TraceLineJump()
Definition: tracedata.cpp:1010
TraceCallList
QList< TraceCall * > TraceCallList
Definition: tracedata.h:184
TraceFunction::callingCount
SubCost callingCount()
Definition: tracedata.cpp:2253
TraceFunctionSource::TraceFunctionSource
TraceFunctionSource(TraceFunction *, TraceFile *)
Definition: tracedata.cpp:1506
TraceData::fixPool
FixPool * fixPool()
Definition: tracedata.cpp:3102
FixJump::targetAddr
Addr targetAddr() const
Definition: fixcost.h:159
TraceFunction::removeAssoziation
void removeAssoziation(TraceAssoziation *a)
Definition: tracedata.cpp:1831
TracePartClass::cls
TraceClass * cls()
Definition: tracedata.h:615
TraceAssoziation::setFunction
bool setFunction(TraceFunction *)
reset function to associate this object to.
Definition: tracedata.cpp:1756
TraceInclusiveListCost::_deps
TraceInclusiveCostList _deps
Definition: tracedata.h:379
TraceJumpCost::followedCount
SubCost followedCount()
Definition: tracedata.cpp:62
TraceLineCall::partLineCall
TracePartLineCall * partLineCall(TracePart *, TracePartCall *)
Definition: tracedata.cpp:1094
TraceFile::directory
QString directory()
Definition: tracedata.cpp:2834
TraceClass
A C++ Class / Namespace.
Definition: tracedata.h:1271
TraceInstrJump::instrFrom
TraceInstr * instrFrom() const
Definition: tracedata.h:736
TraceData::functionMap
TraceFunctionMap & functionMap()
Definition: tracedata.h:1441
TraceFunction::prettyLocation
QString prettyLocation(int maxFiles=0) const
Definition: tracedata.cpp:2047
TraceData::updateFileCycles
void updateFileCycles()
Definition: tracedata.cpp:3741
FixJump::targetFunction
TraceFunction * targetFunction() const
Definition: fixcost.h:157
TracePartInstrJump::TracePartInstrJump
TracePartInstrJump(TraceInstrJump *, TracePartInstrJump *)
Definition: tracedata.cpp:482
ProfileContext::Object
Definition: context.h:49
TraceData
This class holds profiling data of multiple tracefiles generated with cachegrind on one command...
Definition: tracedata.h:1363
TraceFunction::isCycle
bool isCycle()
Definition: tracedata.cpp:2402
TraceLine::setLineno
void setLineno(uint lineno)
Definition: tracedata.h:961
TraceAssoziation::rtti
virtual int rtti()
Definition: tracedata.h:1078
TraceObject::partObject
TracePartObject * partObject(TracePart *)
Definition: tracedata.cpp:2894
TraceData::~TraceData
virtual ~TraceData()
Definition: tracedata.cpp:3085
TraceJumpCost::TraceJumpCost
TraceJumpCost(ProfileContext *)
Definition: tracedata.cpp:46
TracePartFunction::partCallings
const TracePartCallList & partCallings()
Definition: tracedata.h:563
TraceJumpCost
Cost of a (conditional) jump.
Definition: tracedata.h:201
TraceFile::prettyEmptyName
static QString prettyEmptyName()
Definition: tracedata.cpp:2868
TraceFunction::location
QString location(int maxFiles=0) const
Returns empty string if location is fully unknown.
Definition: tracedata.cpp:1994
TraceLineJump::partLineJump
TracePartLineJump * partLineJump(TracePart *)
Definition: tracedata.cpp:1017
TracePart::setPartNumber
void setPartNumber(int n)
Definition: tracedata.cpp:2996
TracePartInstr::TracePartInstr
TracePartInstr(TraceInstr *)
Definition: tracedata.cpp:511
ProfileContext::context
static ProfileContext * context(ProfileContext::Type)
Definition: context.cpp:36
TraceCall
A call from one to another function.
Definition: tracedata.h:835
TracePartFile::addPartFunction
void addPartFunction(TracePartFunction *f)
Definition: tracedata.h:631
TraceInstrCall::call
TraceCall * call() const
Definition: tracedata.h:791
TraceFunction::cycleReset
void cycleReset()
Definition: tracedata.cpp:2412
FixJump::addr
Addr addr() const
Definition: fixcost.h:155
TraceFunction::prettyCalledCount
QString prettyCalledCount()
Definition: tracedata.cpp:2267
TraceFunctionCycle::setup
void setup()
Definition: tracedata.cpp:2673
TraceFunction::instr
TraceInstr * instr(Addr addr, bool createNew=true)
Definition: tracedata.cpp:2100
TracePartInstrCall::instrCall
TraceInstrCall * instrCall() const
Definition: tracedata.h:427
TraceAssoziation::isAssoziated
bool isAssoziated()
Could we set the function assoziation to ourself? This only can return false if this is a unique asso...
Definition: tracedata.cpp:1749
TraceFile::shortName
QString shortName() const
Definition: tracedata.cpp:2849
TraceData::addPart
void addPart(TracePart *)
Definition: tracedata.cpp:3260
TraceData::dynPool
DynPool * dynPool()
Definition: tracedata.cpp:3110
TraceInstr::setLine
void setLine(TraceLine *l)
Definition: tracedata.h:915
TraceFunction::calling
TraceCall * calling(TraceFunction *called)
Definition: tracedata.cpp:2150
TraceObject::directory
QString directory()
Definition: tracedata.cpp:2935
TraceCall::calledName
QString calledName(bool skipCycle=false) const
Definition: tracedata.cpp:1264
TraceLine::~TraceLine
virtual ~TraceLine()
Definition: tracedata.cpp:1387
TraceLineJump
A jump from one line to another inside of a function.
Definition: tracedata.h:754
TracePartFunction::prettyCallingCount
QString prettyCallingCount()
Definition: tracedata.cpp:643
TracePartFunction::addPartCalling
void addPartCalling(TracePartCall *)
Definition: tracedata.cpp:725
TraceInclusiveCost::inclusive
ProfileCostArray * inclusive()
Definition: tracedata.cpp:163
TraceLineCall::~TraceLineCall
virtual ~TraceLineCall()
Definition: tracedata.cpp:1087
TraceCall::~TraceCall
virtual ~TraceCall()
Definition: tracedata.cpp:1125
TraceCall::TraceCall
TraceCall(TraceFunction *caller, TraceFunction *called)
Definition: tracedata.cpp:1117
TraceJumpListCost::addDep
void addDep(TraceJumpCost *)
Definition: tracedata.cpp:264
TraceClass::TraceClass
TraceClass()
Definition: tracedata.cpp:2700
TraceJumpListCost::~TraceJumpListCost
virtual ~TraceJumpListCost()
Definition: tracedata.cpp:261
FixJump::nextJumpOfPartFunction
FixJump * nextJumpOfPartFunction() const
Definition: fixcost.h:166
TraceInstr::addr
Addr addr() const
Definition: tracedata.h:905
TraceObject::shortName
QString shortName() const
Definition: tracedata.cpp:2950
ProfileContext::Function
Definition: context.h:46
TracePartObject
Cost of a object, from a single trace file.
Definition: tracedata.h:639
ProfileContext::InvalidType
Definition: context.h:37
GlobalConfig::cycleCut
static double cycleCut()
Definition: globalconfig.cpp:380
TraceFunctionSource::lineMap
TraceLineMap * lineMap()
Definition: tracedata.cpp:1618
FixCallCost
A FixCallCost will be inserted into a.
Definition: fixcost.h:96
TraceData::update
virtual void update()
Updates cost attributes.
Definition: tracedata.cpp:3506
TraceObject::TraceObject
TraceObject()
Definition: tracedata.cpp:2884
TraceCallListCost::addDep
void addDep(TraceCallCost *)
Definition: tracedata.cpp:338
TraceData::invalidateDynamicCost
void invalidateDynamicCost()
Definition: tracedata.cpp:3306
TraceData::functionBeginIterator
TraceFunctionMap::ConstIterator functionBeginIterator() const
Definition: tracedata.cpp:3487
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:03:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kcachegrind

Skip menu "kcachegrind"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • okteta
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal