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

kcachegrind

  • sources
  • kde-4.14
  • kdesdk
  • kcachegrind
  • libcore
coverage.cpp
Go to the documentation of this file.
1 /* This file is part of KCachegrind.
2  Copyright (C) 2002 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  * Function Coverage Analysis
21  */
22 
23 #include "coverage.h"
24 
25 //#define DEBUG_COVERAGE 1
26 
27 EventType* Coverage::_costType;
28 
29 const int Coverage::maxHistogramDepth = maxHistogramDepthValue;
30 const int Coverage::Rtti = 1;
31 
32 Coverage::Coverage()
33 {
34 }
35 
36 void Coverage::init()
37 {
38  _self = 0.0;
39  _incl = 0.0;
40  _callCount = 0.0;
41  // should always be overwritten before usage
42  _firstPercentage = 1.0;
43  _minDistance = 9999;
44  _maxDistance = 0;
45  _active = false;
46  _inRecursion = false;
47  for (int i = 0;i<maxHistogramDepth;i++) {
48  _selfHisto[i] = 0.0;
49  _inclHisto[i] = 0.0;
50  }
51 
52  _valid = true;
53 }
54 
55 int Coverage::inclusiveMedian()
56 {
57  double maxP = _inclHisto[0];
58  int medD = 0;
59  for (int i = 1;i<maxHistogramDepth;i++)
60  if (_inclHisto[i]>maxP) {
61  maxP = _inclHisto[i];
62  medD = i;
63  }
64 
65  return medD;
66 }
67 
68 int Coverage::selfMedian()
69 {
70  double maxP = _selfHisto[0];
71  int medD = 0;
72  for (int i = 1;i<maxHistogramDepth;i++)
73  if (_selfHisto[i]>maxP) {
74  maxP = _selfHisto[i];
75  medD = i;
76  }
77 
78  return medD;
79 }
80 
81 TraceFunctionList Coverage::coverage(TraceFunction* f, CoverageMode m,
82  EventType* ct)
83 {
84  invalidate(f->data(), Coverage::Rtti);
85 
86  _costType = ct;
87 
88  // function f takes ownership over c!
89  Coverage* c = new Coverage();
90  c->setFunction(f);
91  c->init();
92 
93  TraceFunctionList l;
94 
95  if (m == Caller)
96  c->addCallerCoverage(l, 1.0, 0);
97  else
98  c->addCallingCoverage(l, 1.0, 1.0, 0);
99 
100  return l;
101 }
102 
103 void Coverage::addCallerCoverage(TraceFunctionList& fList,
104  double pBack, int d)
105 {
106  if (_inRecursion) return;
107 
108  double incl;
109  incl = (double) (_function->inclusive()->subCost(_costType));
110 
111  if (_active) {
112 #ifdef DEBUG_COVERAGE
113  qDebug("CallerCov: D %d, %s (was active, incl %f, self %f): newP %f", d,
114  qPrintable(_function->prettyName()), _incl, _self, pBack);
115 #endif
116  _inRecursion = true;
117  }
118  else {
119  _active = true;
120 
121  // only add cost if this is no recursion
122 
123  _incl += pBack;
124  _firstPercentage = pBack;
125 
126  if (_minDistance > d) _minDistance = d;
127  if (_maxDistance < d) _maxDistance = d;
128  if (d<maxHistogramDepth) {
129  _inclHisto[d] += pBack;
130  }
131  else {
132  _inclHisto[maxHistogramDepth-1] += pBack;
133  }
134 
135 #ifdef DEBUG_COVERAGE
136  qDebug("CallerCov: D %d, %s (now active, new incl %f): newP %f",
137  d, qPrintable(_function->prettyName()), _incl, pBack);
138 #endif
139  }
140 
141  double callVal, pBackNew;
142 
143  foreach(TraceCall* call, _function->callers()) {
144  if (call->inCycle()>0) continue;
145  if (call->isRecursion()) continue;
146 
147  if (call->subCost(_costType)>0) {
148  TraceFunction* caller = call->caller();
149 
150  Coverage* c = (Coverage*) caller->association(rtti());
151  if (!c) {
152  c = new Coverage();
153  c->setFunction(caller);
154  }
155  if (!c->isValid()) {
156  c->init();
157  fList.append(caller);
158  }
159 
160  if (c->isActive()) continue;
161  if (c->inRecursion()) continue;
162 
163  callVal = (double) call->subCost(_costType);
164  pBackNew = pBack * (callVal / incl);
165 
166  // FIXME ?!?
167 
168  if (!c->isActive()) {
169  if (d>=0)
170  c->callCount() += (double)call->callCount();
171  else
172  c->callCount() += _callCount;
173  }
174  else {
175  // adjust pNew by sum of geometric series of recursion factor.
176  // Thus we can avoid endless recursion here
177  pBackNew *= 1.0 / (1.0 - pBackNew / c->firstPercentage());
178  }
179 
180  // Limit depth
181  if (pBackNew > 0.0001)
182  c->addCallerCoverage(fList, pBackNew, d+1);
183  }
184  }
185 
186  if (_inRecursion)
187  _inRecursion = false;
188  else if (_active)
189  _active = false;
190 }
191 
196 void Coverage::addCallingCoverage(TraceFunctionList& fList,
197  double pForward, double pBack, int d)
198 {
199  if (_inRecursion) return;
200 
201 #ifdef DEBUG_COVERAGE
202  static const char* spaces = " ";
203 #endif
204 
205  double self, incl;
206  incl = (double) (_function->inclusive()->subCost(_costType));
207 
208 #ifdef DEBUG_COVERAGE
209  qDebug("CngCov:%s - %s (incl %f, self %f): forward %f, back %f",
210  spaces+strlen(spaces)-d,
211  qPrintable(_function->prettyName()), _incl, _self, pForward, pBack);
212 #endif
213 
214 
215  if (_active) {
216  _inRecursion = true;
217 
218 #ifdef DEBUG_COVERAGE
219  qDebug("CngCov:%s < %s: STOP (is active)",
220  spaces+strlen(spaces)-d,
221  qPrintable(_function->prettyName()));
222 #endif
223 
224  }
225  else {
226  _active = true;
227 
228  // only add cost if this is no recursion
229  self = pForward * (_function->subCost(_costType)) / incl;
230  _incl += pForward;
231  _self += self;
232  _firstPercentage = pForward;
233 
234  if (_minDistance > d) _minDistance = d;
235  if (_maxDistance < d) _maxDistance = d;
236  if (d<maxHistogramDepth) {
237  _inclHisto[d] += pForward;
238  _selfHisto[d] += self;
239  }
240  else {
241  _inclHisto[maxHistogramDepth-1] += pForward;
242  _selfHisto[maxHistogramDepth-1] += self;
243  }
244 
245 #ifdef DEBUG_COVERAGE
246  qDebug("CngCov:%s < %s (incl %f, self %f)",
247  spaces+strlen(spaces)-d,
248  qPrintable(_function->prettyName()), _incl, _self);
249 #endif
250  }
251 
252  double callVal, pForwardNew, pBackNew;
253 
254  foreach(TraceCall* call, _function->callings()) {
255  if (call->inCycle()>0) continue;
256  if (call->isRecursion()) continue;
257 
258  if (call->subCost(_costType)>0) {
259  TraceFunction* calling = call->called();
260 
261  Coverage* c = (Coverage*) calling->association(rtti());
262  if (!c) {
263  c = new Coverage();
264  c->setFunction(calling);
265  }
266  if (!c->isValid()) {
267  c->init();
268  fList.append(calling);
269  }
270 
271  if (c->isActive()) continue;
272  if (c->inRecursion()) continue;
273 
274  callVal = (double) call->subCost(_costType);
275  pForwardNew = pForward * (callVal / incl);
276  pBackNew = pBack * (callVal /
277  calling->inclusive()->subCost(_costType));
278 
279  if (!c->isActive()) {
280  c->callCount() += pBack * call->callCount();
281 
282 #ifdef DEBUG_COVERAGE
283  qDebug("CngCov:%s > %s: forward %f, back %f, calls %f -> %f, now %f",
284  spaces+strlen(spaces)-d,
285  qPrintable(calling->prettyName()),
286  pForwardNew, pBackNew,
287  (double)call->callCount(),
288  pBack * call->callCount(),
289  c->callCount());
290 #endif
291  }
292  else {
293  // adjust pNew by sum of geometric series of recursion factor.
294  // Thus we can avoid endless recursion here
295  double fFactor = 1.0 / (1.0 - pForwardNew / c->firstPercentage());
296  double bFactor = 1.0 / (1.0 - pBackNew);
297 #ifdef DEBUG_COVERAGE
298  qDebug("CngCov:%s Recursion - origP %f, actP %f => factor %f, newP %f",
299  spaces+strlen(spaces)-d,
300  c->firstPercentage(), pForwardNew,
301  fFactor, pForwardNew * fFactor);
302 #endif
303  pForwardNew *= fFactor;
304  pBackNew *= bFactor;
305 
306  }
307 
308  // Limit depth
309  if (pForwardNew > 0.0001)
310  c->addCallingCoverage(fList, pForwardNew, pBackNew, d+1);
311  }
312  }
313 
314  if (_inRecursion)
315  _inRecursion = false;
316  else if (_active)
317  _active = false;
318 }
319 
Coverage::inclusiveMedian
int inclusiveMedian()
Definition: coverage.cpp:55
TraceCall::isRecursion
bool isRecursion()
Definition: tracedata.h:844
ProfileCostArray::subCost
SubCost subCost(EventType *)
Returns a sub cost.
Definition: costitem.cpp:591
Coverage::rtti
virtual int rtti()
Definition: coverage.h:50
Coverage::coverage
static TraceFunctionList coverage(TraceFunction *f, CoverageMode m, EventType *ct)
Calculate coverage of all functions based on function f.
Definition: coverage.cpp:81
TraceFunction::callings
const TraceCallList & callings(bool skipCycle=false) const
Definition: tracedata.cpp:2302
TraceCall::caller
TraceFunction * caller(bool skipCycle=false) const
Definition: tracedata.cpp:1230
TraceFunction
A traced function.
Definition: tracedata.h:1122
TraceCallCost::callCount
SubCost callCount()
Definition: tracedata.cpp:125
Coverage::callCount
double & callCount()
Definition: coverage.h:57
Coverage::maxHistogramDepth
static const int maxHistogramDepth
Definition: coverage.h:44
TraceFunction::callers
TraceCallList callers(bool skipCycle=false) const
Definition: tracedata.cpp:2278
EventType
A cost type, e.g.
Definition: eventtype.h:43
Coverage::init
void init()
Definition: coverage.cpp:36
Coverage::Caller
Definition: coverage.h:40
TraceFunction::association
TraceAssociation * association(int rtti)
Definition: tracedata.cpp:1862
TraceAssociation::_valid
bool _valid
Definition: tracedata.h:1110
QList::append
void append(const T &value)
Coverage
Coverage of a function.
Definition: coverage.h:36
maxHistogramDepthValue
#define maxHistogramDepthValue
Definition: coverage.h:43
Coverage::CoverageMode
CoverageMode
Definition: coverage.h:40
Coverage::selfMedian
int selfMedian()
Definition: coverage.cpp:68
TraceAssociation::invalidate
void invalidate()
Definition: tracedata.h:1093
coverage.h
TraceFunction::prettyName
QString prettyName() const
Similar to name, but prettyfied = more descriptive to humans.
Definition: tracedata.cpp:1889
CostItem::data
virtual TraceData * data()
Definition: costitem.cpp:111
Coverage::Rtti
static const int Rtti
Definition: coverage.h:46
QList
TraceCall::inCycle
int inCycle()
Definition: tracedata.cpp:1202
TraceAssociation::setFunction
bool setFunction(TraceFunction *)
reset function to associate this object to.
Definition: tracedata.cpp:1756
Coverage::firstPercentage
double firstPercentage()
Definition: coverage.h:56
TraceCall::called
TraceFunction * called(bool skipCycle=false) const
Definition: tracedata.cpp:1235
Coverage::inRecursion
bool inRecursion()
Definition: coverage.h:65
Coverage::isActive
bool isActive()
Definition: coverage.h:64
Coverage::Coverage
Coverage()
Definition: coverage.cpp:32
TraceCall
A call from one to another function.
Definition: tracedata.h:835
TraceAssociation::_function
TraceFunction * _function
Definition: tracedata.h:1109
TraceAssociation::isValid
bool isValid()
Definition: tracedata.h:1094
TraceInclusiveCost::inclusive
ProfileCostArray * inclusive()
Definition: tracedata.cpp:163
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:39:50 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
  • 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