Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H
00038 #define _GLIBCXX_PROFILE_PROFILER_NODE_H 1
00039
00040 #include <cstdio>
00041
00042 #include <vector>
00043 #if defined _GLIBCXX_HAVE_EXECINFO_H
00044 #include <execinfo.h>
00045 #endif
00046
00047 namespace __gnu_profile
00048 {
00049 typedef const void* __object_t;
00050 typedef void* __instruction_address_t;
00051 typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt;
00052 typedef __stack_npt* __stack_t;
00053
00054 std::size_t __stack_max_depth();
00055
00056 inline __stack_t
00057 __get_stack()
00058 {
00059 #if defined _GLIBCXX_HAVE_EXECINFO_H
00060 std::size_t __max_depth = __stack_max_depth();
00061 if (__max_depth == 0)
00062 return 0;
00063 __stack_npt __buffer(__max_depth);
00064 int __depth = backtrace(&__buffer[0], __max_depth);
00065 __stack_t __stack = new __stack_npt(__depth);
00066 __builtin_memcpy(&(*__stack)[0], &__buffer[0],
00067 __depth * sizeof(__object_t));
00068 return __stack;
00069 #else
00070 return 0;
00071 #endif
00072 }
00073
00074 inline std::size_t
00075 __size(__stack_t __stack)
00076 {
00077 if (!__stack)
00078 return 0;
00079 else
00080 return __stack->size();
00081 }
00082
00083
00084 inline void
00085 __write(FILE* __f, __stack_t __stack)
00086 {
00087 if (!__stack)
00088 return;
00089
00090 __stack_npt::const_iterator __it;
00091 for (__it = __stack->begin(); __it != __stack->end(); ++__it)
00092 std::fprintf(__f, "%p ", *__it);
00093 }
00094
00095
00096 class __stack_hash
00097 {
00098 public:
00099 std::size_t
00100 operator()(__stack_t __s) const
00101 {
00102 if (!__s)
00103 return 0;
00104
00105 __UINTPTR_TYPE__ __index = 0;
00106 __stack_npt::const_iterator __it;
00107 for (__it = __s->begin(); __it != __s->end(); ++__it)
00108 __index += reinterpret_cast<__UINTPTR_TYPE__>(*__it);
00109 return __index;
00110 }
00111
00112 bool operator() (__stack_t __stack1, __stack_t __stack2) const
00113 {
00114 if (!__stack1 && !__stack2)
00115 return true;
00116 if (!__stack1 || !__stack2)
00117 return false;
00118 if (__stack1->size() != __stack2->size())
00119 return false;
00120
00121 std::size_t __byte_size
00122 = __stack1->size() * sizeof(__stack_npt::value_type);
00123 return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0],
00124 __byte_size) == 0;
00125 }
00126 };
00127
00128
00129
00130 class __object_info_base
00131 {
00132 public:
00133 __object_info_base() { }
00134
00135 __object_info_base(__stack_t __stack)
00136 : _M_stack(__stack), _M_valid(true) { }
00137
00138 __object_info_base(const __object_info_base& __o)
00139 : _M_stack(__o._M_stack), _M_valid(__o._M_valid) { }
00140
00141 virtual ~__object_info_base() { }
00142
00143 bool
00144 __is_valid() const
00145 { return _M_valid; }
00146
00147 __stack_t
00148 __stack() const
00149 { return _M_stack; }
00150
00151 virtual void __write(FILE* __f) const = 0;
00152
00153 protected:
00154 __stack_t _M_stack;
00155 bool _M_valid;
00156 };
00157
00158
00159
00160 template<typename __object_info>
00161 class __stack_info_base
00162 {
00163 public:
00164 __stack_info_base() { }
00165 __stack_info_base(const __object_info& __info) = 0;
00166 virtual ~__stack_info_base() {}
00167 void __merge(const __object_info& __info) = 0;
00168 virtual float __magnitude() const = 0;
00169 virtual const char* __get_id() const = 0;
00170 };
00171
00172 }
00173 #endif