diff --git a/src/bin/debug/profile/BasicProfileResult.cpp b/src/bin/debug/profile/BasicProfileResult.cpp index c6458aec83..ae3928be43 100644 --- a/src/bin/debug/profile/BasicProfileResult.cpp +++ b/src/bin/debug/profile/BasicProfileResult.cpp @@ -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), fUnknownHits(0) { } -BasicProfileResultImage::~BasicProfileResultImage() +BasicImageProfileResult::~BasicImageProfileResult() { } status_t -BasicProfileResultImage::Init() +BasicImageProfileResult::Init() { int32 symbolCount = fImage->SymbolCount(); fSymbolHits = new(std::nothrow) int64[symbolCount]; @@ -59,7 +60,7 @@ BasicProfileResultImage::Init() bool -BasicProfileResultImage::AddHit(addr_t address) +BasicImageProfileResult::AddHit(addr_t address) { int32 symbolIndex = fImage->FindSymbol(address); if (symbolIndex < 0) @@ -73,7 +74,7 @@ BasicProfileResultImage::AddHit(addr_t address) void -BasicProfileResultImage::AddUnknownHit() +BasicImageProfileResult::AddUnknownHit() { fUnknownHits++; fTotalHits++; @@ -81,28 +82,28 @@ BasicProfileResultImage::AddUnknownHit() void -BasicProfileResultImage::AddSymbolHit(int32 symbolIndex) +BasicImageProfileResult::AddSymbolHit(int32 symbolIndex) { fSymbolHits[symbolIndex]++; } void -BasicProfileResultImage::AddImageHit() +BasicImageProfileResult::AddImageHit() { fTotalHits++; } const int64* -BasicProfileResultImage::SymbolHits() const +BasicImageProfileResult::SymbolHits() const { return fSymbolHits; } int64 -BasicProfileResultImage::UnknownHits() const +BasicImageProfileResult::UnknownHits() const { return fUnknownHits; } @@ -129,16 +130,16 @@ BasicProfileResult::AddDroppedTicks(int32 dropped) void -BasicProfileResult::PrintResults() +BasicProfileResult::PrintResults(ImageProfileResultContainer* container) { // get hit images - BasicProfileResultImage* images[fOldImages.Count() + fImages.Count()]; - int32 imageCount = GetHitImages(images); + BasicImageProfileResult* images[container->CountImages()]; + int32 imageCount = GetHitImages(container, images); // count symbols int32 symbolCount = 0; for (int32 k = 0; k < imageCount; k++) { - BasicProfileResultImage* image = images[k]; + BasicImageProfileResult* image = images[k]; if (image->TotalHits() > image->UnknownHits()) symbolCount += image->GetImage()->SymbolCount(); } @@ -148,7 +149,7 @@ BasicProfileResult::PrintResults() int32 hitSymbolCount = 0; for (int32 k = 0; k < imageCount; k++) { - BasicProfileResultImage* image = images[k]; + BasicImageProfileResult* image = images[k]; if (image->TotalHits() > image->UnknownHits()) { Symbol** symbols = image->GetImage()->Symbols(); const int64* symbolHits = image->SymbolHits(); @@ -193,10 +194,10 @@ BasicProfileResult::PrintResults() fprintf(gOptions.output, " ---------------------------------------" "---------------------------------------\n"); for (int32 k = 0; k < imageCount; k++) { - BasicProfileResultImage* image = images[k]; + BasicImageProfileResult* image = images[k]; fprintf(gOptions.output, " %10lld %10lld %7ld %s\n", image->TotalHits(), image->UnknownHits(), - image->GetImage()->ID(), image->GetImage()->Name()); + image->ID(), image->GetImage()->Name()); } } @@ -219,10 +220,10 @@ BasicProfileResult::PrintResults() } -BasicProfileResultImage* -BasicProfileResult::CreateProfileResultImage(Image* image) +ImageProfileResult* +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 -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 // 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); int32 unknownSamples = 0; - BasicProfileResultImage* previousImage = NULL; + BasicImageProfileResult* previousImage = NULL; int32 previousSymbol = -1; for (int32 i = 0; i < sampleCount; i++) { addr_t address = samples[i]; - BasicProfileResultImage* image = FindImage(address); + addr_t loadDelta; + BasicImageProfileResult* image = static_cast( + container->FindImage(address, loadDelta)); int32 symbol = -1; if (image != NULL) { - symbol = image->GetImage()->FindSymbol(address); + symbol = image->GetImage()->FindSymbol(address - loadDelta); if (symbol < 0) { // TODO: Count unknown image hits? } else if (image != previousImage || symbol != previousSymbol) @@ -273,18 +277,21 @@ InclusiveProfileResult::AddSamples(addr_t* samples, int32 sampleCount) 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 - BasicProfileResultImage* firstImage = NULL; + BasicImageProfileResult* firstImage = NULL; // the first image we hit, != image if no symbol was hit for (int32 k = 0; k < sampleCount; k++) { addr_t address = samples[k]; - image = FindImage(address); + addr_t loadDelta; + image = static_cast( + container->FindImage(address, loadDelta)); if (image != NULL) { - if (image->AddHit(address)) + if (image->AddHit(address - loadDelta)) break; if (firstImage == NULL) firstImage = image; diff --git a/src/bin/debug/profile/BasicProfileResult.h b/src/bin/debug/profile/BasicProfileResult.h index 76bb0042ac..e3cd38e54b 100644 --- a/src/bin/debug/profile/BasicProfileResult.h +++ b/src/bin/debug/profile/BasicProfileResult.h @@ -9,11 +9,12 @@ #include "ProfileResult.h" -class BasicProfileResultImage : public ProfileResultImage, - public DoublyLinkedListLinkImpl { +class BasicImageProfileResult : public ImageProfileResult, + public DoublyLinkedListLinkImpl { public: - BasicProfileResultImage(Image* image); - virtual ~BasicProfileResultImage(); + BasicImageProfileResult(SharedImage* image, + image_id id); + virtual ~BasicImageProfileResult(); virtual status_t Init(); @@ -31,15 +32,16 @@ private: }; -class BasicProfileResult - : public AbstractProfileResult { +class BasicProfileResult : public ProfileResult { public: BasicProfileResult(); 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: int64 fTotalTicks; @@ -51,15 +53,17 @@ protected: class InclusiveProfileResult : public BasicProfileResult { public: - virtual void AddSamples(addr_t* samples, - int32 sampleCount); + virtual void AddSamples( + ImageProfileResultContainer* container, + addr_t* samples, int32 sampleCount); }; class ExclusiveProfileResult : public BasicProfileResult { public: - virtual void AddSamples(addr_t* samples, - int32 sampleCount); + virtual void AddSamples( + ImageProfileResultContainer* container, + addr_t* samples, int32 sampleCount); }; diff --git a/src/bin/debug/profile/CallgrindProfileResult.cpp b/src/bin/debug/profile/CallgrindProfileResult.cpp index a1636ce3c4..e88f858389 100644 --- a/src/bin/debug/profile/CallgrindProfileResult.cpp +++ b/src/bin/debug/profile/CallgrindProfileResult.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -16,19 +16,20 @@ #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), fOutputIndex(0) { } -CallgrindProfileResultImage::~CallgrindProfileResultImage() +CallgrindImageProfileResult::~CallgrindImageProfileResult() { int32 symbolCount = fImage->SymbolCount(); for (int32 i = 0; i < symbolCount; i++) { @@ -44,7 +45,7 @@ CallgrindProfileResultImage::~CallgrindProfileResultImage() status_t -CallgrindProfileResultImage::Init() +CallgrindImageProfileResult::Init() { int32 symbolCount = fImage->SymbolCount(); fFunctions = new(std::nothrow) CallgrindFunction[symbolCount]; @@ -58,8 +59,8 @@ CallgrindProfileResultImage::Init() void -CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex, - CallgrindProfileResultImage* calledImage, int32 calledSymbol) +CallgrindImageProfileResult::AddSymbolHit(int32 symbolIndex, + CallgrindImageProfileResult* calledImage, int32 calledSymbol) { fTotalHits++; @@ -94,21 +95,21 @@ CallgrindProfileResultImage::AddSymbolHit(int32 symbolIndex, CallgrindFunction* -CallgrindProfileResultImage::Functions() const +CallgrindImageProfileResult::Functions() const { return fFunctions; } int32 -CallgrindProfileResultImage::OutputIndex() const +CallgrindImageProfileResult::OutputIndex() const { return fOutputIndex; } void -CallgrindProfileResultImage::SetOutputIndex(int32 index) +CallgrindImageProfileResult::SetOutputIndex(int32 index) { fOutputIndex = index; } @@ -129,19 +130,23 @@ CallgrindProfileResult::CallgrindProfileResult() void -CallgrindProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +CallgrindProfileResult::AddSamples(ImageProfileResultContainer* container, + addr_t* samples, int32 sampleCount) { int32 unknownSamples = 0; - CallgrindProfileResultImage* previousImage = NULL; + CallgrindImageProfileResult* previousImage = NULL; int32 previousSymbol = -1; // TODO: That probably doesn't work with recursive functions. for (int32 i = 0; i < sampleCount; i++) { addr_t address = samples[i]; - CallgrindProfileResultImage* image = FindImage(address); + addr_t loadDelta; + CallgrindImageProfileResult* image + = static_cast( + container->FindImage(address, loadDelta)); int32 symbol = -1; if (image != NULL) { - symbol = image->GetImage()->FindSymbol(address); + symbol = image->GetImage()->FindSymbol(address - loadDelta); if (symbol >= 0) { image->AddSymbolHit(symbol, previousImage, previousSymbol); previousImage = image; @@ -166,7 +171,7 @@ CallgrindProfileResult::AddDroppedTicks(int32 dropped) void -CallgrindProfileResult::PrintResults() +CallgrindProfileResult::PrintResults(ImageProfileResultContainer* container) { // create output file @@ -206,11 +211,11 @@ CallgrindProfileResult::PrintResults() fprintf(out, "summary: %lld %lld\n", fTotalTicks, fTotalTicks * fInterval); // get hit images - CallgrindProfileResultImage* images[fOldImages.Count() + fImages.Count()]; - int32 imageCount = GetHitImages(images); + CallgrindImageProfileResult* images[container->CountImages()]; + int32 imageCount = GetHitImages(container, images); for (int32 i = 0; i < imageCount; i++) { - CallgrindProfileResultImage* image = images[i]; + CallgrindImageProfileResult* image = images[i]; CallgrindFunction* functions = image->Functions(); int32 imageSymbolCount = image->GetImage()->SymbolCount(); @@ -257,16 +262,17 @@ CallgrindProfileResult::PrintResults() } -CallgrindProfileResultImage* -CallgrindProfileResult::CreateProfileResultImage(Image* image) +ImageProfileResult* +CallgrindProfileResult::CreateImageProfileResult(SharedImage* image, + image_id id) { - return new(std::nothrow) CallgrindProfileResultImage(image); + return new(std::nothrow) CallgrindImageProfileResult(image, id); } void CallgrindProfileResult::_PrintFunction(FILE* out, - CallgrindProfileResultImage* image, int32 functionIndex, bool called) + CallgrindImageProfileResult* image, int32 functionIndex, bool called) { if (image->OutputIndex() == 0) { // need to print the image name diff --git a/src/bin/debug/profile/CallgrindProfileResult.h b/src/bin/debug/profile/CallgrindProfileResult.h index 6ecfdc103b..1517967e52 100644 --- a/src/bin/debug/profile/CallgrindProfileResult.h +++ b/src/bin/debug/profile/CallgrindProfileResult.h @@ -11,16 +11,16 @@ #include "ProfileResult.h" -class CallgrindProfileResultImage; +class CallgrindImageProfileResult; struct CallgrindCalledFunction { CallgrindCalledFunction* next; - CallgrindProfileResultImage* image; + CallgrindImageProfileResult* image; int32 function; int64 hits; - CallgrindCalledFunction(CallgrindProfileResultImage* image, int32 function) + CallgrindCalledFunction(CallgrindImageProfileResult* image, int32 function) : next(NULL), image(image), @@ -39,16 +39,17 @@ struct CallgrindFunction { }; -class CallgrindProfileResultImage : public ProfileResultImage, - public DoublyLinkedListLinkImpl { +class CallgrindImageProfileResult : public ImageProfileResult, + public DoublyLinkedListLinkImpl { public: - CallgrindProfileResultImage(Image* image); - virtual ~CallgrindProfileResultImage(); + CallgrindImageProfileResult(SharedImage* image, + image_id id); + virtual ~CallgrindImageProfileResult(); virtual status_t Init(); inline void AddSymbolHit(int32 symbolIndex, - CallgrindProfileResultImage* calledImage, + CallgrindImageProfileResult* calledImage, int32 calledSymbol); inline CallgrindFunction* Functions() const; @@ -62,21 +63,23 @@ private: }; -class CallgrindProfileResult - : public AbstractProfileResult { +class CallgrindProfileResult : public ProfileResult { public: CallgrindProfileResult(); - virtual void AddSamples(addr_t* samples, - int32 sampleCount); + virtual void AddSamples( + ImageProfileResultContainer* container, + addr_t* samples, int32 sampleCount); 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: void _PrintFunction(FILE* out, - CallgrindProfileResultImage* image, + CallgrindImageProfileResult* image, int32 functionIndex, bool called); private: int64 fTotalTicks; diff --git a/src/bin/debug/profile/ProfileResult.cpp b/src/bin/debug/profile/ProfileResult.cpp index e7658dc2fe..5d81a40bb2 100644 --- a/src/bin/debug/profile/ProfileResult.cpp +++ b/src/bin/debug/profile/ProfileResult.cpp @@ -7,26 +7,43 @@ #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), - fTotalHits(0) + fTotalHits(0), + fImageID(id) { fImage->AddReference(); } -ProfileResultImage::~ProfileResultImage() +ImageProfileResult::~ImageProfileResult() { fImage->RemoveReference(); } status_t -ProfileResultImage::Init() +ImageProfileResult::Init() { return B_OK; } diff --git a/src/bin/debug/profile/ProfileResult.h b/src/bin/debug/profile/ProfileResult.h index 7df8306075..16b8be142e 100644 --- a/src/bin/debug/profile/ProfileResult.h +++ b/src/bin/debug/profile/ProfileResult.h @@ -8,30 +8,53 @@ #include -#include "Image.h" +#include "SharedImage.h" class ProfiledEntity; class Team; -class ProfileResultImage { +class ImageProfileResult { public: - ProfileResultImage(Image* image); - virtual ~ProfileResultImage(); + ImageProfileResult(SharedImage* image, + image_id id); + virtual ~ImageProfileResult(); virtual status_t Init(); inline image_id ID() const; - inline Image* GetImage() const; - - inline bool ContainsAddress(addr_t address) const; + inline SharedImage* GetImage() const; inline int64 TotalHits() const; protected: - Image* fImage; + SharedImage* fImage; 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); - virtual void SetLazyImages(bool lazy) = 0; - - virtual status_t AddImage(Image* image) = 0; - virtual void RemoveImage(Image* image) = 0; - virtual void SynchronizeImages(int32 event) = 0; - - virtual void AddSamples(addr_t* samples, + virtual void AddSamples( + ImageProfileResultContainer* container, + addr_t* samples, int32 sampleCount) = 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 + int32 GetHitImages( + ImageProfileResultContainer* container, + ImageProfileResultType** images) const; protected: ProfiledEntity* fEntity; @@ -61,204 +90,58 @@ protected: }; -template -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 ImageList; - - ImageList fImages; - ImageList fNewImages; - ImageList fOldImages; - bool fLazyImages; -}; - - -// #pragma mark - +// #pragma mark - ImageProfileResult image_id -ProfileResultImage::ID() const +ImageProfileResult::ID() const { - return fImage->ID(); + return fImageID; } -bool -ProfileResultImage::ContainsAddress(addr_t address) const -{ - return fImage->ContainsAddress(address); -} - - -Image* -ProfileResultImage::GetImage() const +SharedImage* +ImageProfileResult::GetImage() const { return fImage; } int64 -ProfileResultImage::TotalHits() const +ImageProfileResult::TotalHits() const { return fTotalHits; } -// #pragma mark - AbstractProfileResult +// #pragma mark - ProfileResult -template -AbstractProfileResult::AbstractProfileResult() - : - fImages(), - fNewImages(), - fOldImages(), - fLazyImages(true) -{ -} - - -template -AbstractProfileResult::~AbstractProfileResult() -{ - while (ProfileResultImageType* image = fImages.RemoveHead()) - delete image; - while (ProfileResultImageType* image = fOldImages.RemoveHead()) - delete image; -} - - -template -void -AbstractProfileResult::SetLazyImages(bool lazy) -{ - fLazyImages = lazy; -} - - -template -status_t -AbstractProfileResult::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 -void -AbstractProfileResult::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 -void -AbstractProfileResult::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 -ProfileResultImageType* -AbstractProfileResult::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 +template int32 -AbstractProfileResult::GetHitImages( - ProfileResultImageType** images) const +ProfileResult::GetHitImages(ImageProfileResultContainer* container, + ImageProfileResultType** images) const { - int32 imageCount = 0; + struct Visitor : ImageProfileResultContainer::Visitor { + ImageProfileResultType** images; + int32 imageCount; - typename ImageList::ConstIterator it = fOldImages.GetIterator(); - while (ProfileResultImageType* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } + virtual bool VisitImage(ImageProfileResult* image) + { + if (image->TotalHits() > 0) { + images[imageCount++] + = static_cast(image); + } + return false; + } + } visitor; - it = fImages.GetIterator(); - while (ProfileResultImageType* image = it.Next()) { - if (image->TotalHits() > 0) - images[imageCount++] = image; - } + visitor.images = images; + visitor.imageCount = 0; - return imageCount; + container->VisitImages(visitor); + + return visitor.imageCount; } diff --git a/src/bin/debug/profile/Team.cpp b/src/bin/debug/profile/Team.cpp index d201f51a9e..65e5cfe74c 100644 --- a/src/bin/debug/profile/Team.cpp +++ b/src/bin/debug/profile/Team.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -14,6 +14,7 @@ #include "debug_utils.h" +#include "Image.h" #include "Options.h" @@ -104,7 +105,7 @@ status_t Team::InitThread(Thread* thread) { // The thread - thread->GetProfileResult()->SetLazyImages(!_SynchronousProfiling()); + thread->SetLazyImages(!_SynchronousProfiling()); // create the sample area char areaName[B_OS_NAME_LENGTH]; @@ -267,7 +268,7 @@ Team::_RemoveImage(int32 index, int32 event) if (_SynchronousProfiling()) { ThreadList::Iterator it = fThreads.GetIterator(); while (Thread* thread = it.Next()) - thread->GetProfileResult()->RemoveImage(image); + thread->RemoveImage(image); } else { // 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 diff --git a/src/bin/debug/profile/Team.h b/src/bin/debug/profile/Team.h index 2b2d8fb5e4..deae2eba56 100644 --- a/src/bin/debug/profile/Team.h +++ b/src/bin/debug/profile/Team.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef TEAM_H @@ -14,6 +14,8 @@ #include "Thread.h" +class Image; +class SharedImage; struct system_profiler_team_added; diff --git a/src/bin/debug/profile/Thread.cpp b/src/bin/debug/profile/Thread.cpp index e8035e301c..75ad661e88 100644 --- a/src/bin/debug/profile/Thread.cpp +++ b/src/bin/debug/profile/Thread.cpp @@ -13,10 +13,32 @@ #include "debug_utils.h" +#include "Image.h" #include "Options.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) : @@ -25,7 +47,8 @@ Thread::Thread(thread_id threadID, const char* name, Team* team) fTeam(team), fSampleArea(-1), fSamples(NULL), - fProfileResult(NULL) + fProfileResult(NULL), + fLazyImages(true) { } @@ -36,6 +59,11 @@ Thread::~Thread() delete_area(fSampleArea); 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 Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, bool variableStackDepth, int32 event) { - fProfileResult->SynchronizeImages(event); + _SynchronizeImages(event); if (variableStackDepth) { addr_t* samples = fSamples; @@ -106,7 +187,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, int32 eventParameterCount = sampleCount & B_DEBUG_PROFILE_EVENT_PARAMETER_MASK; if (sampleCount == B_DEBUG_PROFILE_IMAGE_EVENT) { - fProfileResult->SynchronizeImages((int32)samples[0]); + _SynchronizeImages((int32)samples[0]); } else { fprintf(stderr, "unknown profile event: %#lx\n", sampleCount); @@ -117,7 +198,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, continue; } - fProfileResult->AddSamples(samples, sampleCount); + fProfileResult->AddSamples(this, samples, sampleCount); samples += sampleCount; count -= sampleCount + 1; @@ -126,7 +207,7 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, count = count / stackDepth * stackDepth; for (int32 i = 0; i < count; i += stackDepth) - fProfileResult->AddSamples(fSamples + i, stackDepth); + fProfileResult->AddSamples(this, fSamples + i, stackDepth); } fProfileResult->AddDroppedTicks(dropped); @@ -136,12 +217,84 @@ Thread::AddSamples(int32 count, int32 dropped, int32 stackDepth, void Thread::AddSamples(addr_t* samples, int32 sampleCount) { - fProfileResult->AddSamples(samples, sampleCount); + fProfileResult->AddSamples(this, samples, sampleCount); } 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); + } + } } diff --git a/src/bin/debug/profile/Thread.h b/src/bin/debug/profile/Thread.h index 774d0a6a6a..95245d38b1 100644 --- a/src/bin/debug/profile/Thread.h +++ b/src/bin/debug/profile/Thread.h @@ -14,10 +14,27 @@ #include "ProfileResult.h" +class Image; class Team; -class Thread : public ProfiledEntity, public DoublyLinkedListLinkImpl { +class ThreadImage : public DoublyLinkedListLinkImpl { +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, + private ImageProfileResultContainer { public: Thread(thread_id threadID, const char* name, Team* team); @@ -40,14 +57,29 @@ public: void SetSampleArea(area_id area, addr_t* samples); void SetInterval(bigtime_t interval); - inline status_t AddImage(Image* image); - inline void RemoveImage(Image* image); + void SetLazyImages(bool lazy); + + status_t AddImage(Image* image); + void RemoveImage(Image* image); void AddSamples(int32 count, int32 dropped, int32 stackDepth, bool variableStackDepth, int32 event); void AddSamples(addr_t* samples, int32 sampleCount); - void PrintResults() const; + void PrintResults(); + +private: + typedef DoublyLinkedList 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: thread_id fID; @@ -56,6 +88,10 @@ private: area_id fSampleArea; addr_t* fSamples; 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