2 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "BasicProfileResult.h"
18 #include "ProfiledEntity.h"
26 inline bool operator<(const HitSymbol
& other
) const
28 return hits
> other
.hits
;
33 // #pragma mark - BasicImageProfileResult
36 BasicImageProfileResult::BasicImageProfileResult(SharedImage
* image
,
39 ImageProfileResult(image
, id
),
46 BasicImageProfileResult::~BasicImageProfileResult()
52 BasicImageProfileResult::Init()
54 int32 symbolCount
= fImage
->SymbolCount();
55 fSymbolHits
= new(std::nothrow
) int64
[symbolCount
];
56 if (fSymbolHits
== NULL
)
59 memset(fSymbolHits
, 0, 8 * symbolCount
);
66 BasicImageProfileResult::AddHit(addr_t address
)
68 int32 symbolIndex
= fImage
->FindSymbol(address
);
72 fSymbolHits
[symbolIndex
]++;
80 BasicImageProfileResult::AddUnknownHit()
88 BasicImageProfileResult::AddSymbolHit(int32 symbolIndex
)
90 fSymbolHits
[symbolIndex
]++;
95 BasicImageProfileResult::AddImageHit()
102 BasicImageProfileResult::SymbolHits() const
109 BasicImageProfileResult::UnknownHits() const
115 // #pragma mark - BasicProfileResult
118 BasicProfileResult::BasicProfileResult()
129 BasicProfileResult::AddDroppedTicks(int32 dropped
)
131 fDroppedTicks
+= dropped
;
136 BasicProfileResult::PrintResults(ImageProfileResultContainer
* container
)
139 BasicImageProfileResult
* images
[container
->CountImages()];
140 int32 imageCount
= GetHitImages(container
, images
);
143 int32 symbolCount
= 0;
144 for (int32 k
= 0; k
< imageCount
; k
++) {
145 BasicImageProfileResult
* image
= images
[k
];
146 if (image
->TotalHits() > image
->UnknownHits())
147 symbolCount
+= image
->GetImage()->SymbolCount();
150 // find and sort the hit symbols
151 HitSymbol hitSymbols
[symbolCount
];
152 int32 hitSymbolCount
= 0;
154 for (int32 k
= 0; k
< imageCount
; k
++) {
155 BasicImageProfileResult
* image
= images
[k
];
156 if (image
->TotalHits() > image
->UnknownHits()) {
157 Symbol
** symbols
= image
->GetImage()->Symbols();
158 const int64
* symbolHits
= image
->SymbolHits();
159 int32 imageSymbolCount
= image
->GetImage()->SymbolCount();
160 for (int32 i
= 0; i
< imageSymbolCount
; i
++) {
161 if (symbolHits
[i
] > 0) {
162 HitSymbol
& hitSymbol
= hitSymbols
[hitSymbolCount
++];
163 hitSymbol
.hits
= symbolHits
[i
];
164 hitSymbol
.symbol
= symbols
[i
];
165 hitSymbol
.imageID
= image
->ID();
171 if (hitSymbolCount
> 1)
172 std::sort(hitSymbols
, hitSymbols
+ hitSymbolCount
);
174 int64 totalTicks
= fTotalTicks
;
175 fprintf(gOptions
.output
, "\nprofiling results for %s \"%s\" "
176 "(%" B_PRId32
"):\n", fEntity
->EntityType(), fEntity
->EntityName(),
177 fEntity
->EntityID());
178 fprintf(gOptions
.output
, " tick interval: %lld us\n", fInterval
);
179 fprintf(gOptions
.output
, " total ticks: %lld (%lld us)\n",
180 totalTicks
, totalTicks
* fInterval
);
183 fprintf(gOptions
.output
, " unknown ticks: %lld (%lld us, %6.2f%%)\n",
184 fUnkownTicks
, fUnkownTicks
* fInterval
,
185 100.0 * fUnkownTicks
/ totalTicks
);
186 fprintf(gOptions
.output
, " dropped ticks: %lld (%lld us, %6.2f%%)\n",
187 fDroppedTicks
, fDroppedTicks
* fInterval
,
188 100.0 * fDroppedTicks
/ totalTicks
);
189 if (gOptions
.analyze_full_stack
) {
190 fprintf(gOptions
.output
, " samples/tick: %.1f\n",
191 (double)fTotalSampleCount
/ totalTicks
);
194 if (imageCount
> 0) {
195 fprintf(gOptions
.output
, "\n");
196 fprintf(gOptions
.output
, " hits unknown image\n");
197 fprintf(gOptions
.output
, " ---------------------------------------"
198 "---------------------------------------\n");
199 for (int32 k
= 0; k
< imageCount
; k
++) {
200 BasicImageProfileResult
* image
= images
[k
];
201 fprintf(gOptions
.output
, " %10lld %10lld %7ld %s\n",
202 image
->TotalHits(), image
->UnknownHits(),
203 image
->ID(), image
->GetImage()->Name());
207 if (hitSymbolCount
> 0) {
208 fprintf(gOptions
.output
, "\n");
209 fprintf(gOptions
.output
, " hits in us in %% "
211 fprintf(gOptions
.output
, " ---------------------------------------"
212 "---------------------------------------\n");
213 for (int32 i
= 0; i
< hitSymbolCount
; i
++) {
214 const HitSymbol
& hitSymbol
= hitSymbols
[i
];
215 const Symbol
* symbol
= hitSymbol
.symbol
;
218 const char* symbolName
= __cxxabiv1::__cxa_demangle(symbol
->Name(),
219 NULL
, NULL
, &status
);
220 if (symbolName
== NULL
)
221 symbolName
= symbol
->Name();
223 const char* symbolName
= symbol
->Name();
225 fprintf(gOptions
.output
, " %10lld %10lld %6.2f %6ld %s\n",
226 hitSymbol
.hits
, hitSymbol
.hits
* fInterval
,
227 100.0 * hitSymbol
.hits
/ totalTicks
, hitSymbol
.imageID
,
231 free(const_cast<char*>(symbolName
));
235 fprintf(gOptions
.output
, " no functions were hit\n");
240 BasicProfileResult::GetImageProfileResult(SharedImage
* image
, image_id id
,
241 ImageProfileResult
*& _imageResult
)
243 BasicImageProfileResult
* result
244 = new(std::nothrow
) BasicImageProfileResult(image
, id
);
248 status_t error
= result
->Init();
254 _imageResult
= result
;
259 // #pragma mark - InclusiveProfileResult
263 InclusiveProfileResult::AddSamples(ImageProfileResultContainer
* container
,
264 addr_t
* samples
, int32 sampleCount
)
266 // Sort the samples. This way hits of the same symbol are
267 // successive and we can avoid incrementing the hit count of the
268 // same symbol twice. Same for images.
269 std::sort(samples
, samples
+ sampleCount
);
271 int32 unknownSamples
= 0;
272 BasicImageProfileResult
* previousImage
= NULL
;
273 int32 previousSymbol
= -1;
275 for (int32 i
= 0; i
< sampleCount
; i
++) {
276 addr_t address
= samples
[i
];
278 BasicImageProfileResult
* image
= static_cast<BasicImageProfileResult
*>(
279 container
->FindImage(address
, loadDelta
));
282 symbol
= image
->GetImage()->FindSymbol(address
- loadDelta
);
284 // TODO: Count unknown image hits?
285 } else if (image
!= previousImage
|| symbol
!= previousSymbol
)
286 image
->AddSymbolHit(symbol
);
288 if (image
!= previousImage
)
289 image
->AddImageHit();
293 previousImage
= image
;
294 previousSymbol
= symbol
;
297 if (unknownSamples
== sampleCount
)
301 fTotalSampleCount
+= sampleCount
;
305 // #pragma mark - ExclusiveProfileResult
309 ExclusiveProfileResult::AddSamples(ImageProfileResultContainer
* container
,
310 addr_t
* samples
, int32 sampleCount
)
312 BasicImageProfileResult
* image
= NULL
;
313 // the image in which we hit a symbol
314 BasicImageProfileResult
* firstImage
= NULL
;
315 // the first image we hit, != image if no symbol was hit
317 for (int32 k
= 0; k
< sampleCount
; k
++) {
318 addr_t address
= samples
[k
];
320 image
= static_cast<BasicImageProfileResult
*>(
321 container
->FindImage(address
, loadDelta
));
323 if (image
->AddHit(address
- loadDelta
))
325 if (firstImage
== NULL
)
331 if (firstImage
!= NULL
)
332 firstImage
->AddUnknownHit();
338 fTotalSampleCount
+= sampleCount
;