From 72e19fd42681e08daec05ef864a661a6fe6fbec9 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 29 Sep 2008 15:36:39 +0000 Subject: [PATCH] Pulled subclass BasicThreadProfileResult out of AbstractThreadProfileResult. The latter only manages the images, now. Moved the AddSamples() code into BasicThreadProfileResult subclasses that handle it depending on whether the function hits are counted inclusively or exclusively ("-f" option). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27782 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/bin/debug/profile/Thread.cpp | 155 +++++++++++++++++------------- src/bin/debug/profile/Thread.h | 37 ++++++- src/bin/debug/profile/profile.cpp | 8 +- 3 files changed, 126 insertions(+), 74 deletions(-) diff --git a/src/bin/debug/profile/Thread.cpp b/src/bin/debug/profile/Thread.cpp index 07408b645b..1ac2a1bcd7 100644 --- a/src/bin/debug/profile/Thread.cpp +++ b/src/bin/debug/profile/Thread.cpp @@ -39,7 +39,7 @@ public: fImage->AddReference(); } - ~ThreadImage() + virtual ~ThreadImage() { fImage->RemoveReference(); } @@ -260,15 +260,12 @@ ThreadProfileResult::SetInterval(bigtime_t interval) // #pragma mark - AbstractThreadProfileResult + AbstractThreadProfileResult::AbstractThreadProfileResult() : fImages(), fNewImages(), - fOldImages(), - fTotalTicks(0), - fUnkownTicks(0), - fDroppedTicks(0), - fTotalSampleCount(0) + fOldImages() { } @@ -282,17 +279,10 @@ AbstractThreadProfileResult::~AbstractThreadProfileResult() } -status_t -AbstractThreadProfileResult::Init(Thread* thread) -{ - return ThreadProfileResult::Init(thread); -} - - status_t AbstractThreadProfileResult::AddImage(Image* image) { - ThreadImage* threadImage = new(std::nothrow) ThreadImage(image); + ThreadImage* threadImage = CreateThreadImage(image); if (threadImage == NULL) return B_NO_MEMORY; @@ -347,70 +337,28 @@ AbstractThreadProfileResult::FindImage(addr_t address) const } -void -AbstractThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +// #pragma mark - BasicThreadProfileResult + + +BasicThreadProfileResult::BasicThreadProfileResult() + : + fTotalTicks(0), + fUnkownTicks(0), + fDroppedTicks(0), + fTotalSampleCount(0) { - if (gOptions.analyze_full_stack) { - // Sort the samples. This way hits of the same symbol are - // successive and we can avoid incrementing the hit count of the - // same symbol twice. Same for images. - std::sort(samples, samples + sampleCount); - - int32 unknownSamples = 0; - ThreadImage* previousImage = NULL; - int32 previousSymbol = -1; - - for (int32 i = 0; i < sampleCount; i++) { - addr_t address = samples[i]; - ThreadImage* image = FindImage(address); - int32 symbol = -1; - if (image != NULL) { - symbol = image->GetImage()->FindSymbol(address); - if (symbol < 0) { - // TODO: Count unknown image hits? - } else if (symbol != previousSymbol) - image->AddSymbolHit(symbol); - - if (image != previousImage) - image->AddImageHit(); - } else - unknownSamples++; - - previousImage = image; - previousSymbol = symbol; - } - - if (unknownSamples == sampleCount) - fUnkownTicks++; - } else { - ThreadImage* image = NULL; - for (int32 k = 0; k < sampleCount; k++) { - addr_t address = samples[k]; - image = FindImage(address); - if (image != NULL) { - image->AddHit(address); - break; - } - } - - if (image == NULL) - fUnkownTicks++; - } - - fTotalTicks++; - fTotalSampleCount += sampleCount; } void -AbstractThreadProfileResult::AddDroppedTicks(int32 dropped) +BasicThreadProfileResult::AddDroppedTicks(int32 dropped) { fDroppedTicks += dropped; } void -AbstractThreadProfileResult::PrintResults() +BasicThreadProfileResult::PrintResults() { // count images and symbols int32 imageCount = 0; @@ -523,3 +471,76 @@ AbstractThreadProfileResult::PrintResults() fprintf(gOptions.output, " no functions were hit\n"); } + +ThreadImage* +BasicThreadProfileResult::CreateThreadImage(Image* image) +{ + return new(std::nothrow) ThreadImage(image); +} + + +// #pragma mark - InclusiveThreadProfileResult + + +void +InclusiveThreadProfileResult::AddSamples(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 + // same symbol twice. Same for images. + std::sort(samples, samples + sampleCount); + + int32 unknownSamples = 0; + ThreadImage* previousImage = NULL; + int32 previousSymbol = -1; + + for (int32 i = 0; i < sampleCount; i++) { + addr_t address = samples[i]; + ThreadImage* image = FindImage(address); + int32 symbol = -1; + if (image != NULL) { + symbol = image->GetImage()->FindSymbol(address); + if (symbol < 0) { + // TODO: Count unknown image hits? + } else if (symbol != previousSymbol) + image->AddSymbolHit(symbol); + + if (image != previousImage) + image->AddImageHit(); + } else + unknownSamples++; + + previousImage = image; + previousSymbol = symbol; + } + + if (unknownSamples == sampleCount) + fUnkownTicks++; + + fTotalTicks++; + fTotalSampleCount += sampleCount; +} + + +// #pragma mark - ExclusiveThreadProfileResult + + +void +ExclusiveThreadProfileResult::AddSamples(addr_t* samples, int32 sampleCount) +{ + ThreadImage* image = NULL; + for (int32 k = 0; k < sampleCount; k++) { + addr_t address = samples[k]; + image = FindImage(address); + if (image != NULL) { + image->AddHit(address); + break; + } + } + + if (image == NULL) + fUnkownTicks++; + + fTotalTicks++; + fTotalSampleCount += sampleCount; +} diff --git a/src/bin/debug/profile/Thread.h b/src/bin/debug/profile/Thread.h index ada2f2e422..123d37777b 100644 --- a/src/bin/debug/profile/Thread.h +++ b/src/bin/debug/profile/Thread.h @@ -80,17 +80,17 @@ public: AbstractThreadProfileResult(); virtual ~AbstractThreadProfileResult(); - virtual status_t Init(Thread* thread); - virtual status_t AddImage(Image* image); virtual void SynchronizeImages(int32 event); ThreadImage* FindImage(addr_t address) const; virtual void AddSamples(addr_t* samples, - int32 sampleCount); - virtual void AddDroppedTicks(int32 dropped); - virtual void PrintResults(); + int32 sampleCount) = 0; + virtual void AddDroppedTicks(int32 dropped) = 0; + virtual void PrintResults() = 0; + + virtual ThreadImage* CreateThreadImage(Image* image) = 0; protected: typedef DoublyLinkedList ImageList; @@ -98,6 +98,19 @@ protected: ImageList fImages; ImageList fNewImages; ImageList fOldImages; +}; + + +class BasicThreadProfileResult : public AbstractThreadProfileResult { +public: + BasicThreadProfileResult(); + + virtual void AddDroppedTicks(int32 dropped); + virtual void PrintResults(); + + virtual ThreadImage* CreateThreadImage(Image* image); + +protected: int64 fTotalTicks; int64 fUnkownTicks; int64 fDroppedTicks; @@ -105,6 +118,20 @@ protected: }; +class InclusiveThreadProfileResult : public BasicThreadProfileResult { +public: + virtual void AddSamples(addr_t* samples, + int32 sampleCount); +}; + + +class ExclusiveThreadProfileResult : public BasicThreadProfileResult { +public: + virtual void AddSamples(addr_t* samples, + int32 sampleCount); +}; + + // #pragma mark - diff --git a/src/bin/debug/profile/profile.cpp b/src/bin/debug/profile/profile.cpp index d1494f6186..293a57cbab 100644 --- a/src/bin/debug/profile/profile.cpp +++ b/src/bin/debug/profile/profile.cpp @@ -174,8 +174,12 @@ public: private: status_t _CreateThreadProfileResult(Thread* thread) { - ThreadProfileResult* profileResult - = new(std::nothrow) AbstractThreadProfileResult; + ThreadProfileResult* profileResult; + if (gOptions.analyze_full_stack) + profileResult = new(std::nothrow) InclusiveThreadProfileResult; + else + profileResult = new(std::nothrow) ExclusiveThreadProfileResult; + if (profileResult == NULL) return B_NO_MEMORY;