00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SUPPORT_CALLSTACK_H
00014 #define _SUPPORT_CALLSTACK_H
00015
00021 #include <support/ITextStream.h>
00022 #include <support/SupportDefs.h>
00023 #include <support/Vector.h>
00024 #include <support/KeyedVector.h>
00025 #include <support/Locker.h>
00026
00027 #if _SUPPORTS_NAMESPACE
00028 namespace palmos {
00029 namespace support {
00030 #endif
00031
00036 class SCallTree;
00037
00038 typedef int32_t (*b_demangle_func)( const char *mangled_name,
00039 char *unmangled_name,
00040 size_t buffersize);
00041
00042 enum {
00043 B_CALLSTACK_DEPTH = 32
00044 };
00045
00047 class SCallStack {
00048 public:
00049 SCallStack();
00050 SCallStack(const SCallStack& o);
00051 SCallStack(const SValue &value);
00052 virtual ~SCallStack();
00053
00054 SValue AsValue() const;
00055
00056 SCallStack &operator=(const SCallStack& o);
00057
00058 void Update(int32_t ignoreDepth=0, int32_t maxDepth=B_CALLSTACK_DEPTH);
00059
00060 intptr_t AddressAt(int32_t level) const;
00061 void SPrint(char *buffer) const;
00062 void Print(const sptr<ITextOutput>& io) const;
00063 void LongPrint(const sptr<ITextOutput>& io, b_demangle_func demangler=NULL) const;
00064
00065 bool operator==(const SCallStack& o) const;
00066 inline bool operator!=(const SCallStack& o) const { return !(*this == o); }
00067
00068 int32_t Compare(const SCallStack& o) const;
00069 inline bool operator<(const SCallStack& o) const { return Compare(o) < 0; }
00070 inline bool operator<=(const SCallStack& o) const { return Compare(o) <= 0; }
00071 inline bool operator>=(const SCallStack& o) const { return Compare(o) >= 0; }
00072 inline bool operator>(const SCallStack& o) const { return Compare(o) > 0; }
00073
00074 private:
00075 intptr_t GetCallerAddress(int32_t level) const;
00076
00077 intptr_t m_caller[B_CALLSTACK_DEPTH];
00078 int32_t _reserved[2];
00079 };
00080
00081 inline const sptr<ITextOutput>& operator<<(const sptr<ITextOutput>& io, const SCallStack& stack)
00082 {
00083 stack.Print(io);
00084 return io;
00085 }
00086
00087 class SCallTreeNode {
00088 public:
00089 SCallTreeNode();
00090 virtual ~SCallTreeNode();
00091
00092 void PruneNode();
00093 void ShortReport(const sptr<ITextOutput>& io);
00094 void LongReport(const sptr<ITextOutput>& io, b_demangle_func demangler=NULL,
00095 char *buffer=NULL, int32_t bufferSize=0);
00096
00097 private:
00098 SCallTreeNode(const SCallTreeNode& o);
00099 SCallTreeNode& operator=(const SCallTreeNode& o);
00100
00101 friend class SCallTree;
00102
00103 intptr_t addr;
00104 int32_t count;
00105 SCallTreeNode * higher;
00106 SCallTreeNode * lower;
00107 SCallTreeNode * parent;
00108 SVector<SCallTreeNode*> branches;
00109 };
00110
00111 class SCallTree : public SCallTreeNode {
00112 public:
00113 SCallTree(const char *name);
00114 virtual ~SCallTree();
00115
00116 void Prune();
00117 void AddToTree(SCallStack *stack, const sptr<ITextOutput>& io);
00118 void Report(const sptr<ITextOutput>& io, int32_t count, bool longReport=false);
00119
00120 private:
00121 SCallTree(const SCallTree& o);
00122 SCallTree& operator=(const SCallTree& o);
00123
00124 SCallTreeNode* highest;
00125 SCallTreeNode* lowest;
00126 };
00127
00128
00129 class SStackCounter
00130 {
00131 public:
00132 SStackCounter();
00133 virtual ~SStackCounter();
00134
00135 void Update(int32_t ignoreDepth=0, int32_t maxDepth=B_CALLSTACK_DEPTH);
00136
00137 void Reset();
00138 void Print(const sptr<ITextOutput>& io, size_t maxItems=-1) const;
00139 void LongPrint(const sptr<ITextOutput>& io, size_t maxItems=-1, b_demangle_func demangler=NULL) const;
00140
00141 size_t TotalCount() const;
00142
00143 private:
00144 struct stack_info {
00145 size_t count;
00146 };
00147 mutable SLocker m_lock;
00148 SKeyedVector<SCallStack, stack_info> m_data;
00149 size_t m_totalCount;
00150 };
00151
00152
00155 #if _SUPPORTS_NAMESPACE
00156 } }
00157 #endif
00158
00159 #endif