File indexing completed on 2024-04-28 09:36:49

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 /*
0010  * Classes holding profiling data for
0011  * multiple tracefiles for one command.
0012  * See class TraceData first.
0013  */
0014 
0015 #ifndef TRACEDATA_H
0016 #define TRACEDATA_H
0017 
0018 #include <qstring.h>
0019 #include <qstringlist.h>
0020 #include <qmap.h>
0021 
0022 #include "costitem.h"
0023 #include "subcost.h"
0024 #include "utils.h"
0025 #include "addr.h"
0026 #include "context.h"
0027 #include "eventtype.h"
0028 
0029 class QFile;
0030 
0031 /**
0032  * All cost items are classes prefixed with "Trace".
0033  * "ProfileCostArray" holds basic cost metrics for the simplest, smallest
0034  * trace entity: These are events counted for an instruction at
0035  * a specific memory address of the traced program.
0036  * All other cost items are derived from ProfileCostArray, and add needed
0037  * cost metrics, e.g. for a call the number of calls that happened.
0038  *
0039  * Abstract, i.e. never instantiated cost items are
0040  * - ProfileCostArray: Basic cost metrics (instr/read/write access + cache events)
0041  * - TraceCallCost: Additional call count cost metric.
0042  * - TraceInclusiveCost: Additional ProfileCostArray aggregated.
0043  * - TraceListCost: Adds dependency to a list of ProfileCostArray's
0044  * - TraceCallListCost: same for list of TraceCallCost's
0045  * - TraceInclusiveListCost: same for list of TraceInclusiveCost's
0046  * - TraceCostItem: Base for cost items for "interesting" costs:
0047  *              TraceFunction, TraceClass, TraceFile, TraceObject
0048  *
0049  * The smallest Cachegrind output is trace data indexed by a source
0050  * line number, a TracePartLine. Another one is a call from one
0051  * source line of a function to another function, a TracePartLineCall.
0052  * All other cost items derive the value by summation of cost metrics
0053  * from TraceLineItem and TracePartLineCall costs; their cost is
0054  * calculated lazy on demand and cached afterwards.
0055  *
0056  * For cost items, which are sums over all trace files read in, the
0057  * summed cost metrics change when e.g. a new trace file is read.
0058  * Thus, their cached costs are invalidated, and again recalculated
0059  * only on demand. In the following list, theses cost items are called
0060  * "dynamic", the other "fixed" (but neverless calculated lazy).
0061  *
0062  *  Cost Item          Type      Summation of ...
0063  *
0064  *  TracePartLineCall  fixed     Read from trace file
0065  *  TracePartLine      fixed     Read from trace file
0066  *  TracePartCall      fixed     TracePartLineCall's
0067  *  TraceLineCall      dynamic   TracePartLineCall's
0068  *  TraceCall          dynamic   TraceLineCall's
0069  *  TraceLine          dynamic   TracePartLine's and TraceLineCall's
0070  *  TracePartFunction  fixed     TracePartLine's / TracePartCall's
0071  *  TraceFunction      dynamic   TraceLine's / TraceCall's (called from)
0072  *  TracePartClass     fixed     TracePartFunction's
0073  *  TraceClass         dynamic   TraceFunction's
0074  *  TracePartFile      fixed     TracePartFunction's
0075  *  TraceFile          dynamic   TraceFunction's
0076  *  TracePartObject    fixed     TracePartFunction's
0077  *  TraceObject        dynamic   TraceFunction's
0078  *  TracePart          fixed     TracePartLine's
0079  *  TraceData          dynamic   TracePart's
0080  *
0081  * As there exists only one TraceData object for a traced program, it is the
0082  * owner of some "high level" cost items. The following shows the owner
0083  * relationship of the cost item classes, together with references.
0084  *
0085  *  Cost Item          Owner (& back ref)   Other References to
0086  *
0087  *  TracePartLineCall  TraceLineCall
0088  *  TracePartCall      TraceCall            TracePartLineCall's
0089  *  TracePartLine      TraceLine            TracePartLineCall's
0090  *  TracePartFunction  TraceFunction
0091  *  TracePartClass     TraceClass           TracePart
0092  *  TracePartFile      TraceFile            TracePart
0093  *  TracePartObject    TraceObject          TracePart
0094  *  TraceLineCall      TraceCall            TracePartLineCall's
0095  *  TraceCall          TraceFunction        TracePartCall's
0096  *  TraceLine          TraceData            TraceLineCall's
0097  *  TraceFunction      TraceData            TraceCall's (calling)
0098  *  TraceClass         TraceData
0099  *  TraceFile          TraceData
0100  *  TraceObject        TraceData
0101  *  TracePart          TraceData
0102  *  TraceData          Main Application
0103  *
0104  * Convention:
0105  * - The owner has a factory method for owned objects,
0106  *   and calls addXXX() to install references in other objects
0107  * - The owner is first arg in a constructor.
0108  */
0109 
0110 
0111 class FixCost;
0112 class FixCallCost;
0113 class FixJump;
0114 class FixPool;
0115 class DynPool;
0116 class Logger;
0117 
0118 class ProfileCostArray;
0119 class EventType;
0120 class EventTypeSet;
0121 class EventTypeMapping;
0122 class TraceJumpCost;
0123 class TraceCallCost;
0124 class TraceInclusiveCost;
0125 
0126 class TracePartInstr;
0127 class TracePartInstrCall;
0128 class TracePartLine;
0129 class TracePartLineCall;
0130 class TracePartCall;
0131 class TracePartLineRegion;
0132 class TracePartFunction;
0133 class TracePartClass;
0134 class TracePartObject;
0135 class TracePartFile;
0136 
0137 class TraceInstr;
0138 class TraceInstrJump;
0139 class TraceInstrCall;
0140 class TraceLine;
0141 class TraceLineJump;
0142 class TraceLineCall;
0143 class TraceCall;
0144 class TraceLineRegion;
0145 class TraceFunctionSource;
0146 class TraceFunction;
0147 class TraceFunctionCycle;
0148 class TraceClass;
0149 class TraceObject;
0150 class TraceFile;
0151 class TracePart;
0152 class TraceData;
0153 
0154 typedef QList<ProfileCostArray*> TraceCostList;
0155 typedef QList<TraceJumpCost*> TraceJumpCostList;
0156 typedef QList<TraceCallCost*> TraceCallCostList;
0157 typedef QList<TraceInclusiveCost*> TraceInclusiveCostList;
0158 
0159 typedef QList<TracePartCall*> TracePartCallList;
0160 typedef QList<TracePartInstr*> TracePartInstrList;
0161 typedef QList<TracePartLine*> TracePartLineList;
0162 typedef QList<TracePartLineRegion*> TracePartLineRegionList;
0163 typedef QList<TracePartFunction*> TracePartFunctionList;
0164 typedef QList<TracePartInstrCall*> TracePartInstrCallList;
0165 typedef QList<TracePartLineCall*> TracePartLineCallList;
0166 typedef QList<TracePart*> TracePartList;
0167 
0168 typedef QList<TraceInstr*> TraceInstrList;
0169 typedef QList<TraceLine*> TraceLineList;
0170 typedef QList<TraceInstrJump*> TraceInstrJumpList;
0171 typedef QList<TraceLineJump*> TraceLineJumpList;
0172 typedef QList<TraceInstrCall*> TraceInstrCallList;
0173 typedef QList<TraceLineCall*> TraceLineCallList;
0174 typedef QList<TraceCall*> TraceCallList;
0175 typedef QList<TraceFile*> TraceFileList;
0176 typedef QList<TraceLineRegion*> TraceLineRegionList;
0177 typedef QList<TraceFunctionSource*> TraceFunctionSourceList;
0178 typedef QList<TraceFunction*> TraceFunctionList;
0179 typedef QList<TraceFunctionCycle*> TraceFunctionCycleList;
0180 typedef QMap<QString, TraceObject> TraceObjectMap;
0181 typedef QMap<QString, TraceClass> TraceClassMap;
0182 typedef QMap<QString, TraceFile> TraceFileMap;
0183 typedef QMap<QString, TraceFunction> TraceFunctionMap;
0184 typedef QMap<uint, TraceLine> TraceLineMap;
0185 typedef QMap<Addr, TraceInstr> TraceInstrMap;
0186 
0187 
0188 /**
0189  * Cost of a (conditional) jump.
0190  */
0191 class TraceJumpCost: public CostItem
0192 {
0193 public:
0194     explicit TraceJumpCost(ProfileContext*);
0195     ~TraceJumpCost() override;
0196 
0197     // reimplementations for cost addition
0198     QString costString(EventTypeSet* m) override;
0199     void clear() override;
0200 
0201     void addCost(TraceJumpCost*);
0202 
0203     // additional cost metrics
0204     SubCost followedCount();
0205     SubCost executedCount();
0206     void addFollowedCount(SubCost c) { _followedCount += c; }
0207     void addExecutedCount(SubCost c) { _executedCount += c; }
0208 
0209 protected:
0210     SubCost _executedCount, _followedCount;
0211 };
0212 
0213 
0214 
0215 /**
0216  * Cost item with additional call count metric.
0217  */
0218 class TraceCallCost: public ProfileCostArray
0219 {
0220 public:
0221     explicit TraceCallCost(ProfileContext*);
0222     ~TraceCallCost() override;
0223 
0224     // reimplementations for cost addition
0225     QString costString(EventTypeSet* m) override;
0226     void clear() override;
0227 
0228     // additional cost metric
0229     SubCost callCount();
0230     QString prettyCallCount();
0231     void addCallCount(SubCost c);
0232 
0233 protected:
0234     SubCost _callCount;
0235 };
0236 
0237 
0238 /**
0239  * Cost item with additional inclusive metric
0240  */
0241 class TraceInclusiveCost: public ProfileCostArray
0242 {
0243 public:
0244     explicit TraceInclusiveCost(ProfileContext*);
0245     ~TraceInclusiveCost() override;
0246 
0247     // reimplementations for cost addition
0248     QString costString(EventTypeSet* m) override;
0249     void clear() override;
0250 
0251     // additional cost metric
0252     ProfileCostArray* inclusive();
0253     void addInclusive(ProfileCostArray*);
0254 
0255 protected:
0256     ProfileCostArray _inclusive;
0257 };
0258 
0259 
0260 /**
0261  * Cost Item
0262  * depends on a list of cost items.
0263  */
0264 class TraceListCost: public ProfileCostArray
0265 {
0266 public:
0267     explicit TraceListCost(ProfileContext*);
0268     ~TraceListCost() override;
0269 
0270     // reimplementation for dependency list
0271     void update() override;
0272 
0273     TraceCostList& deps() { return _deps; }
0274     void addDep(ProfileCostArray*);
0275     ProfileCostArray* findDepFromPart(TracePart*);
0276 
0277 protected:
0278     // overwrite in subclass to change update behaviour
0279     virtual bool onlyActiveParts() { return false; }
0280 
0281     TraceCostList _deps;
0282 
0283 private:
0284     // very temporary: cached
0285     ProfileCostArray* _lastDep;
0286 };
0287 
0288 
0289 /**
0290  * Jump Cost Item
0291  * depends on a list of Jump cost items.
0292  */
0293 class TraceJumpListCost: public TraceJumpCost
0294 {
0295 public:
0296     explicit TraceJumpListCost(ProfileContext*);
0297     ~TraceJumpListCost() override;
0298 
0299     // reimplementation for dependency list
0300     void update() override;
0301 
0302     TraceJumpCostList deps() { return _deps; }
0303     void addDep(TraceJumpCost*);
0304     TraceJumpCost* findDepFromPart(TracePart*);
0305 
0306 protected:
0307     // overwrite in subclass to change update behaviour
0308     virtual bool onlyActiveParts() { return false; }
0309 
0310     TraceJumpCostList _deps;
0311 
0312 private:
0313     // very temporary: cached
0314     TraceJumpCost* _lastDep;
0315 };
0316 
0317 
0318 
0319 
0320 /**
0321  * Call Cost Item
0322  * depends on a list of Call cost items.
0323  */
0324 class TraceCallListCost: public TraceCallCost
0325 {
0326 public:
0327     explicit TraceCallListCost(ProfileContext*);
0328     ~TraceCallListCost() override;
0329 
0330     // reimplementation for dependency list
0331     void update() override;
0332 
0333     TraceCallCostList deps() { return _deps; }
0334     void addDep(TraceCallCost*);
0335     TraceCallCost* findDepFromPart(TracePart*);
0336 
0337 protected:
0338     // overwrite in subclass to change update behaviour
0339     virtual bool onlyActiveParts() { return false; }
0340 
0341     TraceCallCostList _deps;
0342 
0343 private:
0344     // very temporary: cached
0345     TraceCallCost* _lastDep;
0346 };
0347 
0348 
0349 /**
0350  * Inclusive Cost Item depends on a list of inclusive cost items.
0351  */
0352 class TraceInclusiveListCost: public TraceInclusiveCost
0353 {
0354 public:
0355     explicit TraceInclusiveListCost(ProfileContext*);
0356     ~TraceInclusiveListCost() override;
0357 
0358     // reimplementation for dependency
0359     void update() override;
0360 
0361     TraceInclusiveCostList deps() { return _deps; }
0362     void addDep(TraceInclusiveCost*);
0363     TraceInclusiveCost* findDepFromPart(TracePart*);
0364 
0365 protected:
0366     // overwrite in subclass to change update behaviour
0367     virtual bool onlyActiveParts() { return false; }
0368 
0369     TraceInclusiveCostList _deps;
0370 
0371 private:
0372     // very temporary: cached
0373     TraceInclusiveCost* _lastDep;
0374 };
0375 
0376 
0377 
0378 
0379 
0380 /*-----------------------------------------------------------------
0381  * Classes for cost items of one trace file, i.e. a "trace part"
0382  *-----------------------------------------------------------------
0383  */
0384 
0385 /**
0386  * Cost of jump at a instruction code address from a trace file.
0387  */
0388 class TracePartInstrJump: public TraceJumpCost
0389 {
0390 public:
0391     TracePartInstrJump(TraceInstrJump*, TracePartInstrJump*);
0392     ~TracePartInstrJump() override;
0393 
0394     // fix cost item
0395     void update() override {}
0396     TraceInstrJump* instrJump() const { return (TraceInstrJump*) _dep; }
0397     TracePartInstrJump* next() const { return _next; }
0398 
0399 private:
0400     // chaining all parts for InstrJump
0401     TracePartInstrJump* _next;
0402 };
0403 
0404 
0405 /**
0406  * Cost of a call at a instruction code address from a trace file.
0407  * Cost is always up to date, no lazy update needed.
0408  */
0409 class TracePartInstrCall: public TraceCallCost
0410 {
0411 public:
0412     explicit TracePartInstrCall(TraceInstrCall*);
0413     ~TracePartInstrCall() override;
0414 
0415     // fix cost item
0416     void update() override {}
0417     TraceInstrCall* instrCall() const { return (TraceInstrCall*) _dep; }
0418 };
0419 
0420 
0421 /**
0422  * Cost of a code instruction address from a trace file.
0423  * Cost is always up to date, no lazy update needed.
0424  */
0425 class TracePartInstr: public ProfileCostArray
0426 {
0427 public:
0428     explicit TracePartInstr(TraceInstr*);
0429     ~TracePartInstr() override;
0430 
0431     // fix cost item
0432     void update() override {}
0433 
0434     TraceInstr* instr() const { return (TraceInstr*)_dep; }
0435 };
0436 
0437 
0438 /**
0439  * Cost of jump at a source line from a trace file.
0440  */
0441 class TracePartLineJump: public TraceJumpCost
0442 {
0443 public:
0444     explicit TracePartLineJump(TraceLineJump*);
0445     ~TracePartLineJump() override;
0446 
0447     // fix cost item
0448     void update() override {}
0449     TraceLineJump* lineJump() const { return (TraceLineJump*) _dep; }
0450 };
0451 
0452 
0453 /**
0454  * Cost of a call at a line from a trace file.
0455  * Cost is always up to date, no lazy update needed.
0456  */
0457 class TracePartLineCall: public TraceCallCost
0458 {
0459 public:
0460     explicit TracePartLineCall(TraceLineCall*);
0461     ~TracePartLineCall() override;
0462 
0463     // fix cost item
0464     void update() override {}
0465     TraceLineCall* lineCall() const { return (TraceLineCall*) _dep; }
0466 };
0467 
0468 
0469 
0470 /**
0471  * Cost of a line from a trace file.
0472  * Cost is always up to date, no lazy update needed.
0473  */
0474 class TracePartLine: public ProfileCostArray
0475 {
0476 public:
0477     explicit TracePartLine(TraceLine*);
0478     ~TracePartLine() override;
0479 
0480     // fix cost item
0481     void update() override {}
0482 
0483     TraceLine* line() const { return (TraceLine*)_dep; }
0484 };
0485 
0486 
0487 /**
0488  * Cost of a source region.
0489  */
0490 class TracePartLineRegion: public TraceInclusiveCost
0491 {
0492 public:
0493     explicit TracePartLineRegion(TraceLineRegion*);
0494     ~TracePartLineRegion() override;
0495 
0496     void update() override;
0497 
0498     TraceLineRegion* region() const { return (TraceLineRegion*)_dep; }
0499 };
0500 
0501 
0502 /**
0503  * Cost of a call at a function to another function,
0504  * from a single trace file.
0505  */
0506 class TracePartCall: public TraceCallListCost
0507 {
0508 public:
0509     explicit TracePartCall(TraceCall* call);
0510     ~TracePartCall() override;
0511 
0512     // calls a function itself?
0513     bool isRecursion();
0514 
0515     // reimplementation for dependency list
0516     void update() override;
0517 
0518     TraceCall* call() const { return (TraceCall*)_dep; }
0519 
0520     FixCallCost* setFirstFixCallCost(FixCallCost* fc)
0521     { FixCallCost* t = _firstFixCallCost; _firstFixCallCost = fc; return t; }
0522     FixCallCost* firstFixCallCost() const { return _firstFixCallCost; }
0523 
0524 private:
0525     FixCallCost* _firstFixCallCost;
0526 };
0527 
0528 
0529 /**
0530  * Cost of a function,
0531  * from a single trace file.
0532  */
0533 class TracePartFunction: public TraceInclusiveCost
0534 {
0535 public:
0536     TracePartFunction(TraceFunction*,
0537                       TracePartObject*, TracePartFile*);
0538     ~TracePartFunction() override;
0539 
0540     void update() override;
0541     QString costString(EventTypeSet* m) override;
0542 
0543     void addPartInstr(TracePartInstr*);
0544     void addPartLine(TracePartLine*);
0545     void addPartCaller(TracePartCall*);
0546     void addPartCalling(TracePartCall*);
0547 
0548     TraceFunction* function() { return (TraceFunction*) _dep; }
0549     TracePartObject* partObject() { return _partObject; }
0550     TracePartClass* partClass() { return _partClass; }
0551     TracePartFile* partFile() { return _partFile; }
0552     const TracePartCallList& partCallers() { return _partCallers; }
0553     const TracePartCallList& partCallings() { return _partCallings; }
0554     void setPartObject(TracePartObject* o) { _partObject = o; }
0555     void setPartClass(TracePartClass* c) { _partClass = c; }
0556     void setPartFile(TracePartFile* f) { _partFile = f; }
0557 
0558     /* for linked list of FixXXX objects */
0559     FixCost* setFirstFixCost(FixCost* fc)
0560     { FixCost* t = _firstFixCost; _firstFixCost = fc; return t; }
0561     FixCost* firstFixCost() const { return _firstFixCost; }
0562     FixJump* setFirstFixJump(FixJump* fj)
0563     { FixJump* t = _firstFixJump; _firstFixJump = fj; return t; }
0564     FixJump* firstFixJump() const { return _firstFixJump; }
0565 
0566     // additional cost metrics
0567     SubCost calledCount();
0568     SubCost callingCount();
0569     QString prettyCalledCount();
0570     QString prettyCallingCount();
0571     int calledContexts();
0572     int callingContexts();
0573 
0574 private:
0575     TracePartObject* _partObject;
0576     TracePartClass* _partClass;
0577     TracePartFile* _partFile;
0578 
0579     TracePartCallList _partCallings;
0580     TracePartCallList _partCallers;
0581     TracePartInstrList _partInstr;
0582     TracePartLineList _partLines;
0583 
0584     // cached
0585     SubCost _calledCount, _callingCount;
0586     int _calledContexts, _callingContexts;
0587 
0588     FixCost* _firstFixCost;
0589     FixJump* _firstFixJump;
0590 };
0591 
0592 
0593 /**
0594  * Cost of a class,
0595  * from a single trace file.
0596  */
0597 class TracePartClass: public TraceInclusiveListCost
0598 {
0599 public:
0600     explicit TracePartClass(TraceClass*);
0601     ~TracePartClass() override;
0602 
0603     QString prettyName() const override;
0604 
0605     TraceClass* cls() { return (TraceClass*)_dep; }
0606     void addPartFunction(TracePartFunction* f) { addDep(f); }
0607 };
0608 
0609 
0610 /**
0611  * Cost of a source file,
0612  * from a single trace file.
0613  */
0614 class TracePartFile: public TraceInclusiveListCost
0615 {
0616 public:
0617     explicit TracePartFile(TraceFile*);
0618     ~TracePartFile() override;
0619 
0620     TraceFile* file() { return (TraceFile*)_dep; }
0621     void addPartFunction(TracePartFunction* f) { addDep(f); }
0622 };
0623 
0624 
0625 /**
0626  * Cost of a object,
0627  * from a single trace file.
0628  */
0629 class TracePartObject: public TraceInclusiveListCost
0630 {
0631 public:
0632     explicit TracePartObject(TraceObject*);
0633     ~TracePartObject() override;
0634 
0635     TraceObject* object() const { return (TraceObject*)_dep; }
0636     void addPartFunction(TracePartFunction* f) { addDep(f); }
0637 };
0638 
0639 
0640 
0641 /**
0642  * A Trace Part: All data read from a trace file, containing all costs
0643  * that happened in a specified time interval of the executed command.
0644  */
0645 class TracePart: public TraceListCost
0646 {
0647 public:
0648     explicit TracePart(TraceData*);
0649     ~TracePart() override;
0650 
0651     TracePart* part() override { return this; }
0652     const TracePart* part() const override { return this; }
0653 
0654     QString shortName() const;
0655     QString prettyName() const override;
0656     /// @return Name of the file this part was loaded from
0657     QString name() const override { return _name; }
0658     QString description() const { return _descr; }
0659     QString trigger() const { return _trigger; }
0660     QString timeframe() const { return _timeframe; }
0661     QString version() const { return _version; }
0662     int partNumber() const { return _number; }
0663     int threadID() const { return _tid; }
0664     int processID() const { return _pid; }
0665     void setDescription(const QString& d) { _descr = d; }
0666     void setTrigger(const QString& t) { _trigger = t; }
0667     void setTimeframe(const QString& t) { _timeframe = t; }
0668     void setVersion(const QString& v) { _version = v; }
0669     void setName(const QString& n) { _name = n; }
0670     void setPartNumber(int n);
0671     void setThreadID(int t);
0672     void setProcessID(int p);
0673     ProfileCostArray* totals() { return &_totals; }
0674     /* passes ownership of mapping */
0675     void setEventMapping(EventTypeMapping* sm) { _eventTypeMapping = sm; }
0676     EventTypeMapping* eventTypeMapping() { return _eventTypeMapping; }
0677 
0678     // returns true if something changed
0679     bool activate(bool);
0680     bool isActive() const { return _active; }
0681 
0682     // for sorting
0683     bool operator<(const TracePart&) const;
0684 
0685 private:
0686     QString _name;
0687     QString _descr;
0688     QString _trigger;
0689     QString _timeframe;
0690     QString _version;
0691 
0692     int _number, _tid, _pid;
0693 
0694     bool _active;
0695 
0696     // the totals line
0697     ProfileCostArray _totals;
0698 
0699     // event type mapping for all fix costs of this part
0700     EventTypeMapping* _eventTypeMapping;
0701 };
0702 
0703 
0704 
0705 /*-----------------------------------------------------------------
0706  * Classes for cost items summed up from multiple trace parts
0707  *-----------------------------------------------------------------
0708  */
0709 
0710 
0711 /**
0712  * A jump from an instruction to another inside of a function
0713  */
0714 class TraceInstrJump: public TraceJumpCost
0715 {
0716 public:
0717     TraceInstrJump(TraceInstr* instrFrom, TraceInstr* instrTo,
0718                    bool isCondJump);
0719     ~TraceInstrJump() override;
0720 
0721     QString name() const override;
0722 
0723     void update() override;
0724 
0725     TraceInstr* instrFrom() const { return _instrFrom; }
0726     TraceInstr* instrTo() const { return _instrTo; }
0727     bool isCondJump() const { return _isCondJump; }
0728 
0729     // part factory
0730     TracePartInstrJump* partInstrJump(TracePart*);
0731 
0732 private:
0733     TraceInstr *_instrFrom, *_instrTo;
0734     bool _isCondJump;
0735     // list of parts for this InstrJump
0736     TracePartInstrJump* _first;
0737 };
0738 
0739 
0740 /**
0741  * A jump from one line to another inside of a function.
0742  */
0743 class TraceLineJump: public TraceJumpListCost
0744 {
0745 public:
0746     TraceLineJump(TraceLine* lineFrom, TraceLine* lineTo,
0747                   bool isCondJump);
0748     ~TraceLineJump() override;
0749 
0750     QString name() const override;
0751 
0752     TraceLine* lineFrom() const { return _lineFrom; }
0753     TraceLine* lineTo() const { return _lineTo; }
0754     bool isCondJump() { return _isCondJump; }
0755 
0756     // part factory
0757     TracePartLineJump* partLineJump(TracePart*);
0758 
0759 protected:
0760     bool onlyActiveParts() override { return true; }
0761 
0762 private:
0763     TraceLine *_lineFrom, *_lineTo;
0764     bool _isCondJump;
0765 };
0766 
0767 
0768 /**
0769  * A call from an instruction of one function to another function
0770  */
0771 class TraceInstrCall: public TraceCallListCost
0772 {
0773 public:
0774     TraceInstrCall(TraceCall* call, TraceInstr* instr);
0775     ~TraceInstrCall() override;
0776 
0777     QString name() const override;
0778 
0779     TraceInstr* instr() const { return _instr; }
0780     TraceCall* call() const { return _call; }
0781 
0782     // part factory
0783     TracePartInstrCall* partInstrCall(TracePart*, TracePartCall*);
0784 
0785 protected:
0786     bool onlyActiveParts() override { return true; }
0787 
0788 private:
0789     TraceInstr* _instr;
0790     TraceCall* _call;
0791 };
0792 
0793 
0794 /**
0795  * A call from a line of one function to another function.
0796  */
0797 class TraceLineCall: public TraceCallListCost
0798 {
0799 public:
0800     TraceLineCall(TraceCall* call, TraceLine* line);
0801     ~TraceLineCall() override;
0802 
0803     QString name() const override;
0804 
0805     TraceLine* line() const { return _line; }
0806     TraceCall* call() const { return _call; }
0807 
0808     // part factory
0809     TracePartLineCall* partLineCall(TracePart*, TracePartCall*);
0810 
0811 protected:
0812     bool onlyActiveParts() override { return true; }
0813 
0814 private:
0815     TraceLine* _line;
0816     TraceCall* _call;
0817 };
0818 
0819 
0820 /**
0821  * A call from one to another function.
0822  * Consists of a list a TraceLineCalls
0823  */
0824 class TraceCall: public TraceCallListCost
0825 {
0826 public:
0827     TraceCall(TraceFunction* caller, TraceFunction* called);
0828     ~TraceCall() override;
0829 
0830     QString name() const override;
0831 
0832     // calls a function itself?
0833     bool isRecursion() { return _caller == _called; }
0834 
0835     // return cycle number >0 if call is inside of a cycle
0836     int inCycle();
0837     // we need some special handling for cycle calls
0838     void update() override;
0839 
0840     void invalidateDynamicCost();
0841 
0842     // factories
0843     TracePartCall* partCall(TracePart*,
0844                             TracePartFunction*, TracePartFunction*);
0845     TraceLineCall* lineCall(TraceLine*);
0846     TraceInstrCall* instrCall(TraceInstr*);
0847 
0848     TraceFunction* caller(bool skipCycle=false) const;
0849     TraceFunction* called(bool skipCycle=false) const;
0850     QString callerName(bool skipCycle=false) const;
0851     QString calledName(bool skipCycle=false) const;
0852     const TraceLineCallList& lineCalls() const { return _lineCalls; }
0853     const TraceInstrCallList& instrCalls() const { return _instrCalls; }
0854 
0855     FixCallCost* setFirstFixCost(FixCallCost* fc)
0856     { FixCallCost* t = _firstFixCost; _firstFixCost = fc; return t; }
0857 
0858 protected:
0859     bool onlyActiveParts() override { return true; }
0860 
0861 private:
0862     TraceInstrCallList _instrCalls;
0863     TraceLineCallList _lineCalls;
0864     TraceFunction* _caller;
0865     TraceFunction* _called;
0866 
0867     FixCallCost* _firstFixCost;
0868 };
0869 
0870 
0871 /**
0872  * A code instruction address of the program.
0873  * Consists of a list a TracePartInstr from different trace files
0874  * and a list of TraceInstrCalls if there are calls from this address.
0875  */
0876 class TraceInstr: public TraceListCost
0877 {
0878 public:
0879     TraceInstr();
0880     ~TraceInstr() override;
0881 
0882     QString name() const override;
0883     QString prettyName() const override;
0884 
0885     bool isValid() { return _addr != Addr(0); }
0886 
0887     // factories
0888     TracePartInstr* partInstr(TracePart* part,
0889                               TracePartFunction* partFunction);
0890     TraceInstrJump* instrJump(TraceInstr* to, bool isCondJump);
0891 
0892     void addInstrCall(TraceInstrCall*);
0893 
0894     Addr addr() const { return _addr; }
0895     TraceFunction* function() const { return _function; }
0896     TraceLine* line() const { return _line; }
0897     const TraceInstrJumpList& instrJumps() const { return _instrJumps; }
0898     const TraceInstrCallList& instrCalls() const { return _instrCalls; }
0899     bool hasCost(EventType*);
0900 
0901     // only to be called after default constructor
0902     void setAddr(const Addr addr) { _addr = addr; }
0903     void setFunction(TraceFunction* f) { _function = f; }
0904     void setLine(TraceLine* l) { _line = l; }
0905 
0906 protected:
0907     bool onlyActiveParts() override { return true; }
0908 
0909 private:
0910     Addr _addr;
0911     TraceFunction* _function;
0912     TraceLine* _line;
0913 
0914     TraceInstrJumpList _instrJumps;
0915     TraceInstrCallList _instrCalls;
0916 };
0917 
0918 
0919 /**
0920  * A source line of the program.
0921  * Consists of a list a TracePartLines from different trace files
0922  * and a list of TraceLineCalls if there are calls from this line.
0923  */
0924 class TraceLine: public TraceListCost
0925 {
0926 public:
0927     TraceLine();
0928     ~TraceLine() override;
0929 
0930     QString name() const override;
0931     QString prettyName() const override;
0932 
0933     // factories
0934     TracePartLine* partLine(TracePart* part,
0935                             TracePartFunction* partFunction);
0936     TraceLineJump* lineJump(TraceLine* to, bool isCondJump);
0937 
0938     void addLineCall(TraceLineCall*);
0939 
0940 
0941     bool isValid() { return _sourceFile != nullptr; }
0942     bool hasCost(EventType*);
0943     TraceFunctionSource* functionSource() const { return _sourceFile; }
0944     uint lineno() const { return _lineno; }
0945     const TraceLineCallList& lineCalls() const { return _lineCalls; }
0946     const TraceLineJumpList& lineJumps() const { return _lineJumps; }
0947 
0948     // only to be called after default constructor
0949     void setSourceFile(TraceFunctionSource* sf) { _sourceFile = sf; }
0950     void setLineno(uint lineno) { _lineno = lineno; }
0951 
0952 protected:
0953     bool onlyActiveParts() override { return true; }
0954 
0955 private:
0956     TraceFunctionSource* _sourceFile;
0957     uint _lineno;
0958 
0959     TraceLineJumpList _lineJumps;
0960     TraceLineCallList _lineCalls;
0961 };
0962 
0963 
0964 /*
0965  * Base class for all costs which
0966  * represent "interesting" items or group of items
0967  * with settable name and inclusive cost
0968  */
0969 class TraceCostItem: public TraceInclusiveListCost
0970 {
0971 public:
0972     explicit TraceCostItem(ProfileContext*);
0973     ~TraceCostItem() override;
0974 
0975     QString name() const override { return _name; }
0976     virtual void setName(const QString& name) { _name = name; }
0977 
0978 protected:
0979     bool onlyActiveParts() override { return true; }
0980 
0981 protected:
0982     QString _name;
0983 };
0984 
0985 
0986 /**
0987  * Cost of a source region.
0988  */
0989 class TraceLineRegion: public TraceInclusiveListCost
0990 {
0991 public:
0992     TraceLineRegion(uint from, uint to, QString name);
0993     ~TraceLineRegion() override;
0994 
0995     void update() override;
0996 
0997     uint from() const { return _from; }
0998     uint to() const { return _to; }
0999     QString name() const override { return _name; }
1000 
1001     // factories
1002     TracePartLine* partLineRegion(TracePart* part,
1003                                   TracePartFunction* partFunction);
1004 private:
1005     uint _from, _to;
1006     QString _name;
1007 };
1008 
1009 
1010 /**
1011  * A container helper class for TraceFunction for source lines
1012  * where a function is implemented in.
1013  * With inlining, lines of the same function can come from
1014  * different source files.
1015  * An instance of this class holds all lines of one source file
1016  * for a function in a map
1017  */
1018 class TraceFunctionSource: public ProfileCostArray
1019 {
1020 public:
1021     TraceFunctionSource(TraceFunction*, TraceFile*);
1022     ~TraceFunctionSource() override;
1023 
1024     QString name() const override;
1025 
1026     // reimplementation for dependency map
1027     void update() override;
1028 
1029     TraceFile* file() const { return _file; }
1030     TraceFunction* function() const { return _function; }
1031     uint firstLineno();
1032     uint lastLineno();
1033     TraceLineMap* lineMap();
1034 
1035     void invalidateDynamicCost();
1036 
1037     /* factories */
1038     TraceLine* line(uint lineno, bool createNew = true);
1039     TraceLineRegion* region(uint from, uint to, QString name,
1040                             bool createNew = true);
1041 
1042 private:
1043     TraceFile* _file;
1044     TraceFunction* _function;
1045     TraceLineMap* _lineMap;
1046     TraceLine* _line0;
1047     TraceLineRegionList* _regions;
1048 
1049     bool _lineMapFilled;
1050 };
1051 
1052 
1053 /**
1054  * For temporary association of objects with TraceFunctions.
1055  * Used in coverage analysis and TreeMap drawing.
1056  */
1057 class TraceAssociation
1058 {
1059 public:
1060     /**
1061      * Creates an invalid association.
1062      */
1063     TraceAssociation();
1064     virtual ~TraceAssociation();
1065 
1066     // for runtime detection
1067     virtual int rtti() { return 0; }
1068 
1069     /**
1070      * Could we set the function association to ourself?
1071      * This only can return false if this is a unique association.
1072      */
1073     bool isAssociated();
1074 
1075     /**
1076      * reset function to associate this object to.
1077      * returns true if association could be established
1078      */
1079     bool setFunction(TraceFunction*);
1080     TraceFunction* function() { return _function; }
1081 
1082     void invalidate() { _valid = false; }
1083     bool isValid() { return _valid; }
1084 
1085     /**
1086      * Delete all associations in TraceFunctions of data with
1087      * rtti runtime info. rtti = 0: delete ALL associations.
1088      */
1089     static void clear(TraceData* data, int rtti);
1090 
1091     /**
1092      * Invalidate all associations in TraceFunctions of data with
1093      * rtti runtime info. rtti = 0: Invalidate ALL associations.
1094      */
1095     static void invalidate(TraceData* data, int rtti);
1096 
1097 protected:
1098     TraceFunction* _function;
1099     bool _valid;
1100 };
1101 
1102 typedef QList<TraceAssociation*> TraceAssociationList;
1103 
1104 /**
1105  * A traced function
1106  *
1107  * References to functions are stored in
1108  *  (1) a function map in TraceData (by value)
1109  *  (2) a TraceClass
1110  */
1111 class TraceFunction: public TraceCostItem
1112 {
1113 public:
1114     TraceFunction();
1115     TraceFunction(TraceData* data, const QString& name,
1116                   TraceClass* cls, TraceFile* file, TraceObject* object);
1117     ~TraceFunction() override;
1118 
1119     void update() override;
1120 
1121     // this invalidate all subcosts of function depending on
1122     // active status of parts
1123     void invalidateDynamicCost();
1124 
1125     void addCaller(TraceCall*);
1126 
1127     // factories
1128     TraceCall* calling(TraceFunction* called);
1129     TraceLine* line(TraceFile*, uint lineno, bool createNew = true);
1130     TraceInstr* instr(Addr addr, bool createNew = true);
1131     TracePartFunction* partFunction(TracePart*,
1132                                     TracePartFile*, TracePartObject*);
1133 
1134     /**
1135      * Returns empty string if location is fully unknown.
1136      * Use prettyLocation for single user-visible string.
1137      * A function can have a lot of code from different sources (inlined);
1138      * maxItems limits this list. Default is full list
1139      */
1140     QString location(int maxFiles = 0) const;
1141 
1142     QString prettyName() const override;
1143     QString formattedName() const override;
1144     static QString prettyEmptyName();
1145     QString prettyLocation(int maxFiles = 0) const;
1146     QString prettyNameWithLocation(int maxFiles = 1) const;
1147     void addPrettyLocation(QString&, int maxFiles = 1) const;
1148     // type + name + location
1149     QString info() const;
1150 
1151     TraceClass* cls() const { return _cls; }
1152     TraceFile* file() const { return _file; }
1153     TraceObject* object() const { return _object; }
1154     // get the source file with lines from function declaration (not inlined)
1155     TraceFunctionSource* sourceFile(TraceFile* file = nullptr,
1156                                     bool createNew = false);
1157     const TraceFunctionSourceList& sourceFiles() const
1158     { return _sourceFiles; }
1159     TraceCallList callers(bool skipCycle=false) const;
1160     const TraceCallList& callings(bool skipCycle=false) const;
1161 
1162     Addr firstAddress() const;
1163     Addr lastAddress() const;
1164     TraceInstrMap* instrMap();
1165 
1166     // cost metrics
1167     SubCost calledCount();
1168     SubCost callingCount();
1169     QString prettyCalledCount();
1170     QString prettyCallingCount();
1171     int calledContexts();
1172     int callingContexts();
1173 
1174     // only to be called after default constructor
1175     void setFile(TraceFile* file) { _file = file; }
1176     void setObject(TraceObject* object) { _object = object; }
1177     void setClass(TraceClass* cls) { _cls = cls; }
1178     //void setMapIterator(TraceFunctionMap::Iterator it) { _myMapIterator = it; }
1179 
1180     // see TraceFunctionAssociation
1181     void addAssociation(TraceAssociation* a);
1182     void removeAssociation(TraceAssociation* a);
1183     void removeAssociation(int rtti, bool reallyDelete = true);
1184     void invalidateAssociation(int rtti);
1185     TraceAssociation* association(int rtti);
1186 
1187     // cycles
1188     void setCycle(TraceFunctionCycle* c) { _cycle = c; }
1189     TraceFunctionCycle* cycle() { return _cycle; }
1190     bool isCycle();
1191     bool isCycleMember();
1192     void cycleReset();
1193     void cycleDFS(int d, int& pNo, TraceFunction** pTop);
1194 
1195 protected:
1196     TraceCallList _callers; // list of calls we are called from
1197     TraceCallList _callings; // list of calls we are calling (we are owner)
1198     TraceFunctionCycle* _cycle;
1199 
1200 private:
1201     bool isUniquePrefix(const QString&) const;
1202     //TraceFunctionMap::Iterator _myMapIterator;
1203 
1204     TraceClass* _cls;
1205     TraceObject* _object;
1206     TraceFile* _file;
1207 
1208     TraceFunctionSourceList _sourceFiles; // we are owner
1209     TraceInstrMap* _instrMap; // we are owner
1210     bool _instrMapFilled;
1211 
1212     // see TraceAssociation
1213     TraceAssociationList _associations;
1214 
1215     // for cycle detection
1216     int _cycleLow;
1217     TraceFunction* _cycleStackDown;
1218 
1219     // cached
1220     SubCost _calledCount, _callingCount;
1221     int _calledContexts, _callingContexts;
1222 };
1223 
1224 
1225 /**
1226  * A cycle of recursive calling functions.
1227  *
1228  * This is itself shown as a function
1229  */
1230 class TraceFunctionCycle: public TraceFunction
1231 {
1232 public:
1233     TraceFunctionCycle(TraceFunction*, int n);
1234 
1235     // this removes all members from this cycle
1236     void init();
1237     void add(TraceFunction*);
1238     // this sets up the cycle once members are added
1239     void setup();
1240 
1241     TraceFunction* base() const { return _base; }
1242     int cycleNo() const { return _cycleNo; }
1243     const TraceFunctionList& members() const { return _members; }
1244 
1245 private:
1246     TraceFunction* _base;
1247     int _cycleNo;
1248 
1249     TraceFunctionList _members;
1250 };
1251 
1252 
1253 /**
1254  * A C++ Class / Namespace
1255  *
1256  * If a function symbol has a prefix ending in "::",
1257  * the prefix is supposed to be a class/namespace specifier.
1258  * Without such a prefix, we put a symbol in the "(global)" namespace.
1259  */
1260 class TraceClass: public TraceCostItem
1261 {
1262 public:
1263     TraceClass();
1264     ~TraceClass() override;
1265 
1266     QString prettyName() const override;
1267     static QString prettyEmptyName();
1268 
1269     void addFunction(TraceFunction*);
1270     const TraceFunctionList& functions() const { return _functions; }
1271 
1272     // part factory
1273     TracePartClass* partClass(TracePart*);
1274 
1275 private:
1276     TraceFunctionList _functions;
1277 };
1278 
1279 
1280 
1281 /**
1282  * A source file containing function definitions
1283  */
1284 class TraceFile: public TraceCostItem
1285 {
1286 public:
1287     TraceFile();
1288     ~TraceFile() override;
1289 
1290     void setDirectory(const QString& dir);
1291     void resetDirectory() { _dir = QString(); }
1292     QString directory();
1293 
1294     void addFunction(TraceFunction*);
1295     void addSourceFile(TraceFunctionSource*);
1296 
1297     // without path
1298     QString shortName() const;
1299     QString prettyName() const override;
1300     QString prettyLongName() const;
1301     static QString prettyEmptyName();
1302     const TraceFunctionList& functions() const { return _functions; }
1303     const TraceFunctionSourceList& sourceFiles() const
1304     { return _sourceFiles; }
1305 
1306     // part factory
1307     TracePartFile* partFile(TracePart*);
1308 
1309 private:
1310     TraceFunctionList _functions;
1311     TraceFunctionSourceList _sourceFiles;
1312     QString _dir;
1313 };
1314 
1315 
1316 /**
1317  * A object containing a text segment (shared lib/executable)
1318  * with defined functions
1319  */
1320 class TraceObject: public TraceCostItem
1321 {
1322 public:
1323     TraceObject();
1324     ~TraceObject() override;
1325 
1326     void setDirectory(const QString& dir);
1327     void resetDirectory() { _dir = QString(); }
1328     QString directory();
1329 
1330     void addFunction(TraceFunction*);
1331 
1332     QString shortName() const;
1333     QString prettyName() const override;
1334     static QString prettyEmptyName();
1335     const TraceFunctionList& functions() const { return _functions; }
1336 
1337     // part factory
1338     TracePartObject* partObject(TracePart*);
1339 
1340 private:
1341     TraceFunctionList _functions;
1342     QString _dir;
1343 };
1344 
1345 
1346 
1347 /**
1348  * This class holds profiling data of multiple tracefiles
1349  * generated with cachegrind on one command.
1350  *
1351  */
1352 class TraceData: public ProfileCostArray
1353 {
1354 public:
1355     // profiled architecture (must be same for every part)
1356     enum Arch { ArchUnknown, ArchARM };
1357 
1358     explicit TraceData(Logger* l = nullptr);
1359     ~TraceData() override;
1360 
1361     TraceData* data() override { return this; }
1362     const TraceData* data() const override { return this; }
1363 
1364     /**
1365      * Loads profile data files.
1366      * If a single file is given, it is assumed to be a prefix.
1367      *
1368      * This adjusts the EventTypeSet according to given cost types.
1369      * Returns the number of parts loaded
1370      */
1371     int load(QStringList files);
1372     int load(QString file);
1373     int load(QIODevice*, const QString&);
1374 
1375     /** returns true if something changed. These do NOT
1376      * invalidate the dynamic costs on a activation change,
1377      * i.e. all cost items depends on active parts.
1378      * This has to be done by the caller when true is returned by
1379      * calling invalidateDynamicCost().
1380      */
1381     bool activateParts(const TracePartList&);
1382     bool activateParts(TracePartList, bool active);
1383     bool activatePart(TracePart*, bool active);
1384     bool activateAll(bool active=true);
1385 
1386     // to be used by loader
1387     void addPart(TracePart*);
1388 
1389     TracePartList parts() const { return _parts; }
1390     TracePart* partWithName(const QString& name);
1391 
1392     // with path
1393     QString traceName() const { return _traceName; }
1394 
1395     // without path
1396     QString shortTraceName() const;
1397     QString activePartRange();
1398 
1399     EventTypeSet* eventTypes() { return &_eventTypes; }
1400 
1401     // memory pools
1402     FixPool* fixPool();
1403     DynPool* dynPool();
1404 
1405     // factories for object/file/class/function/line instances
1406     TraceObject* object(const QString& name);
1407     TraceFile* file(const QString& name);
1408     TraceClass* cls(const QString& fnName, QString& shortName);
1409     // function creation involves class creation if needed
1410     TraceFunction* function(const QString& name, TraceFile*, TraceObject*);
1411     // factory for function cycles
1412     TraceFunctionCycle* functionCycle(TraceFunction*);
1413 
1414     /**
1415      * Search for item with given name and highest subcost of given cost type.
1416      *
1417      * For some items, they will only be found if the parent cost is given:
1418      *  Instr, Line, Call  => need parent of type Function
1419      * For Function, a parent of type Obj/File/Class can be given, but
1420      * is not needed.
1421      */
1422     ProfileCostArray* search(ProfileContext::Type, QString,
1423                              EventType* ct = nullptr, ProfileCostArray* parent = nullptr);
1424 
1425     // for pretty function names without signature if unique...
1426     TraceFunctionMap::Iterator functionIterator(TraceFunction*);
1427     TraceFunctionMap::ConstIterator functionBeginIterator() const;
1428     TraceFunctionMap::ConstIterator functionEndIterator() const;
1429 
1430     TraceObjectMap& objectMap() { return _objectMap; }
1431     TraceFileMap& fileMap() { return _fileMap; }
1432     TraceClassMap& classMap() { return _classMap; }
1433     TraceFunctionMap& functionMap() { return _functionMap; }
1434 
1435     const TraceFunctionCycleList& functionCycles() { return _functionCycles; }
1436 
1437     ProfileCostArray* callMax() { return &_callMax; }
1438     SubCost maxCallCount() { return _maxCallCount; }
1439     void updateMaxCallCount(SubCost);
1440 
1441     void setCommand(const QString& command) { _command = command; }
1442     QString command() const { return _command; }
1443     void setArchitecture(Arch a) { _arch = a; }
1444     Arch architecture() const { return _arch; }
1445     ProfileCostArray* totals() { return &_totals; }
1446     void setMaxThreadID(int tid) { _maxThreadID = tid; }
1447     int maxThreadID() const { return _maxThreadID; }
1448     void setMaxPartNumber(int n) { _maxPartNumber = n; }
1449     int maxPartNumber() const { return _maxPartNumber; }
1450 
1451     // reset all manually set directories for source files
1452     void resetSourceDirs();
1453 
1454     void update() override;
1455 
1456     // invalidates all cost items dependent on active state of parts
1457     void invalidateDynamicCost();
1458 
1459     // cycle detection
1460     void updateFunctionCycles();
1461     void updateObjectCycles();
1462     void updateClassCycles();
1463     void updateFileCycles();
1464     bool inFunctionCycleUpdate() { return _inFunctionCycleUpdate; }
1465 
1466 private:
1467     void init();
1468     // add profile parts from one file
1469     int internalLoad(QIODevice* file, const QString& filename);
1470 
1471     // for notification callbacks
1472     Logger* _logger;
1473 
1474     TracePartList _parts;
1475 
1476     // The set for all costs
1477     EventTypeSet _eventTypes;
1478 
1479     FixPool* _fixPool;
1480     DynPool* _dynPool;
1481 
1482     // always the trace totals (not dependent on active parts)
1483     ProfileCostArray _totals;
1484     int _maxThreadID;
1485     int _maxPartNumber;
1486 
1487     TraceObjectMap _objectMap;
1488     TraceClassMap _classMap;
1489     TraceFileMap _fileMap;
1490     TraceFunctionMap _functionMap;
1491     QString _command;
1492     Arch _arch;
1493     QString _traceName;
1494 
1495     // Max of all costs of calls: This allows to see if the incl. cost can
1496     // be hidden for a cost type, as it is always the same as self cost
1497     ProfileCostArray _callMax;
1498     SubCost _maxCallCount;
1499 
1500     // cycles
1501     TraceFunctionCycleList _functionCycles;
1502     int _functionCycleCount;
1503     bool _inFunctionCycleUpdate;
1504 };
1505 
1506 
1507 
1508 #endif