More refactoring:
* Renamed *ProfileResultImage to *ImageProfileResult.
* Separated the image result management from the *ProfileResult classes:
- The general per-thread image management functionality does now live in
Thread.
- Introduced interface ImageProfileResultContainer which is implemented by
Thread. An instance is passed to ProfileResult::AddSamples()/PrintResult().
* Made *ProfileResultImage independent of Image. The dependency is now to
SharedImage only.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35556 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -27,25 +27,26 @@ struct HitSymbol {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - BasicProfileResultImage
|
// #pragma mark - BasicImageProfileResult
|
||||||
|
|
||||||
|
|
||||||
BasicProfileResultImage::BasicProfileResultImage(Image* image)
|
BasicImageProfileResult::BasicImageProfileResult(SharedImage* image,
|
||||||
|
image_id id)
|
||||||
:
|
:
|
||||||
ProfileResultImage(image),
|
ImageProfileResult(image, id),
|
||||||
fSymbolHits(NULL),
|
fSymbolHits(NULL),
|
||||||
fUnknownHits(0)
|
fUnknownHits(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicProfileResultImage::~BasicProfileResultImage()
|
BasicImageProfileResult::~BasicImageProfileResult()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BasicProfileResultImage::Init()
|
BasicImageProfileResult::Init()
|
||||||
{
|
{
|
||||||
int32 symbolCount = fImage->SymbolCount();
|
int32 symbolCount = fImage->SymbolCount();
|
||||||
fSymbolHits = new(std::nothrow) int64[symbolCount];
|
fSymbolHits = new(std::nothrow) int64[symbolCount];
|
||||||
@@ -59,7 +60,7 @@ BasicProfileResultImage::Init()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BasicProfileResultImage::AddHit(addr_t address)
|
BasicImageProfileResult::AddHit(addr_t address)
|
||||||
{
|
{
|
||||||
int32 symbolIndex = fImage->FindSymbol(address);
|
int32 symbolIndex = fImage->FindSymbol(address);
|
||||||
if (symbolIndex < 0)
|
if (symbolIndex < 0)
|
||||||
@@ -73,7 +74,7 @@ BasicProfileResultImage::AddHit(addr_t address)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicProfileResultImage::AddUnknownHit()
|
BasicImageProfileResult::AddUnknownHit()
|
||||||
{
|
{
|
||||||
fUnknownHits++;
|
fUnknownHits++;
|
||||||
fTotalHits++;
|
fTotalHits++;
|
||||||
@@ -81,28 +82,28 @@ BasicProfileResultImage::AddUnknownHit()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicProfileResultImage::AddSymbolHit(int32 symbolIndex)
|
BasicImageProfileResult::AddSymbolHit(int32 symbolIndex)
|
||||||
{
|
{
|
||||||
fSymbolHits[symbolIndex]++;
|
fSymbolHits[symbolIndex]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicProfileResultImage::AddImageHit()
|
BasicImageProfileResult::AddImageHit()
|
||||||
{
|
{
|
||||||
fTotalHits++;
|
fTotalHits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int64*
|
const int64*
|
||||||
BasicProfileResultImage::SymbolHits() const
|
BasicImageProfileResult::SymbolHits() const
|
||||||
{
|
{
|
||||||
return fSymbolHits;
|
return fSymbolHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
BasicProfileResultImage::UnknownHits() const
|
BasicImageProfileResult::UnknownHits() const
|
||||||
{
|
{
|
||||||
return fUnknownHits;
|
return fUnknownHits;
|
||||||
}
|
}
|
||||||
@@ -129,16 +130,16 @@ BasicProfileResult::AddDroppedTicks(int32 dropped)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicProfileResult::PrintResults()
|
BasicProfileResult::PrintResults(ImageProfileResultContainer* container)
|
||||||
{
|
{
|
||||||
// get hit images
|
// get hit images
|
||||||
BasicProfileResultImage* images[fOldImages.Count() + fImages.Count()];
|
BasicImageProfileResult* images[container->CountImages()];
|
||||||
int32 imageCount = GetHitImages(images);
|
int32 imageCount = GetHitImages(container, images);
|
||||||
|
|
||||||
// count symbols
|
// count symbols
|
||||||
int32 symbolCount = 0;
|
int32 symbolCount = 0;
|
||||||
for (int32 k = 0; k < imageCount; k++) {
|
for (int32 k = 0; k < imageCount; k++) {
|
||||||
BasicProfileResultImage* image = images[k];
|
BasicImageProfileResult* image = images[k];
|
||||||
if (image->TotalHits() > image->UnknownHits())
|
if (image->TotalHits() > image->UnknownHits())
|
||||||
symbolCount += image->GetImage()->SymbolCount();
|
symbolCount += image->GetImage()->SymbolCount();
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,7 @@ BasicProfileResult::PrintResults()
|
|||||||
int32 hitSymbolCount = 0;
|
int32 hitSymbolCount = 0;
|
||||||
|
|
||||||
for (int32 k = 0; k < imageCount; k++) {
|
for (int32 k = 0; k < imageCount; k++) {
|
||||||
BasicProfileResultImage* image = images[k];
|
BasicImageProfileResult* image = images[k];
|
||||||
if (image->TotalHits() > image->UnknownHits()) {
|
if (image->TotalHits() > image->UnknownHits()) {
|
||||||
Symbol** symbols = image->GetImage()->Symbols();
|
Symbol** symbols = image->GetImage()->Symbols();
|
||||||
const int64* symbolHits = image->SymbolHits();
|
const int64* symbolHits = image->SymbolHits();
|
||||||
@@ -193,10 +194,10 @@ BasicProfileResult::PrintResults()
|
|||||||
fprintf(gOptions.output, " ---------------------------------------"
|
fprintf(gOptions.output, " ---------------------------------------"
|
||||||
"---------------------------------------\n");
|
"---------------------------------------\n");
|
||||||
for (int32 k = 0; k < imageCount; k++) {
|
for (int32 k = 0; k < imageCount; k++) {
|
||||||
BasicProfileResultImage* image = images[k];
|
BasicImageProfileResult* image = images[k];
|
||||||
fprintf(gOptions.output, " %10lld %10lld %7ld %s\n",
|
fprintf(gOptions.output, " %10lld %10lld %7ld %s\n",
|
||||||
image->TotalHits(), image->UnknownHits(),
|
image->TotalHits(), image->UnknownHits(),
|
||||||
image->GetImage()->ID(), image->GetImage()->Name());
|
image->ID(), image->GetImage()->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,10 +220,10 @@ BasicProfileResult::PrintResults()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicProfileResultImage*
|
ImageProfileResult*
|
||||||
BasicProfileResult::CreateProfileResultImage(Image* image)
|
BasicProfileResult::CreateImageProfileResult(SharedImage* image, image_id id)
|
||||||
{
|
{
|
||||||
return new(std::nothrow) BasicProfileResultImage(image);
|
return new(std::nothrow) BasicImageProfileResult(image, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,7 +231,8 @@ BasicProfileResult::CreateProfileResultImage(Image* image)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
InclusiveProfileResult::AddSamples(ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount)
|
||||||
{
|
{
|
||||||
// Sort the samples. This way hits of the same symbol are
|
// Sort the samples. This way hits of the same symbol are
|
||||||
// successive and we can avoid incrementing the hit count of the
|
// successive and we can avoid incrementing the hit count of the
|
||||||
@@ -238,15 +240,17 @@ InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
|||||||
std::sort(samples, samples + sampleCount);
|
std::sort(samples, samples + sampleCount);
|
||||||
|
|
||||||
int32 unknownSamples = 0;
|
int32 unknownSamples = 0;
|
||||||
BasicProfileResultImage* previousImage = NULL;
|
BasicImageProfileResult* previousImage = NULL;
|
||||||
int32 previousSymbol = -1;
|
int32 previousSymbol = -1;
|
||||||
|
|
||||||
for (int32 i = 0; i < sampleCount; i++) {
|
for (int32 i = 0; i < sampleCount; i++) {
|
||||||
addr_t address = samples[i];
|
addr_t address = samples[i];
|
||||||
BasicProfileResultImage* image = FindImage(address);
|
addr_t loadDelta;
|
||||||
|
BasicImageProfileResult* image = static_cast<BasicImageProfileResult*>(
|
||||||
|
container->FindImage(address, loadDelta));
|
||||||
int32 symbol = -1;
|
int32 symbol = -1;
|
||||||
if (image != NULL) {
|
if (image != NULL) {
|
||||||
symbol = image->GetImage()->FindSymbol(address);
|
symbol = image->GetImage()->FindSymbol(address - loadDelta);
|
||||||
if (symbol < 0) {
|
if (symbol < 0) {
|
||||||
// TODO: Count unknown image hits?
|
// TODO: Count unknown image hits?
|
||||||
} else if (image != previousImage || symbol != previousSymbol)
|
} else if (image != previousImage || symbol != previousSymbol)
|
||||||
@@ -273,18 +277,21 @@ InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
ExclusiveProfileResult::AddSamples(ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount)
|
||||||
{
|
{
|
||||||
BasicProfileResultImage* image = NULL;
|
BasicImageProfileResult* image = NULL;
|
||||||
// the image in which we hit a symbol
|
// the image in which we hit a symbol
|
||||||
BasicProfileResultImage* firstImage = NULL;
|
BasicImageProfileResult* firstImage = NULL;
|
||||||
// the first image we hit, != image if no symbol was hit
|
// the first image we hit, != image if no symbol was hit
|
||||||
|
|
||||||
for (int32 k = 0; k < sampleCount; k++) {
|
for (int32 k = 0; k < sampleCount; k++) {
|
||||||
addr_t address = samples[k];
|
addr_t address = samples[k];
|
||||||
image = FindImage(address);
|
addr_t loadDelta;
|
||||||
|
image = static_cast<BasicImageProfileResult*>(
|
||||||
|
container->FindImage(address, loadDelta));
|
||||||
if (image != NULL) {
|
if (image != NULL) {
|
||||||
if (image->AddHit(address))
|
if (image->AddHit(address - loadDelta))
|
||||||
break;
|
break;
|
||||||
if (firstImage == NULL)
|
if (firstImage == NULL)
|
||||||
firstImage = image;
|
firstImage = image;
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
#include "ProfileResult.h"
|
#include "ProfileResult.h"
|
||||||
|
|
||||||
|
|
||||||
class BasicProfileResultImage : public ProfileResultImage,
|
class BasicImageProfileResult : public ImageProfileResult,
|
||||||
public DoublyLinkedListLinkImpl<BasicProfileResultImage> {
|
public DoublyLinkedListLinkImpl<BasicImageProfileResult> {
|
||||||
public:
|
public:
|
||||||
BasicProfileResultImage(Image* image);
|
BasicImageProfileResult(SharedImage* image,
|
||||||
virtual ~BasicProfileResultImage();
|
image_id id);
|
||||||
|
virtual ~BasicImageProfileResult();
|
||||||
|
|
||||||
virtual status_t Init();
|
virtual status_t Init();
|
||||||
|
|
||||||
@@ -31,15 +32,16 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BasicProfileResult
|
class BasicProfileResult : public ProfileResult {
|
||||||
: public AbstractProfileResult<BasicProfileResultImage> {
|
|
||||||
public:
|
public:
|
||||||
BasicProfileResult();
|
BasicProfileResult();
|
||||||
|
|
||||||
virtual void AddDroppedTicks(int32 dropped);
|
virtual void AddDroppedTicks(int32 dropped);
|
||||||
virtual void PrintResults();
|
virtual void PrintResults(
|
||||||
|
ImageProfileResultContainer* container);
|
||||||
|
|
||||||
virtual BasicProfileResultImage* CreateProfileResultImage(Image* image);
|
virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
|
||||||
|
image_id id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int64 fTotalTicks;
|
int64 fTotalTicks;
|
||||||
@@ -51,15 +53,17 @@ protected:
|
|||||||
|
|
||||||
class InclusiveProfileResult : public BasicProfileResult {
|
class InclusiveProfileResult : public BasicProfileResult {
|
||||||
public:
|
public:
|
||||||
virtual void AddSamples(addr_t* samples,
|
virtual void AddSamples(
|
||||||
int32 sampleCount);
|
ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ExclusiveProfileResult : public BasicProfileResult {
|
class ExclusiveProfileResult : public BasicProfileResult {
|
||||||
public:
|
public:
|
||||||
virtual void AddSamples(addr_t* samples,
|
virtual void AddSamples(
|
||||||
int32 sampleCount);
|
ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, Ingo Weinhold, [email protected].
|
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,19 +16,20 @@
|
|||||||
#include "ProfiledEntity.h"
|
#include "ProfiledEntity.h"
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - CallgrindProfileResultImage
|
// #pragma mark - CallgrindImageProfileResult
|
||||||
|
|
||||||
|
|
||||||
CallgrindProfileResultImage::CallgrindProfileResultImage(Image* image)
|
CallgrindImageProfileResult::CallgrindImageProfileResult(SharedImage* image,
|
||||||
|
image_id id)
|
||||||
:
|
:
|
||||||
ProfileResultImage(image),
|
ImageProfileResult(image, id),
|
||||||
fFunctions(NULL),
|
fFunctions(NULL),
|
||||||
fOutputIndex(0)
|
fOutputIndex(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CallgrindProfileResultImage::~CallgrindProfileResultImage()
|
CallgrindImageProfileResult::~CallgrindImageProfileResult()
|
||||||
{
|
{
|
||||||
int32 symbolCount = fImage->SymbolCount();
|
int32 symbolCount = fImage->SymbolCount();
|
||||||
for (int32 i = 0; i < symbolCount; i++) {
|
for (int32 i = 0; i < symbolCount; i++) {
|
||||||
@@ -44,7 +45,7 @@ CallgrindProfileResultImage::~CallgrindProfileResultImage()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
CallgrindProfileResultImage::Init()
|
CallgrindImageProfileResult::Init()
|
||||||
{
|
{
|
||||||
int32 symbolCount = fImage->SymbolCount();
|
int32 symbolCount = fImage->SymbolCount();
|
||||||
fFunctions = new(std::nothrow) CallgrindFunction[symbolCount];
|
fFunctions = new(std::nothrow) CallgrindFunction[symbolCount];
|
||||||
@@ -58,8 +59,8 @@ CallgrindProfileResultImage::Init()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex,
|
CallgrindImageProfileResult::AddSymbolHit(int32 symbolIndex,
|
||||||
CallgrindProfileResultImage* calledImage, int32 calledSymbol)
|
CallgrindImageProfileResult* calledImage, int32 calledSymbol)
|
||||||
|
|
||||||
{
|
{
|
||||||
fTotalHits++;
|
fTotalHits++;
|
||||||
@@ -94,21 +95,21 @@ CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex,
|
|||||||
|
|
||||||
|
|
||||||
CallgrindFunction*
|
CallgrindFunction*
|
||||||
CallgrindProfileResultImage::Functions() const
|
CallgrindImageProfileResult::Functions() const
|
||||||
{
|
{
|
||||||
return fFunctions;
|
return fFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
CallgrindProfileResultImage::OutputIndex() const
|
CallgrindImageProfileResult::OutputIndex() const
|
||||||
{
|
{
|
||||||
return fOutputIndex;
|
return fOutputIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallgrindProfileResultImage::SetOutputIndex(int32 index)
|
CallgrindImageProfileResult::SetOutputIndex(int32 index)
|
||||||
{
|
{
|
||||||
fOutputIndex = index;
|
fOutputIndex = index;
|
||||||
}
|
}
|
||||||
@@ -129,19 +130,23 @@ CallgrindProfileResult::CallgrindProfileResult()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallgrindProfileResult::AddSamples(addr_t* samples, int32 sampleCount)
|
CallgrindProfileResult::AddSamples(ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount)
|
||||||
{
|
{
|
||||||
int32 unknownSamples = 0;
|
int32 unknownSamples = 0;
|
||||||
CallgrindProfileResultImage* previousImage = NULL;
|
CallgrindImageProfileResult* previousImage = NULL;
|
||||||
int32 previousSymbol = -1;
|
int32 previousSymbol = -1;
|
||||||
|
|
||||||
// TODO: That probably doesn't work with recursive functions.
|
// TODO: That probably doesn't work with recursive functions.
|
||||||
for (int32 i = 0; i < sampleCount; i++) {
|
for (int32 i = 0; i < sampleCount; i++) {
|
||||||
addr_t address = samples[i];
|
addr_t address = samples[i];
|
||||||
CallgrindProfileResultImage* image = FindImage(address);
|
addr_t loadDelta;
|
||||||
|
CallgrindImageProfileResult* image
|
||||||
|
= static_cast<CallgrindImageProfileResult*>(
|
||||||
|
container->FindImage(address, loadDelta));
|
||||||
int32 symbol = -1;
|
int32 symbol = -1;
|
||||||
if (image != NULL) {
|
if (image != NULL) {
|
||||||
symbol = image->GetImage()->FindSymbol(address);
|
symbol = image->GetImage()->FindSymbol(address - loadDelta);
|
||||||
if (symbol >= 0) {
|
if (symbol >= 0) {
|
||||||
image->AddSymbolHit(symbol, previousImage, previousSymbol);
|
image->AddSymbolHit(symbol, previousImage, previousSymbol);
|
||||||
previousImage = image;
|
previousImage = image;
|
||||||
@@ -166,7 +171,7 @@ CallgrindProfileResult::AddDroppedTicks(int32 dropped)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallgrindProfileResult::PrintResults()
|
CallgrindProfileResult::PrintResults(ImageProfileResultContainer* container)
|
||||||
{
|
{
|
||||||
// create output file
|
// create output file
|
||||||
|
|
||||||
@@ -206,11 +211,11 @@ CallgrindProfileResult::PrintResults()
|
|||||||
fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval);
|
fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval);
|
||||||
|
|
||||||
// get hit images
|
// get hit images
|
||||||
CallgrindProfileResultImage* images[fOldImages.Count() + fImages.Count()];
|
CallgrindImageProfileResult* images[container->CountImages()];
|
||||||
int32 imageCount = GetHitImages(images);
|
int32 imageCount = GetHitImages(container, images);
|
||||||
|
|
||||||
for (int32 i = 0; i < imageCount; i++) {
|
for (int32 i = 0; i < imageCount; i++) {
|
||||||
CallgrindProfileResultImage* image = images[i];
|
CallgrindImageProfileResult* image = images[i];
|
||||||
|
|
||||||
CallgrindFunction* functions = image->Functions();
|
CallgrindFunction* functions = image->Functions();
|
||||||
int32 imageSymbolCount = image->GetImage()->SymbolCount();
|
int32 imageSymbolCount = image->GetImage()->SymbolCount();
|
||||||
@@ -257,16 +262,17 @@ CallgrindProfileResult::PrintResults()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CallgrindProfileResultImage*
|
ImageProfileResult*
|
||||||
CallgrindProfileResult::CreateProfileResultImage(Image* image)
|
CallgrindProfileResult::CreateImageProfileResult(SharedImage* image,
|
||||||
|
image_id id)
|
||||||
{
|
{
|
||||||
return new(std::nothrow) CallgrindProfileResultImage(image);
|
return new(std::nothrow) CallgrindImageProfileResult(image, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CallgrindProfileResult::_PrintFunction(FILE* out,
|
CallgrindProfileResult::_PrintFunction(FILE* out,
|
||||||
CallgrindProfileResultImage* image, int32 functionIndex, bool called)
|
CallgrindImageProfileResult* image, int32 functionIndex, bool called)
|
||||||
{
|
{
|
||||||
if (image->OutputIndex() == 0) {
|
if (image->OutputIndex() == 0) {
|
||||||
// need to print the image name
|
// need to print the image name
|
||||||
|
|||||||
@@ -11,16 +11,16 @@
|
|||||||
#include "ProfileResult.h"
|
#include "ProfileResult.h"
|
||||||
|
|
||||||
|
|
||||||
class CallgrindProfileResultImage;
|
class CallgrindImageProfileResult;
|
||||||
|
|
||||||
|
|
||||||
struct CallgrindCalledFunction {
|
struct CallgrindCalledFunction {
|
||||||
CallgrindCalledFunction* next;
|
CallgrindCalledFunction* next;
|
||||||
CallgrindProfileResultImage* image;
|
CallgrindImageProfileResult* image;
|
||||||
int32 function;
|
int32 function;
|
||||||
int64 hits;
|
int64 hits;
|
||||||
|
|
||||||
CallgrindCalledFunction(CallgrindProfileResultImage* image, int32 function)
|
CallgrindCalledFunction(CallgrindImageProfileResult* image, int32 function)
|
||||||
:
|
:
|
||||||
next(NULL),
|
next(NULL),
|
||||||
image(image),
|
image(image),
|
||||||
@@ -39,16 +39,17 @@ struct CallgrindFunction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CallgrindProfileResultImage : public ProfileResultImage,
|
class CallgrindImageProfileResult : public ImageProfileResult,
|
||||||
public DoublyLinkedListLinkImpl<CallgrindProfileResultImage> {
|
public DoublyLinkedListLinkImpl<CallgrindImageProfileResult> {
|
||||||
public:
|
public:
|
||||||
CallgrindProfileResultImage(Image* image);
|
CallgrindImageProfileResult(SharedImage* image,
|
||||||
virtual ~CallgrindProfileResultImage();
|
image_id id);
|
||||||
|
virtual ~CallgrindImageProfileResult();
|
||||||
|
|
||||||
virtual status_t Init();
|
virtual status_t Init();
|
||||||
|
|
||||||
inline void AddSymbolHit(int32 symbolIndex,
|
inline void AddSymbolHit(int32 symbolIndex,
|
||||||
CallgrindProfileResultImage* calledImage,
|
CallgrindImageProfileResult* calledImage,
|
||||||
int32 calledSymbol);
|
int32 calledSymbol);
|
||||||
|
|
||||||
inline CallgrindFunction* Functions() const;
|
inline CallgrindFunction* Functions() const;
|
||||||
@@ -62,21 +63,23 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CallgrindProfileResult
|
class CallgrindProfileResult : public ProfileResult {
|
||||||
: public AbstractProfileResult<CallgrindProfileResultImage> {
|
|
||||||
public:
|
public:
|
||||||
CallgrindProfileResult();
|
CallgrindProfileResult();
|
||||||
|
|
||||||
virtual void AddSamples(addr_t* samples,
|
virtual void AddSamples(
|
||||||
int32 sampleCount);
|
ImageProfileResultContainer* container,
|
||||||
|
addr_t* samples, int32 sampleCount);
|
||||||
virtual void AddDroppedTicks(int32 dropped);
|
virtual void AddDroppedTicks(int32 dropped);
|
||||||
virtual void PrintResults();
|
virtual void PrintResults(
|
||||||
|
ImageProfileResultContainer* container);
|
||||||
|
|
||||||
virtual CallgrindProfileResultImage* CreateProfileResultImage(Image* image);
|
virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
|
||||||
|
image_id id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _PrintFunction(FILE* out,
|
void _PrintFunction(FILE* out,
|
||||||
CallgrindProfileResultImage* image,
|
CallgrindImageProfileResult* image,
|
||||||
int32 functionIndex, bool called);
|
int32 functionIndex, bool called);
|
||||||
private:
|
private:
|
||||||
int64 fTotalTicks;
|
int64 fTotalTicks;
|
||||||
|
|||||||
@@ -7,26 +7,43 @@
|
|||||||
#include "ProfileResult.h"
|
#include "ProfileResult.h"
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - ProfileResultImage
|
// #pragma mark - ImageProfileResultContainer
|
||||||
|
|
||||||
|
|
||||||
ProfileResultImage::ProfileResultImage(Image* image)
|
ImageProfileResultContainer::~ImageProfileResultContainer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ImageProfileResultContainer::Visitor
|
||||||
|
|
||||||
|
|
||||||
|
ImageProfileResultContainer::Visitor::~Visitor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ImageProfileResult
|
||||||
|
|
||||||
|
|
||||||
|
ImageProfileResult::ImageProfileResult(SharedImage* image, image_id id)
|
||||||
:
|
:
|
||||||
fImage(image),
|
fImage(image),
|
||||||
fTotalHits(0)
|
fTotalHits(0),
|
||||||
|
fImageID(id)
|
||||||
{
|
{
|
||||||
fImage->AddReference();
|
fImage->AddReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ProfileResultImage::~ProfileResultImage()
|
ImageProfileResult::~ImageProfileResult()
|
||||||
{
|
{
|
||||||
fImage->RemoveReference();
|
fImage->RemoveReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ProfileResultImage::Init()
|
ImageProfileResult::Init()
|
||||||
{
|
{
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,30 +8,53 @@
|
|||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
#include "Image.h"
|
#include "SharedImage.h"
|
||||||
|
|
||||||
|
|
||||||
class ProfiledEntity;
|
class ProfiledEntity;
|
||||||
class Team;
|
class Team;
|
||||||
|
|
||||||
|
|
||||||
class ProfileResultImage {
|
class ImageProfileResult {
|
||||||
public:
|
public:
|
||||||
ProfileResultImage(Image* image);
|
ImageProfileResult(SharedImage* image,
|
||||||
virtual ~ProfileResultImage();
|
image_id id);
|
||||||
|
virtual ~ImageProfileResult();
|
||||||
|
|
||||||
virtual status_t Init();
|
virtual status_t Init();
|
||||||
|
|
||||||
inline image_id ID() const;
|
inline image_id ID() const;
|
||||||
inline Image* GetImage() const;
|
inline SharedImage* GetImage() const;
|
||||||
|
|
||||||
inline bool ContainsAddress(addr_t address) const;
|
|
||||||
|
|
||||||
inline int64 TotalHits() const;
|
inline int64 TotalHits() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Image* fImage;
|
SharedImage* fImage;
|
||||||
int64 fTotalHits;
|
int64 fTotalHits;
|
||||||
|
image_id fImageID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ImageProfileResultContainer {
|
||||||
|
public:
|
||||||
|
class Visitor;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~ImageProfileResultContainer();
|
||||||
|
|
||||||
|
virtual int32 CountImages() const = 0;
|
||||||
|
virtual ImageProfileResult* VisitImages(Visitor& visitor) const = 0;
|
||||||
|
virtual ImageProfileResult* FindImage(addr_t address,
|
||||||
|
addr_t& _loadDelta) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ImageProfileResultContainer::Visitor {
|
||||||
|
public:
|
||||||
|
virtual ~Visitor();
|
||||||
|
|
||||||
|
virtual bool VisitImage(ImageProfileResult* image) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -44,16 +67,22 @@ public:
|
|||||||
|
|
||||||
void SetInterval(bigtime_t interval);
|
void SetInterval(bigtime_t interval);
|
||||||
|
|
||||||
virtual void SetLazyImages(bool lazy) = 0;
|
virtual void AddSamples(
|
||||||
|
ImageProfileResultContainer* container,
|
||||||
virtual status_t AddImage(Image* image) = 0;
|
addr_t* samples,
|
||||||
virtual void RemoveImage(Image* image) = 0;
|
|
||||||
virtual void SynchronizeImages(int32 event) = 0;
|
|
||||||
|
|
||||||
virtual void AddSamples(addr_t* samples,
|
|
||||||
int32 sampleCount) = 0;
|
int32 sampleCount) = 0;
|
||||||
virtual void AddDroppedTicks(int32 dropped) = 0;
|
virtual void AddDroppedTicks(int32 dropped) = 0;
|
||||||
virtual void PrintResults() = 0;
|
virtual void PrintResults(
|
||||||
|
ImageProfileResultContainer* container) = 0;
|
||||||
|
|
||||||
|
virtual ImageProfileResult* CreateImageProfileResult(SharedImage* image,
|
||||||
|
image_id id) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename ImageProfileResultType>
|
||||||
|
int32 GetHitImages(
|
||||||
|
ImageProfileResultContainer* container,
|
||||||
|
ImageProfileResultType** images) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ProfiledEntity* fEntity;
|
ProfiledEntity* fEntity;
|
||||||
@@ -61,204 +90,58 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
// #pragma mark - ImageProfileResult
|
||||||
class AbstractProfileResult : public ProfileResult {
|
|
||||||
public:
|
|
||||||
AbstractProfileResult();
|
|
||||||
virtual ~AbstractProfileResult();
|
|
||||||
|
|
||||||
virtual void SetLazyImages(bool lazy);
|
|
||||||
|
|
||||||
virtual status_t AddImage(Image* image);
|
|
||||||
virtual void RemoveImage(Image* image);
|
|
||||||
virtual void SynchronizeImages(int32 event);
|
|
||||||
|
|
||||||
ProfileResultImageType* FindImage(addr_t address) const;
|
|
||||||
int32 GetHitImages(
|
|
||||||
ProfileResultImageType** images) const;
|
|
||||||
|
|
||||||
virtual ProfileResultImageType* CreateProfileResultImage(Image* image) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef DoublyLinkedList<ProfileResultImageType> ImageList;
|
|
||||||
|
|
||||||
ImageList fImages;
|
|
||||||
ImageList fNewImages;
|
|
||||||
ImageList fOldImages;
|
|
||||||
bool fLazyImages;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
image_id
|
image_id
|
||||||
ProfileResultImage::ID() const
|
ImageProfileResult::ID() const
|
||||||
{
|
{
|
||||||
return fImage->ID();
|
return fImageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
SharedImage*
|
||||||
ProfileResultImage::ContainsAddress(addr_t address) const
|
ImageProfileResult::GetImage() const
|
||||||
{
|
|
||||||
return fImage->ContainsAddress(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Image*
|
|
||||||
ProfileResultImage::GetImage() const
|
|
||||||
{
|
{
|
||||||
return fImage;
|
return fImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
ProfileResultImage::TotalHits() const
|
ImageProfileResult::TotalHits() const
|
||||||
{
|
{
|
||||||
return fTotalHits;
|
return fTotalHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AbstractProfileResult
|
// #pragma mark - ProfileResult
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
template<typename ImageProfileResultType>
|
||||||
AbstractProfileResult<ProfileResultImageType>::AbstractProfileResult()
|
|
||||||
:
|
|
||||||
fImages(),
|
|
||||||
fNewImages(),
|
|
||||||
fOldImages(),
|
|
||||||
fLazyImages(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::~AbstractProfileResult()
|
|
||||||
{
|
|
||||||
while (ProfileResultImageType* image = fImages.RemoveHead())
|
|
||||||
delete image;
|
|
||||||
while (ProfileResultImageType* image = fOldImages.RemoveHead())
|
|
||||||
delete image;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
void
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::SetLazyImages(bool lazy)
|
|
||||||
{
|
|
||||||
fLazyImages = lazy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
status_t
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::AddImage(Image* image)
|
|
||||||
{
|
|
||||||
ProfileResultImageType* resultImage = CreateProfileResultImage(image);
|
|
||||||
if (resultImage == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
status_t error = resultImage->Init();
|
|
||||||
if (error != B_OK) {
|
|
||||||
delete resultImage;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fLazyImages)
|
|
||||||
fNewImages.Add(resultImage);
|
|
||||||
else
|
|
||||||
fImages.Add(resultImage);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
void
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::RemoveImage(Image* image)
|
|
||||||
{
|
|
||||||
typename ImageList::Iterator it = fImages.GetIterator();
|
|
||||||
while (ProfileResultImageType* resultImage = it.Next()) {
|
|
||||||
if (resultImage->GetImage() == image) {
|
|
||||||
it.Remove();
|
|
||||||
if (resultImage->TotalHits() > 0)
|
|
||||||
fOldImages.Add(resultImage);
|
|
||||||
else
|
|
||||||
delete resultImage;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
void
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::SynchronizeImages(int32 event)
|
|
||||||
{
|
|
||||||
// remove obsolete images
|
|
||||||
typename ImageList::Iterator it = fImages.GetIterator();
|
|
||||||
while (ProfileResultImageType* image = it.Next()) {
|
|
||||||
int32 deleted = image->GetImage()->DeletionEvent();
|
|
||||||
if (deleted >= 0 && event >= deleted) {
|
|
||||||
it.Remove();
|
|
||||||
if (image->TotalHits() > 0)
|
|
||||||
fOldImages.Add(image);
|
|
||||||
else
|
|
||||||
delete image;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add new images
|
|
||||||
it = fNewImages.GetIterator();
|
|
||||||
while (ProfileResultImageType* image = it.Next()) {
|
|
||||||
if (image->GetImage()->CreationEvent() <= event) {
|
|
||||||
it.Remove();
|
|
||||||
int32 deleted = image->GetImage()->DeletionEvent();
|
|
||||||
if (deleted >= 0 && event >= deleted) {
|
|
||||||
// image already deleted
|
|
||||||
delete image;
|
|
||||||
} else
|
|
||||||
fImages.Add(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
ProfileResultImageType*
|
|
||||||
AbstractProfileResult<ProfileResultImageType>::FindImage(addr_t address) const
|
|
||||||
{
|
|
||||||
typename ImageList::ConstIterator it = fImages.GetIterator();
|
|
||||||
while (ProfileResultImageType* image = it.Next()) {
|
|
||||||
if (image->ContainsAddress(address))
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProfileResultImageType>
|
|
||||||
int32
|
int32
|
||||||
AbstractProfileResult<ProfileResultImageType>::GetHitImages(
|
ProfileResult::GetHitImages(ImageProfileResultContainer* container,
|
||||||
ProfileResultImageType** images) const
|
ImageProfileResultType** images) const
|
||||||
{
|
{
|
||||||
int32 imageCount = 0;
|
struct Visitor : ImageProfileResultContainer::Visitor {
|
||||||
|
ImageProfileResultType** images;
|
||||||
|
int32 imageCount;
|
||||||
|
|
||||||
typename ImageList::ConstIterator it = fOldImages.GetIterator();
|
virtual bool VisitImage(ImageProfileResult* image)
|
||||||
while (ProfileResultImageType* image = it.Next()) {
|
{
|
||||||
if (image->TotalHits() > 0)
|
if (image->TotalHits() > 0) {
|
||||||
images[imageCount++] = image;
|
images[imageCount++]
|
||||||
|
= static_cast<ImageProfileResultType*>(image);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
it = fImages.GetIterator();
|
|
||||||
while (ProfileResultImageType* image = it.Next()) {
|
|
||||||
if (image->TotalHits() > 0)
|
|
||||||
images[imageCount++] = image;
|
|
||||||
}
|
}
|
||||||
|
} visitor;
|
||||||
|
|
||||||
return imageCount;
|
visitor.images = images;
|
||||||
|
visitor.imageCount = 0;
|
||||||
|
|
||||||
|
container->VisitImages(visitor);
|
||||||
|
|
||||||
|
return visitor.imageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "debug_utils.h"
|
#include "debug_utils.h"
|
||||||
|
|
||||||
|
#include "Image.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ status_t
|
|||||||
Team::InitThread(Thread* thread)
|
Team::InitThread(Thread* thread)
|
||||||
{
|
{
|
||||||
// The thread
|
// The thread
|
||||||
thread->GetProfileResult()->SetLazyImages(!_SynchronousProfiling());
|
thread->SetLazyImages(!_SynchronousProfiling());
|
||||||
|
|
||||||
// create the sample area
|
// create the sample area
|
||||||
char areaName[B_OS_NAME_LENGTH];
|
char areaName[B_OS_NAME_LENGTH];
|
||||||
@@ -267,7 +268,7 @@ Team::_RemoveImage(int32 index, int32 event)
|
|||||||
if (_SynchronousProfiling()) {
|
if (_SynchronousProfiling()) {
|
||||||
ThreadList::Iterator it = fThreads.GetIterator();
|
ThreadList::Iterator it = fThreads.GetIterator();
|
||||||
while (Thread* thread = it.Next())
|
while (Thread* thread = it.Next())
|
||||||
thread->GetProfileResult()->RemoveImage(image);
|
thread->RemoveImage(image);
|
||||||
} else {
|
} else {
|
||||||
// Note: We don't tell the threads that the image has been removed. They
|
// Note: We don't tell the threads that the image has been removed. They
|
||||||
// will be updated lazily when their next profiler update arrives. This
|
// will be updated lazily when their next profiler update arrives. This
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
* Copyright 2008-2010, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef TEAM_H
|
#ifndef TEAM_H
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
class SharedImage;
|
||||||
struct system_profiler_team_added;
|
struct system_profiler_team_added;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,32 @@
|
|||||||
|
|
||||||
#include "debug_utils.h"
|
#include "debug_utils.h"
|
||||||
|
|
||||||
|
#include "Image.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ThreadImage
|
||||||
|
|
||||||
|
|
||||||
|
ThreadImage::ThreadImage(Image* image, ImageProfileResult* result)
|
||||||
|
:
|
||||||
|
fImage(image),
|
||||||
|
fResult(result)
|
||||||
|
{
|
||||||
|
fImage->AcquireReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThreadImage::~ThreadImage()
|
||||||
|
{
|
||||||
|
fImage->ReleaseReference();
|
||||||
|
delete fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ThreadI
|
||||||
|
|
||||||
|
|
||||||
Thread::Thread(thread_id threadID, const char* name, Team* team)
|
Thread::Thread(thread_id threadID, const char* name, Team* team)
|
||||||
:
|
:
|
||||||
@@ -25,7 +47,8 @@ Thread::Thread(thread_id threadID, const char* name, Team* team)
|
|||||||
fTeam(team),
|
fTeam(team),
|
||||||
fSampleArea(-1),
|
fSampleArea(-1),
|
||||||
fSamples(NULL),
|
fSamples(NULL),
|
||||||
fProfileResult(NULL)
|
fProfileResult(NULL),
|
||||||
|
fLazyImages(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +59,11 @@ Thread::~Thread()
|
|||||||
delete_area(fSampleArea);
|
delete_area(fSampleArea);
|
||||||
|
|
||||||
delete fProfileResult;
|
delete fProfileResult;
|
||||||
|
|
||||||
|
while (ThreadImage* image = fImages.RemoveHead())
|
||||||
|
delete image;
|
||||||
|
while (ThreadImage* image = fOldImages.RemoveHead())
|
||||||
|
delete image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,11 +118,64 @@ Thread::SetInterval(bigtime_t interval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread::SetLazyImages(bool lazy)
|
||||||
|
{
|
||||||
|
fLazyImages = lazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Thread::AddImage(Image* image)
|
||||||
|
{
|
||||||
|
ImageProfileResult* result = fProfileResult->CreateImageProfileResult(
|
||||||
|
image->GetSharedImage(), image->ID());
|
||||||
|
if (result == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t error = result->Init();
|
||||||
|
if (error != B_OK) {
|
||||||
|
delete result;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadImage* threadImage = new(std::nothrow) ThreadImage(image, result);
|
||||||
|
if (threadImage == NULL) {
|
||||||
|
delete result;
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fLazyImages)
|
||||||
|
fNewImages.Add(threadImage);
|
||||||
|
else
|
||||||
|
fImages.Add(threadImage);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread::RemoveImage(Image* image)
|
||||||
|
{
|
||||||
|
ImageList::Iterator it = fImages.GetIterator();
|
||||||
|
while (ThreadImage* threadImage = it.Next()) {
|
||||||
|
if (threadImage->GetImage() == image) {
|
||||||
|
it.Remove();
|
||||||
|
if (threadImage->Result()->TotalHits() > 0)
|
||||||
|
fOldImages.Add(threadImage);
|
||||||
|
else
|
||||||
|
delete threadImage;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
||||||
bool variableStackDepth, int32 event)
|
bool variableStackDepth, int32 event)
|
||||||
{
|
{
|
||||||
fProfileResult->SynchronizeImages(event);
|
_SynchronizeImages(event);
|
||||||
|
|
||||||
if (variableStackDepth) {
|
if (variableStackDepth) {
|
||||||
addr_t* samples = fSamples;
|
addr_t* samples = fSamples;
|
||||||
@@ -106,7 +187,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
|||||||
int32 eventParameterCount
|
int32 eventParameterCount
|
||||||
= sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK;
|
= sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK;
|
||||||
if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) {
|
if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) {
|
||||||
fProfileResult->SynchronizeImages((int32)samples[0]);
|
_SynchronizeImages((int32)samples[0]);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "unknown profile event: %#lx\n",
|
fprintf(stderr, "unknown profile event: %#lx\n",
|
||||||
sampleCount);
|
sampleCount);
|
||||||
@@ -117,7 +198,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fProfileResult->AddSamples(samples, sampleCount);
|
fProfileResult->AddSamples(this, samples, sampleCount);
|
||||||
|
|
||||||
samples += sampleCount;
|
samples += sampleCount;
|
||||||
count -= sampleCount + 1;
|
count -= sampleCount + 1;
|
||||||
@@ -126,7 +207,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
|||||||
count = count / stackDepth * stackDepth;
|
count = count / stackDepth * stackDepth;
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i += stackDepth)
|
for (int32 i = 0; i < count; i += stackDepth)
|
||||||
fProfileResult->AddSamples(fSamples + i, stackDepth);
|
fProfileResult->AddSamples(this, fSamples + i, stackDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
fProfileResult->AddDroppedTicks(dropped);
|
fProfileResult->AddDroppedTicks(dropped);
|
||||||
@@ -136,12 +217,84 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth,
|
|||||||
void
|
void
|
||||||
Thread::AddSamples(addr_t* samples, int32 sampleCount)
|
Thread::AddSamples(addr_t* samples, int32 sampleCount)
|
||||||
{
|
{
|
||||||
fProfileResult->AddSamples(samples, sampleCount);
|
fProfileResult->AddSamples(this, samples, sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread::PrintResults() const
|
Thread::PrintResults()
|
||||||
{
|
{
|
||||||
fProfileResult->PrintResults();
|
fProfileResult->PrintResults(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Thread::CountImages() const
|
||||||
|
{
|
||||||
|
return fImages.Count() + fOldImages.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImageProfileResult*
|
||||||
|
Thread::VisitImages(Visitor& visitor) const
|
||||||
|
{
|
||||||
|
ImageList::ConstIterator it = fOldImages.GetIterator();
|
||||||
|
while (ThreadImage* image = it.Next()) {
|
||||||
|
if (visitor.VisitImage(image->Result()))
|
||||||
|
return image->Result();
|
||||||
|
}
|
||||||
|
|
||||||
|
it = fImages.GetIterator();
|
||||||
|
while (ThreadImage* image = it.Next()) {
|
||||||
|
if (visitor.VisitImage(image->Result()))
|
||||||
|
return image->Result();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImageProfileResult*
|
||||||
|
Thread::FindImage(addr_t address, addr_t& _loadDelta) const
|
||||||
|
{
|
||||||
|
ImageList::ConstIterator it = fImages.GetIterator();
|
||||||
|
while (ThreadImage* image = it.Next()) {
|
||||||
|
if (image->GetImage()->ContainsAddress(address)) {
|
||||||
|
_loadDelta = image->GetImage()->LoadDelta();
|
||||||
|
return image->Result();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread::_SynchronizeImages(int32 event)
|
||||||
|
{
|
||||||
|
// remove obsolete images
|
||||||
|
ImageList::Iterator it = fImages.GetIterator();
|
||||||
|
while (ThreadImage* image = it.Next()) {
|
||||||
|
int32 deleted = image->GetImage()->DeletionEvent();
|
||||||
|
if (deleted >= 0 && event >= deleted) {
|
||||||
|
it.Remove();
|
||||||
|
if (image->Result()->TotalHits() > 0)
|
||||||
|
fOldImages.Add(image);
|
||||||
|
else
|
||||||
|
delete image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new images
|
||||||
|
it = fNewImages.GetIterator();
|
||||||
|
while (ThreadImage* image = it.Next()) {
|
||||||
|
if (image->GetImage()->CreationEvent() <= event) {
|
||||||
|
it.Remove();
|
||||||
|
int32 deleted = image->GetImage()->DeletionEvent();
|
||||||
|
if (deleted >= 0 && event >= deleted) {
|
||||||
|
// image already deleted
|
||||||
|
delete image;
|
||||||
|
} else
|
||||||
|
fImages.Add(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,27 @@
|
|||||||
#include "ProfileResult.h"
|
#include "ProfileResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Image;
|
||||||
class Team;
|
class Team;
|
||||||
|
|
||||||
|
|
||||||
class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl<Thread> {
|
class ThreadImage : public DoublyLinkedListLinkImpl<ThreadImage> {
|
||||||
|
public:
|
||||||
|
ThreadImage(Image* image,
|
||||||
|
ImageProfileResult* result);
|
||||||
|
~ThreadImage();
|
||||||
|
|
||||||
|
Image* GetImage() const { return fImage; }
|
||||||
|
ImageProfileResult* Result() const { return fResult; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Image* fImage;
|
||||||
|
ImageProfileResult* fResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl<Thread>,
|
||||||
|
private ImageProfileResultContainer {
|
||||||
public:
|
public:
|
||||||
Thread(thread_id threadID, const char* name,
|
Thread(thread_id threadID, const char* name,
|
||||||
Team* team);
|
Team* team);
|
||||||
@@ -40,14 +57,29 @@ public:
|
|||||||
void SetSampleArea(area_id area, addr_t* samples);
|
void SetSampleArea(area_id area, addr_t* samples);
|
||||||
void SetInterval(bigtime_t interval);
|
void SetInterval(bigtime_t interval);
|
||||||
|
|
||||||
inline status_t AddImage(Image* image);
|
void SetLazyImages(bool lazy);
|
||||||
inline void RemoveImage(Image* image);
|
|
||||||
|
status_t AddImage(Image* image);
|
||||||
|
void RemoveImage(Image* image);
|
||||||
|
|
||||||
void AddSamples(int32 count, int32 dropped,
|
void AddSamples(int32 count, int32 dropped,
|
||||||
int32 stackDepth, bool variableStackDepth,
|
int32 stackDepth, bool variableStackDepth,
|
||||||
int32 event);
|
int32 event);
|
||||||
void AddSamples(addr_t* samples, int32 sampleCount);
|
void AddSamples(addr_t* samples, int32 sampleCount);
|
||||||
void PrintResults() const;
|
void PrintResults();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef DoublyLinkedList<ThreadImage> ImageList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ImageProfileResultContainer
|
||||||
|
virtual int32 CountImages() const;
|
||||||
|
virtual ImageProfileResult* VisitImages(Visitor& visitor) const;
|
||||||
|
virtual ImageProfileResult* FindImage(addr_t address,
|
||||||
|
addr_t& _loadDelta) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _SynchronizeImages(int32 event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
thread_id fID;
|
thread_id fID;
|
||||||
@@ -56,6 +88,10 @@ private:
|
|||||||
area_id fSampleArea;
|
area_id fSampleArea;
|
||||||
addr_t* fSamples;
|
addr_t* fSamples;
|
||||||
ProfileResult* fProfileResult;
|
ProfileResult* fProfileResult;
|
||||||
|
ImageList fImages;
|
||||||
|
ImageList fNewImages;
|
||||||
|
ImageList fOldImages;
|
||||||
|
bool fLazyImages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -94,18 +130,4 @@ Thread::GetProfileResult() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Thread::AddImage(Image* image)
|
|
||||||
{
|
|
||||||
return fProfileResult->AddImage(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Thread::RemoveImage(Image* image)
|
|
||||||
{
|
|
||||||
fProfileResult->RemoveImage(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // THREAD_H
|
#endif // THREAD_H
|
||||||
|
|||||||
Reference in New Issue
Block a user