38 #define TRACE_ASSERTIONS 0
73 return QString(
"%1/%2")
109 return QString(
"%1, Calls %2")
152 return QString(
"%1, Inclusive %2")
193 if (
_deps.contains(dep)) {
194 qDebug(
"addDep: %s already in list!",
205 qDebug(
"%s added\n %s (now %d)",
213 if (_lastDep && _lastDep->
part() ==
part)
231 qDebug(
"update %s (count %d)",
267 if (
_deps.contains(dep)) {
268 qDebug(
"addDep: %s already in list!",
279 qDebug(
"%s added\n %s (now %d)",
287 if (_lastDep && _lastDep->
part() ==
part)
305 qDebug(
"update %s (count %d)",
341 if (
_deps.contains(dep)) {
342 qDebug(
"addDep: %s already in list!",
353 qDebug(
"%s added\n %s (now %d)",
361 if (_lastDep && _lastDep->
part() ==
part)
379 qDebug(
"update %s (count %d)",
385 if (
_deps.count()>0) {
420 if (
_deps.contains(dep)) {
421 qDebug(
"addDep: %s already in list!",
432 qDebug(
"%s added\n %s (now %d)",
440 if (_lastDep && _lastDep->
part() ==
part)
457 qDebug(
"update %s (count %d)",
571 _firstFixCallCost = 0;
591 qDebug(
"update %s", qPrintable(
fullName() ));
596 if (_firstFixCallCost) {
609 #endif // USE_FIXCOST
629 _callingContexts = 0;
640 return _calledCount.
pretty();
645 return _callingCount.
pretty();
653 res += QString(
", called from %1: %2")
655 res += QString(
", calling from %1: %2")
665 if (_partInstr.contains(ref)) {
666 qDebug(
"TracePartFunction::addPartInstr: %s already in list!",
667 qPrintable(ref->
name()));
672 _partInstr.append(ref);
676 qDebug(
"%s added\n %s (now %d)",
686 if (_partLines.contains(ref)) {
687 qDebug(
"TracePartFunction::addPartLine: %s already in list!",
688 qPrintable(ref->
name()));
693 _partLines.append(ref);
697 qDebug(
"%s added\n %s (now %d)",
707 if (_partCallers.contains(ref)) {
708 qDebug(
"TracePartFunction::addPartCaller: %s already in list!",
709 qPrintable(ref->
name()));
714 _partCallers.append(ref);
718 qDebug(
"%s added Caller\n %s (now %d)",
720 _partCallers.count());
728 if (_partCallings.contains(ref)) {
729 qDebug(
"TracePartFunction::addPartCalling: %s already in list!",
730 qPrintable(ref->
name()));
735 _partCallings.append(ref);
739 qDebug(
"%s added Calling\n %s (now %d)",
741 _partCallings.count());
756 return _calledContexts;
763 return _callingCount;
771 return _callingContexts;
780 qDebug(
"TracePartFunction::update %s (Callers %d, Callings %d, lines %d)",
781 qPrintable(
name()), _partCallers.count(), _partCallings.count(),
788 _callingContexts = 0;
795 if (e && (caller->
subCost(e) >0))
804 if (e && (calling->
subCost(e)>0))
815 if (_partLines.count()>0) {
847 if (_calledCount>0) {
891 return QString(
"%1 from %2")
956 (item->
part() ==
part))
return item;
958 for(item = _first; item; item = item->
next())
974 for (item = _first; item; item = item->
next()) {
982 qDebug(
"updated %s", qPrintable(
fullName() ));
992 return QString(
"jump at 0x%1 to 0x%2")
1031 return QString(
"jump at %1 to %2")
1072 return QString(
"%1 at %2").arg(_call->
name()).arg(_instr->
name());
1110 return QString(
"%1 at %2").arg(_call->
name()).arg(_line->
name());
1129 qDeleteAll(_lineCalls);
1150 if (icall->
instr() == i)
1154 _instrCalls.append(icall);
1158 qDebug(
"Created %s [TraceCall::instrCall]", qPrintable(icall->
fullName()));
1168 if (lcall->
line() == l)
1172 _lineCalls.append(lcall);
1176 qDebug(
"Created %s [TraceCall::lineCall]", qPrintable(lcall->
fullName()));
1197 return QString(
"%1 => %2")
1198 .arg(_caller->
name())
1199 .arg(_called->
name());
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;
1217 if (_caller && _caller->
cycle() && _caller==_caller->
cycle()) {
1237 if (!skipCycle && _called) {
1240 if (_called->
cycle() && _caller &&
1242 return _called->
cycle();
1250 if (!_caller)
return QObject::tr(
"(no caller)");
1255 if (c && _caller && (_caller->
cycle() != c)) {
1257 return QObject::tr(
"%1 via %2").arg(_caller->
prettyName()).arg(via);
1266 if (!_called)
return QObject::tr(
"(no callee)");
1271 if (c && _caller && (_caller->
cycle() != c)) {
1276 return QObject::tr(
"%1 via %2").arg(c->
name()).arg(via);
1298 qDeleteAll(_instrJumps);
1338 _instrJumps.append(jump);
1346 #if TRACE_ASSERTIONS
1347 if (_instrCalls.contains(instrCall))
return;
1349 if (instrCall->
instr() !=
this) {
1350 qDebug(
"Can not add instruction call to another instruction!");
1355 _instrCalls.append(instrCall);
1359 qDebug(
"%s added\n %s (now %d)",
1361 qPrintable(instrCall->
fullName()), _instrCalls.count());
1368 return QString(
"0x%1").arg(_addr.
toString());
1373 return QString(
"0x%1").arg(_addr.
toString());
1391 qDeleteAll(_lineJumps);
1429 if (jump->
lineTo() == to)
1433 _lineJumps.append(jump);
1440 #if TRACE_ASSERTIONS
1441 if (_lineCalls.contains(lineCall))
return;
1443 if (lineCall->
line() !=
this) {
1444 qDebug(
"Can not add line call to another line!");
1451 if (caller !=
function) {
1454 if ((caller->
cls() !=
function->cls()) ||
1455 (caller->
name() !=
function->name()) ||
1456 (caller->
object() !=
function->object())) {
1458 qDebug(
"ERROR: Adding line call, line %d\n of %s to\n %s ?!",
1460 qPrintable(caller->
info()), qPrintable(function->info()));
1464 _lineCalls.append(lineCall);
1468 qDebug(
"%s added\n %s (now %d)",
1470 qPrintable(lineCall->
fullName()), _lineCalls.count());
1478 if (fileShortName.isEmpty())
1481 return QString(
"%1:%2")
1482 .arg(fileShortName).arg(_lineno);
1487 return QString(
"%1 [%2]")
1511 _function =
function;
1517 _lineMapFilled =
false;
1529 return QString(
"%1 for %2").arg(_file->
name()).arg(_function->
name());
1537 if (!map || map->count() == 0)
return 0;
1538 TraceLineMap::Iterator it = map->begin();
1539 return (*it).lineno();
1547 if (!map || map->count() == 0)
return 0;
1548 TraceLineMap::Iterator it = map->end();
1550 return (*it).lineno();
1558 if (!createNew)
return 0;
1567 if (!_lineMap)
return 0;
1568 TraceLineMap::Iterator it = _lineMap->find(lineno);
1569 if (it == _lineMap->end())
return 0;
1570 return &(it.value());
1581 qDebug(
"Created %s [TraceFunctionSource::line]",
1596 TraceLineMap::Iterator lit;
1597 for ( lit = _lineMap->begin();
1598 lit != _lineMap->end(); ++lit )
1609 TraceLineMap::Iterator lit;
1610 for ( lit = _lineMap->begin();
1611 lit != _lineMap->end(); ++lit )
1612 (*lit).invalidate();
1622 if (_lineMapFilled)
return _lineMap;
1623 _lineMapFilled =
true;
1639 if (0) qDebug(
"PartFunction %s:%d",
1644 for(; fc; fc = fc->nextCostOfPartFunction()) {
1645 if (fc->line() == 0)
continue;
1646 if (fc->functionSource() !=
this)
continue;
1648 if (!l || l->
lineno() != fc->line()) {
1649 l = &(*_lineMap)[fc->line()];
1656 if (!pl || pl->
part() != fc->
part())
1666 if (fj->
line() == 0)
continue;
1667 if (fj->
source() !=
this)
continue;
1678 l = &(*_lineMap)[fj->
line()];
1695 if (0) qDebug(
"PartCall %s:%d",
1700 for(; fcc; fcc = fcc->nextCostOfPartCall()) {
1701 if (fcc->line() == 0)
continue;
1702 if (fcc->functionSource() !=
this)
continue;
1704 if (!l || l->
lineno() != fcc->line()) {
1705 l = &(*_lineMap)[fcc->line()];
1711 if (!lc || lc->
call() != pc->
call() || lc->
line() != l) {
1715 if (!plc || plc->
part() != fcc->
part())
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()));
1776 TraceFunctionMap::Iterator it;
1779 (*it).removeAssoziation(rtti);
1784 TraceFunctionMap::Iterator it;
1787 (*it).invalidateAssoziation(rtti);
1804 _calledContexts = 0;
1805 _callingContexts = 0;
1808 _instrMapFilled =
false;
1814 qDeleteAll(_assoziations);
1819 qDeleteAll(_sourceFiles);
1828 _assoziations.append(a);
1833 _assoziations.removeAll(a);
1840 qDeleteAll(_assoziations);
1841 _assoziations.clear();
1846 if (a->
rtti() == rtti) {
1847 if (reallyDelete)
delete a;
1848 _assoziations.removeAll(a);
1857 if ((rtti==0) || (a->
rtti() == rtti))
1865 if (a->
rtti() == rtti)
1873 bool TraceFunction::isUniquePrefix(
const QString& prefix)
const
1875 TraceFunctionMap::ConstIterator it, it2;
1876 it = it2 = _myMapIterator;
1877 if (it !=
data()->functionBeginIterator()) {
1879 if ((*it2).name().startsWith(prefix))
return false;
1883 if ((*it).name().startsWith(prefix))
return false;
1891 QString res =
_name;
1893 if (
_name.isEmpty())
1900 for(
int i=0;i<
_name.length();i++) {
1901 switch(
_name[i].toLatin1()) {
1903 if (d<=0) res.append(
_name[i]);
1910 if (d<=0) res.append(
_name[i]);
1922 int p =
_name.indexOf(
'(');
1925 if ( (p+2 <
_name.size()) && (
_name[p+1] ==
')') && (
_name[p+2] ==
'(')) p+=2;
1929 if (isUniquePrefix(
_name.left(p+1)))
1930 res =
_name.left(p);
1937 res = QString(
"%1 <cycle %2>").arg(res).arg(
_cycle->
cycleNo());
1952 QString rich(
"<b>");
1954 for(
int i=0;i<
_name.length();i++) {
1955 switch(
_name[i].toLatin1()) {
1957 rich.append(
"&");
1961 rich.append(
"<");
1963 rich.append(
"</b>");
1969 rich.append(
"> ");
1972 rich.append(
"</b>(<i><b>");
1975 rich.append(
"</b></i>)<b>");
1978 rich.append(
_name[i]);
1982 rich.append(
"</b>");
1988 return QObject::tr(
"(unknown)");
2005 if (from != 0 && to != 0) {
2007 loc += QString(
" (0x%1)").arg(to, 0, 16);
2009 loc += QString(
" (0x%1-0x%2)").arg(from, 0, 16).arg(to, 0, 16);
2017 if (!sourceFile->
file() ||
2018 (sourceFile->
file()->
name().isEmpty()) )
2022 loc += (filesAdded>0) ?
", " :
": ";
2025 if ((maxFiles>0) && (filesAdded>maxFiles)) {
2034 if (from != 0 && to != 0) {
2036 loc += QString(
" (%1)").arg(to);
2038 loc += QString(
" (%1-%2)").arg(from).arg(to);
2050 if (l.isEmpty())
return QObject::tr(
"(unknown)");
2058 if (l.isEmpty())
return;
2060 s += QString(
" (%1)").arg(l);
2068 return QString(
"%1 (%2)").arg(
prettyName()).arg(l);
2075 return QString(
"Function %1").arg(
name());
2077 return QString(
"Function %1 (location %2)")
2078 .arg(
name()).arg(l);
2085 if (!_instrMap || _instrMap->count() == 0)
return 0;
2086 TraceInstrMap::ConstIterator it = _instrMap->constBegin();
2087 return (*it).addr();
2093 if (!_instrMap || _instrMap->count() == 0)
return 0;
2094 TraceInstrMap::ConstIterator it = _instrMap->constEnd();
2096 return (*it).addr();
2103 if (addr ==
Addr(0))
return 0;
2106 if (!_instrMap)
return 0;
2107 TraceInstrMap::Iterator it = _instrMap->find(addr);
2108 if (it == _instrMap->end())
2110 return &(it.value());
2121 qDebug(
"Created %s [TraceFunction::instr]",
2130 #if TRACE_ASSERTIONS
2131 if (caller->
called() !=
this) {
2132 qDebug(
"Can not add call to another line!\n");
2136 if (
_callers.contains(caller))
return;
2143 qDebug(
"%s added Caller\n %s (now %d)",
2153 if (calling->
called() == called)
2163 qDebug(
"Created %s [TraceFunction::calling]", qPrintable(calling->
fullName()));
2172 if (!file) file = _file;
2178 if (!createNew)
return 0;
2181 _sourceFiles.append(sourceFile);
2187 qDebug(
"Created SourceFile %s [TraceFunction::line]",
2188 qPrintable(file->
name()));
2203 return sf->
line(lineno, createNew);
2230 else if (item->
partObject()==0 && partObject) {
2243 return _calledCount;
2250 return _calledContexts;
2257 return _callingCount;
2264 return _callingContexts;
2269 return _calledCount.
pretty();
2274 return _callingCount.
pretty();
2293 if (c->
called() ==
this) {
2316 TraceInstrMap::Iterator iit;
2317 for ( iit = _instrMap->begin();
2318 iit != _instrMap->end(); ++iit )
2319 (*iit).invalidate();
2330 qDebug(
"Update %s (Callers %d, sourceFiles %d, instrs %d)",
2332 _sourceFiles.count(), _instrMap ? _instrMap->count():0);
2337 _calledContexts = 0;
2338 _callingContexts = 0;
2346 if (e && (caller->
subCost(e) >0))
2352 if (e && (callee->
subCost(e) >0))
2357 if (
data()->inFunctionCycleUpdate() || !
_cycle) {
2372 (callee->
inCycle()>0))
continue;
2415 _cycleStackDown = 0;
2422 if (_cycleLow != 0)
return;
2427 _cycleLow = prefixNo;
2430 _cycleStackDown = *pTop;
2438 Q_ASSERT((
data() != 0) && (
data()->eventTypes()->realCount()>0));
2444 if (caller->
subCost(e) > base)
2452 qDebug(
"%s (%d) Visiting %s",
2453 qPrintable(QString().fill(
' ', d)),
2455 qDebug(
"%s Cum. %s, Max Caller %s, cut limit %s",
2456 qPrintable(QString().fill(
' ', d)),
2458 qPrintable(base.
pretty()),
2459 qPrintable(cutLimit.
pretty()));
2466 if (callee->
subCost(e) < cutLimit) {
2467 if (0) qDebug(
"%s Cut call to %s (cum. %s)",
2468 qPrintable(QString().fill(
' ', d)),
2475 if (called->_cycleLow==0) {
2478 if (called->_cycleLow < _cycleLow)
2479 _cycleLow = called->_cycleLow;
2481 else if (called->_cycleStackDown) {
2483 if (called->_cycleLow < _cycleLow)
2484 _cycleLow = called->_cycleLow;
2486 if (0) qDebug(
"%s (low %d) Back to %s",
2487 qPrintable(QString().fill(
' ', d)),
2488 _cycleLow, qPrintable(called->
prettyName()));
2492 if (prefixNo == _cycleLow) {
2495 if (*pTop ==
this) {
2496 *pTop = _cycleStackDown;
2497 _cycleStackDown = 0;
2503 if (0) qDebug(
"Found Cycle %d with base %s:",
2510 *pTop = top->_cycleStackDown;
2511 top->_cycleStackDown = 0;
2513 if (0) qDebug(
" %s", qPrintable(top->
prettyName()));
2514 if (top ==
this)
break;
2525 if (_instrMapFilled)
return _instrMap;
2526 _instrMapFilled =
true;
2539 if (0) qDebug(
"PartFunction %s:%d",
2544 for(; fc; fc = fc->nextCostOfPartFunction()) {
2545 if (fc->addr() == 0)
continue;
2547 if (!l || (l->
lineno() != fc->line()) ||
2551 if (!i || i->
addr() != fc->addr()) {
2552 i = &(*_instrMap)[fc->addr()];
2560 if (!pi || pi->
part() != fc->
part())
2570 if (fj->
addr() == 0)
continue;
2576 if (!i || i->
addr() != fj->
addr()) {
2577 i = &(*_instrMap)[fj->
addr()];
2595 if (0) qDebug(
"PartCall %s:%d",
2600 for(; fcc; fcc = fcc->nextCostOfPartCall()) {
2601 if (fcc->addr() == 0)
continue;
2603 if (!l || (l->
lineno() != fcc->line()) ||
2607 if (!i || i->
addr() != fcc->addr()) {
2608 i = &(*_instrMap)[fcc->addr()];
2619 if (!pic || pic->
part() != fcc->
part())
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()));
2650 setName(QString(
"<cycle %1>").arg(n));
2675 if (_members.count()==0)
return;
2681 if (_members.contains(call->
caller()))
continue;
2712 if (
_name.isEmpty())
2719 return QObject::tr(
"(global)");
2735 #if TRACE_ASSERTIONS
2736 if (function->cls() !=
this) {
2737 qDebug(
"Can not add function to a class not enclosing this function\n");
2741 if (_functions.contains(
function))
return;
2744 _functions.append(
function);
2749 qDebug(
"%s added\n %s (now %d)",
2751 qPrintable(function->fullName()), _functions.count());
2783 #if TRACE_ASSERTIONS
2784 if (function->file() !=
this) {
2785 qDebug(
"Can not add function to a file not enclosing this function\n");
2789 if (_functions.contains(
function))
return;
2792 _functions.append(
function);
2797 qDebug(
"%s added\n %s (now %d)",
2799 qPrintable(function->fullName()), _functions.count());
2806 #if TRACE_ASSERTIONS
2807 if (sourceFile->
file() !=
this) {
2808 qDebug(
"Can not add sourceFile to a file not having lines for it\n");
2813 _sourceFiles.append(sourceFile);
2818 qDebug(
"%s \n added SourceFile %s (now %d)",
2820 _sourceFiles.count());
2828 if (dir.endsWith(
'/'))
2829 _dir = dir.left(dir.length()-1);
2836 if (!_dir.isEmpty())
return _dir;
2838 int lastIndex = 0, index;
2839 while ( (index=
_name.indexOf(
"/", lastIndex)) >=0)
2840 lastIndex = index+1;
2842 if (lastIndex==0)
return QString();
2845 return _name.left(lastIndex-1);
2851 int lastIndex = 0, index;
2852 while ( (index=
_name.indexOf(
"/", lastIndex)) >=0)
2853 lastIndex = index+1;
2855 return _name.mid(lastIndex);
2870 return QObject::tr(
"(unknown)");
2875 if (
_name.isEmpty())
2907 #if TRACE_ASSERTIONS
2908 if (function->object() !=
this) {
2909 qDebug(
"Can not add function to an object not enclosing this function\n");
2913 if (_functions.contains(
function))
return;
2916 _functions.append(
function);
2921 qDebug(
"%s added\n %s (now %d)",
2923 qPrintable(function->fullName()), _functions.count());
2929 if (dir.endsWith(
'/'))
2930 _dir = dir.left(dir.length()-1);
2937 if (!_dir.isEmpty())
return _dir;
2939 int lastIndex = 0, index;
2940 while ( (index=
_name.indexOf(
"/", lastIndex)) >=0)
2941 lastIndex = index+1;
2943 if (lastIndex==0)
return QString();
2946 return _name.left(lastIndex-1);
2952 int lastIndex = 0, index;
2953 while ( (index=
_name.indexOf(
"/", lastIndex)) >=0)
2954 lastIndex = index+1;
2956 return _name.mid(lastIndex);
2971 return QObject::tr(
"(unknown)");
2988 _eventTypeMapping = 0;
2993 delete _eventTypeMapping;
3018 int lastIndex = 0, index;
3019 while ( (index=_name.indexOf(
"/", lastIndex)) >=0)
3020 lastIndex = index+1;
3022 return _name.mid(lastIndex);
3028 QString
name = QString(
"PID %1").arg(_pid);
3030 name += QString(
", section %2").arg(_number);
3031 if ((
data()->maxThreadID()>1) && (_tid>0))
3032 name += QString(
", thread %3").arg(_tid);
3038 if (_active == active)
return false;
3074 void TraceData::init()
3076 _functionCycleCount = 0;
3077 _inFunctionCycleUpdate =
false;
3095 int lastIndex = 0, index;
3096 while ( (index=_traceName.indexOf(
"/", lastIndex)) >=0)
3097 lastIndex = index+1;
3099 return _traceName.mid(lastIndex);
3132 if (files.isEmpty())
return 0;
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";
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;
3151 if (files.isEmpty()) {
3152 _traceName +=
' ' + QObject::tr(
"(not found)");
3156 QStringList::const_iterator it;
3157 int partsLoaded = 0;
3158 for (it = files.constBegin(); it != files.constEnd(); ++it ) {
3160 partsLoaded += internalLoad(&file, *it);
3162 if (partsLoaded == 0)
return 0;
3173 return load(QStringList(file));
3178 _traceName = filename;
3179 int partsLoaded = internalLoad(file, filename);
3180 if (partsLoaded>0) {
3187 int TraceData::internalLoad(QIODevice* device,
const QString& filename)
3189 if (!device->open( QIODevice::ReadOnly ) ) {
3198 if (device->size() == 0)
return 0;
3206 int partsLoaded = l->
load(
this, device, filename);
3215 bool changed =
false;
3218 if (part->
activate(l.contains(part)))
3234 bool changed =
false;
3237 if (_parts.contains(part))
3262 if (_parts.contains(part)>0)
return;
3269 _parts.append(part);
3283 int r1=-1, r2=-1, count=0;
3287 if (r1<0) { r1 = r2 = count; }
3288 else if (r2 == count-1) { r2 = count; }
3290 if (!res.isEmpty()) res +=
';';
3291 if (r1==r2) res += QString::number(r1);
3292 else res += QString(
"%1-%2").arg(r1).arg(r2);
3298 if (!res.isEmpty()) res +=
';';
3299 if (r1==r2) res += QString::number(r1);
3300 else res += QString(
"%1-%2").arg(r1).arg(r2);
3310 TraceObjectMap::Iterator oit;
3311 for ( oit = _objectMap.begin();
3312 oit != _objectMap.end(); ++oit )
3313 (*oit).invalidate();
3315 TraceClassMap::Iterator cit;
3316 for ( cit = _classMap.begin();
3317 cit != _classMap.end(); ++cit )
3318 (*cit).invalidate();
3320 TraceFileMap::Iterator fit;
3321 for ( fit = _fileMap.begin();
3322 fit != _fileMap.end(); ++fit )
3323 (*fit).invalidate();
3325 TraceFunctionMap::Iterator it;
3326 for ( it = _functionMap.begin();
3327 it != _functionMap.end(); ++it ) {
3328 (*it).invalidateDynamicCost();
3345 qDebug(
"Created %s [TraceData::object]",
3362 qDebug(
"Created %s [TraceData::file]",
3373 int lastIndex = 0, index, pIndex;
3376 pIndex=fnName.indexOf(
'(', 0);
3379 int sIndex=fnName.find(
" ", 0);
3381 if ((pIndex == -1) || (sIndex < pIndex))
3385 while ((index=fnName.indexOf(
"::", lastIndex)) >=0) {
3386 if (pIndex>=0 && pIndex<index)
break;
3387 lastIndex = index+2;
3390 QString clsName = (lastIndex < 3) ? QString::null :
3391 fnName.left(lastIndex-2);
3392 shortName = fnName.mid(lastIndex);
3401 qDebug(
"Created %s [TraceData::cls]",
3417 if (!file || !
object || !c) {
3418 qDebug(
"ERROR - no file/object/class for %s ?!", qPrintable(name));
3444 QString key = name + file->
shortName() +
object->shortName();
3446 TraceFunctionMap::Iterator it;
3447 it = _functionMap.find(key);
3448 if (it == _functionMap.end()) {
3460 qDebug(
"Created %s [TraceData::function]\n for %s, %s, %s",
3463 object ? qPrintable(object->
fullName()) :
"(unknown object)");
3467 object->addFunction(&f);
3471 return &(it.value());
3484 return _functionMap.find(key);
3489 return _functionMap.begin();
3494 return _functionMap.end();
3500 TraceFileMap::Iterator fit;
3501 for ( fit = _fileMap.begin();
3502 fit != _fileMap.end(); ++fit )
3503 (*fit).resetDirectory();
3534 TraceFunctionMap::Iterator it;
3535 for ( it = _functionMap.begin();
3536 it != _functionMap.end(); ++it ) {
3547 if (sc <= scTop)
continue;
3559 TraceFileMap::Iterator it;
3560 for ( it = _fileMap.begin();
3561 it != _fileMap.end(); ++it ) {
3566 if (sc <= scTop)
continue;
3577 TraceClassMap::Iterator it;
3578 for ( it = _classMap.begin();
3579 it != _classMap.end(); ++it ) {
3584 if (sc <= scTop)
continue;
3595 TraceObjectMap::Iterator it;
3596 for ( it = _objectMap.begin();
3597 it != _objectMap.end(); ++it ) {
3602 if (sc <= scTop)
continue;
3613 if (!instrMap)
break;
3616 TraceInstrMap::Iterator it;
3617 for ( it = instrMap->begin();
3618 it != instrMap->end(); ++it ) {
3620 if (instr->
name() !=
name)
continue;
3637 TraceLineMap::Iterator it;
3640 if (!lineMap)
continue;
3642 for ( it = lineMap->begin();
3643 it != lineMap->end(); ++it ) {
3645 if (line->
name() !=
name)
continue;
3663 foreach(cycle, _functionCycles)
3664 if (cycle->
base() == f)
3667 _functionCycleCount++;
3670 _functionCycles.append(cycle);
3683 TraceFunctionMap::Iterator it;
3684 for ( it = _functionMap.begin(); it != _functionMap.end(); ++it )
3689 _inFunctionCycleUpdate =
true;
3693 int fCount = _functionMap.size(), fNo = 0, progress=0, p;
3694 QString msg = tr(
"Recalculating Function Cycles...");
3695 if (_topLevel) _topLevel->showStatus(msg,0);
3701 for ( it = _functionMap.begin(); it != _functionMap.end(); ++it ) {
3709 _topLevel->showStatus(msg, p);
3722 _inFunctionCycleUpdate =
false;
3727 if (0)
if (_topLevel) _topLevel->showStatus(QString(), 0);
TracePartCall(TraceCall *call)
Call Cost Item depends on a list of Call cost items.
TraceCallCost(ProfileContext *)
FixCallCost * nextCostOfPartCall() const
TraceInclusiveCostList deps()
void addCost(TraceJumpCost *)
virtual TracePart * part()
void setFile(TraceFile *file)
void addCaller(TraceCall *)
A source file containing function definitions.
TracePartClass(TraceClass *)
TraceCallListCost(ProfileContext *)
void setAddr(const Addr addr)
virtual ~TracePartInstrJump()
void addLineCall(TraceLineCall *)
SubCost subCost(EventType *)
Returns a sub cost.
bool activatePart(TracePart *, bool active)
TraceLine * line(uint lineno, bool createNew=true)
TraceClass * cls(const QString &fnName, QString &shortName)
bool partLessThan(const TracePart *p1, const TracePart *p2)
TraceObject * object(const QString &name)
virtual bool onlyActiveParts()
Cost item with additional inclusive metric.
TraceFunction * function()
bool activateAll(bool active=true)
virtual ~TracePartClass()
Cost of a call at a line from a trace file.
virtual bool onlyActiveParts()
TraceLineCall * lineCall() const
bool hasCost(EventType *)
virtual ~TracePartInstrCall()
void addPartInstr(TracePartInstr *)
QMap< uint, TraceLine > TraceLineMap
const TraceCallList & callings(bool skipCycle=false) const
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
void setCycle(TraceFunctionCycle *c)
A cycle of recursive calling functions.
ProfileCostArray * search(ProfileContext::Type, QString, EventType *ct=0, ProfileCostArray *parent=0)
Search for item with given name and highest subcost of given cost type.
virtual ~TracePartObject()
TraceLine * lineTo() const
TraceInstrJump(TraceInstr *instrFrom, TraceInstr *instrTo, bool isCondJump)
TraceInstr * instrTo() const
TracePart * partWithName(const QString &name)
virtual void update()
Updates cost attributes.
TraceFunction * caller(bool skipCycle=false) const
ProfileContext::Type type() const
ProfileCostArray * findDepFromPart(TracePart *)
TracePartObject * partObject()
TraceCostItem(ProfileContext *)
TraceLine * line(TraceFile *, uint lineno, bool createNew=true)
ProfileCostArray * totals()
TraceInstrJump * instrJump() const
void invalidateDynamicCost()
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
void setFunction(TraceFunction *f)
virtual ~TracePartLineJump()
TraceLineJump * lineJump() const
virtual void loadStart(const QString &filename)
virtual void clear()
Set all cost counters to zero.
void setDirectory(const QString &dir)
TraceFunction * function() const
QMap< Addr, TraceInstr > TraceInstrMap
virtual void update()
Updates cost attributes.
void addCallCount(SubCost c)
QString formattedName() const
A HTMLified version of name, can return empty string.
TraceObject * object() const
virtual ~TraceInclusiveCost()
void setContext(ProfileContext *context)
Redefine the context after construction.
QString prettyCallingCount()
void add(TraceFunction *)
virtual QString name() const
Returns dynamic name info (without type)
virtual bool onlyActiveParts()
TraceFunctionCycle * cycle()
virtual void invalidate()
Invalidate the cost attributes.
TraceLineJump * lineJump(TraceLine *to, bool isCondJump)
virtual void update()
Updates cost attributes.
Base class for cost items.
TraceFunction * function(const QString &name, TraceFile *, TraceObject *)
void addPartLine(TracePartLine *)
A call from an instruction of one function to another function.
QString shortName() const
To implement a new loader, inherit from the Loader class and and reimplement canLoad() and load()...
A call from a line of one function to another function.
void addPartFunction(TracePartFunction *f)
FixCost * nextCostOfPartFunction() const
EventTypeSet * eventTypes()
QString activePartRange()
bool hasCost(EventType *)
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
virtual QString costString(EventTypeSet *)
Returns text of all cost metrics.
TracePartInstrJump * partInstrJump(TracePart *)
unsigned int line() const
TraceInclusiveCost(ProfileContext *)
bool operator<(const TracePart &) const
static QString prettyEmptyName()
virtual ~TraceInclusiveListCost()
virtual TracePart * part()
Addresses are 64bit values like costs to be able to always load profile data produced on 64bit archit...
virtual ~TracePartLineCall()
TraceCallList callers(bool skipCycle=false) const
TraceFunctionSource * source() const
virtual void setName(const QString &name)
bool activateParts(const TracePartList &)
returns true if something changed.
TracePartFile(TraceFile *)
TraceAssoziation()
Creates an invalid assoziation.
void invalidateDynamicCost()
virtual void loadFinished(const QString &msg)
TraceAssoziation * assoziation(int rtti)
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
TraceFunctionCycle(TraceFunction *, int n)
virtual void update()
Updates cost attributes.
void invalidateAssoziation(int rtti)
A object containing a text segment (shared lib/executable) with defined functions.
TraceInstr * instr() const
virtual void update()
Updates cost attributes.
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
TraceInstrCall * instrCall(TraceInstr *)
void update()
Updates cost attributes.
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
void setDirectory(const QString &dir)
Cost of a call at a instruction code address from a trace file.
QString callerName(bool skipCycle=false) const
virtual ~TraceInstrCall()
void setMaxThreadID(int tid)
TracePartInstrCall(TraceInstrCall *)
TraceInclusiveCost * findDepFromPart(TracePart *)
FixJump * firstFixJump() const
virtual void clear()
Set all cost counters to zero.
A class holding an unchangable cost item of an input file.
virtual bool onlyActiveParts()
void addFunction(TraceFunction *)
An array of basic cost metrics for a trace item.
void cycleDFS(int d, int &pNo, TraceFunction **pTop)
TracePartInstrCall * partInstrCall(TracePart *, TracePartCall *)
virtual QString name() const
Returns dynamic name info (without type)
Base class for source contexts which event costs contained in a ProfileData instance, ie.
TracePartFunction * partFunction(TracePart *, TracePartFile *, TracePartObject *)
A code instruction address of the program.
void updateObjectCycles()
void addFunction(TraceFunction *)
TracePartLine(TraceLine *)
virtual void update()
Updates cost attributes.
QString prettyNameWithLocation(int maxFiles=1) const
virtual QString name() const
Returns dynamic name info (without type)
virtual QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
virtual void update()
Updates cost attributes.
void updateFunctionCycles()
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
static QString prettyEmptyName()
void setClass(TraceClass *cls)
Cost of a class, from a single trace file.
TracePartFile * partFile()
int load(QStringList files)
Loads profile data files.
void setObject(TraceObject *object)
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
TraceInclusiveListCost(ProfileContext *)
virtual QString name() const
Returns dynamic name info (without type)
For temporary assoziation of objects with TraceFunctions.
QString fullName() const
Returns type name + dynamic name.
virtual void update()
Updates cost attributes.
void addInstrCall(TraceInstrCall *)
static void clear(TraceData *data, int rtti)
Delete all assoziations in TraceFunctions of data with rtti runtime info.
virtual QString costString(EventTypeSet *m)
Returns text of all cost metrics.
TracePartCall * partCall(TracePart *, TracePartFunction *, TracePartFunction *)
QString prettyCallCount()
A container helper class for TraceFunction for source lines where a function is implemented in...
virtual QString name() const
Returns dynamic name info (without type)
void addInclusive(ProfileCostArray *)
void addDep(TraceInclusiveCost *)
virtual ~TraceInstrJump()
void addPartCaller(TracePartCall *)
Cost of a line from a trace file.
virtual QString name() const
Returns dynamic name info (without type)
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
void addTo(TraceCallCost *)
void setPosition(CostItem *p)
If this item is from a single profile data file, position points to a TracePart, otherwise to a Trace...
virtual TraceData * data()
TraceFunctionMap::ConstIterator functionEndIterator() const
Cost Item depends on a list of cost items.
virtual QString name() const
Returns dynamic name info (without type)
TracePartInstr * partInstr(TracePart *part, TracePartFunction *partFunction)
void addTo(ProfileCostArray *)
TracePartFunction(TraceFunction *, TracePartObject *, TracePartFile *)
virtual void invalidate()
Invalidate the cost attributes.
ProfileCostArray _inclusive
A source line of the program.
void addAssoziation(TraceAssoziation *a)
Cost of a function, from a single trace file.
TraceFunction * _function
TraceLineCall(TraceCall *call, TraceLine *line)
void addPartFunction(TracePartFunction *f)
virtual QString name() const
Returns dynamic name info (without type)
TracePartLine * partLine(TracePart *part, TracePartFunction *partFunction)
TraceFunctionCycle * _cycle
static QString prettyEmptyName()
TraceListCost(ProfileContext *)
TraceFunctionMap::Iterator functionIterator(TraceFunction *)
virtual QString name() const
Returns dynamic name info (without type)
virtual ~TraceCallListCost()
void setMaxPartNumber(int n)
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
TraceInstr * instr() const
Jump Cost Item depends on a list of Jump cost items.
TraceCallCost * findDepFromPart(TracePart *)
TraceFunctionSource * functionSource() const
TracePartClass * partClass(TracePart *)
virtual ~TraceAssoziation()
QList< TraceFunctionSource * > TraceFunctionSourceList
void setPartClass(TracePartClass *c)
Cost of a call at a function to another function, from a single trace file.
virtual void update()
Updates cost attributes.
QString prettyLongName() const
TraceLineCall * lineCall(TraceLine *)
TracePartLineCall(TraceLineCall *)
void invalidateDynamicCost()
TraceJumpCost * findDepFromPart(TracePart *)
TraceInstrMap * instrMap()
EventType * realType(int)
void setPartObject(TracePartObject *o)
virtual ~TracePartFunction()
Cost of a code instruction address from a trace file.
virtual void clear()
Set all cost counters to zero.
Inclusive Cost Item depends on a list of inclusive cost items.
TraceLine * lineFrom() const
TraceFunction * base() const
static Loader * matchingLoader(QIODevice *file)
A Trace Part: All data read from a trace file, containing all costs that happened in a specified time...
virtual ~TracePartInstr()
void addFunction(TraceFunction *)
virtual void clear()
Set all cost counters to zero.
A jump from an instruction to another inside of a function.
TraceFile * file(const QString &name)
QString prettyCalledCount()
void addSourceFile(TraceFunctionSource *)
virtual void update()
Updates cost attributes.
TraceInstrJump * instrJump(TraceInstr *to, bool isCondJump)
QString shortTraceName() const
void addTo(TraceJumpCost *)
void setSourceFile(TraceFunctionSource *sf)
TracePartInstrJump * next() const
virtual ~TraceFunctionSource()
virtual QString name() const
Returns dynamic name info (without type)
FixCallCost * firstFixCallCost() const
TracePartFile * partFile(TracePart *)
A class holding a jump (mostly) inside of a function.
Cost of jump at a instruction code address from a trace file.
Cost event counter, simple wrapper around a 64bit entity.
TraceObject * object() const
TraceFunctionSource * sourceFile(TraceFile *file=0, bool createNew=false)
static bool hideTemplates()
Cost of a source file, from a single trace file.
void addDep(ProfileCostArray *)
TracePartLineJump(TraceLineJump *)
TraceFunctionCycle * functionCycle(TraceFunction *)
unsigned int targetLine() const
TraceJumpListCost(ProfileContext *)
FixCost * firstFixCost() const
Addr firstAddress() const
Cost item with additional call count metric.
TraceFunction * called(bool skipCycle=false) const
void addPrettyLocation(QString &, int maxFiles=1) const
Cost of jump at a source line from a trace file.
TraceInstrCall(TraceCall *call, TraceInstr *instr)
virtual void update()
Updates cost attributes.
void addCost(EventTypeMapping *, const char *)
QList< TracePart * > TracePartList
QString pretty(char sep= ' ') const
Convert SubCost value into a QString, spaced every 3 digits.
A class for managing a set of event types.
TraceLineJump(TraceLine *lineFrom, TraceLine *lineTo, bool isCondJump)
virtual int load(TraceData *, QIODevice *file, const QString &filename)
TraceFunctionSource * targetSource() const
TracePartObject(TraceObject *)
QList< TraceCall * > TraceCallList
TraceFunctionSource(TraceFunction *, TraceFile *)
void removeAssoziation(TraceAssoziation *a)
bool setFunction(TraceFunction *)
reset function to associate this object to.
TraceInclusiveCostList _deps
TracePartLineCall * partLineCall(TracePart *, TracePartCall *)
TraceInstr * instrFrom() const
TraceFunctionMap & functionMap()
QString prettyLocation(int maxFiles=0) const
TraceFunction * targetFunction() const
TracePartInstrJump(TraceInstrJump *, TracePartInstrJump *)
This class holds profiling data of multiple tracefiles generated with cachegrind on one command...
void setLineno(uint lineno)
TracePartObject * partObject(TracePart *)
TraceJumpCost(ProfileContext *)
const TracePartCallList & partCallings()
Cost of a (conditional) jump.
static QString prettyEmptyName()
QString location(int maxFiles=0) const
Returns empty string if location is fully unknown.
TracePartLineJump * partLineJump(TracePart *)
void setPartNumber(int n)
TracePartInstr(TraceInstr *)
static ProfileContext * context(ProfileContext::Type)
A call from one to another function.
void addPartFunction(TracePartFunction *f)
QString prettyCalledCount()
TraceInstr * instr(Addr addr, bool createNew=true)
TraceInstrCall * instrCall() const
bool isAssoziated()
Could we set the function assoziation to ourself? This only can return false if this is a unique asso...
QString shortName() const
void addPart(TracePart *)
void setLine(TraceLine *l)
TraceCall * calling(TraceFunction *called)
QString calledName(bool skipCycle=false) const
A jump from one line to another inside of a function.
QString prettyCallingCount()
void addPartCalling(TracePartCall *)
ProfileCostArray * inclusive()
TraceCall(TraceFunction *caller, TraceFunction *called)
void addDep(TraceJumpCost *)
virtual ~TraceJumpListCost()
FixJump * nextJumpOfPartFunction() const
QString shortName() const
Cost of a object, from a single trace file.
A FixCallCost will be inserted into a.
virtual void update()
Updates cost attributes.
void addDep(TraceCallCost *)
void invalidateDynamicCost()
TraceFunctionMap::ConstIterator functionBeginIterator() const