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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstdio>
00042 #include <cstdint>
00043 #include <cstring>
00044 #else
00045 #include <stdio.h>
00046 #include <stdint.h>
00047 #include <string.h>
00048 #endif
00049 #include <vector>
00050 #if defined _GLIBCXX_HAVE_EXECINFO_H
00051 #include <execinfo.h>
00052 #endif
00053
00054 namespace __gnu_profile
00055 {
00056 typedef const void* __object_t;
00057 typedef void* __instruction_address_t;
00058 typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
00059 typedef __stack_npt* __stack_t;
00060
00061 size_t __stack_max_depth();
00062
00063 inline __stack_t __get_stack()
00064 {
00065 #if defined _GLIBCXX_HAVE_EXECINFO_H
00066 size_t __max_depth = __stack_max_depth();
00067 if (__max_depth == 0)
00068 return NULL;
00069 __stack_npt __buffer(__max_depth);
00070 int __depth = backtrace(&__buffer[0], __max_depth);
00071 __stack_t __stack = new __stack_npt(__depth);
00072 memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
00073 return __stack;
00074 #else
00075 return NULL;
00076 #endif
00077 }
00078
00079 inline __size(const __stack_t& __stack)
00080 {
00081 if (!__stack) {
00082 return 0;
00083 } else {
00084 return __stack->size();
00085 }
00086 }
00087
00088 inline void __write(FILE* __f, const __stack_t __stack)
00089 {
00090 if (!__stack) {
00091 return;
00092 }
00093
00094 __stack_npt::const_iterator __it;
00095 for (__it = __stack->begin(); __it != __stack->end(); ++__it) {
00096 fprintf(__f, "%p ", *__it);
00097 }
00098 }
00099
00100
00101 class __stack_hash
00102 {
00103 public:
00104 size_t operator()(const __stack_t __s) const
00105 {
00106 if (!__s) {
00107 return 0;
00108 }
00109
00110 uintptr_t __index = 0;
00111 __stack_npt::const_iterator __it;
00112 for (__it = __s->begin(); __it != __s->end(); ++__it) {
00113 __index += reinterpret_cast<uintptr_t>(*__it);
00114 }
00115 return __index;
00116 }
00117
00118 bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
00119 {
00120 if (!__stack1 && !__stack2) return true;
00121 if (!__stack1 || !__stack2) return false;
00122 if (__stack1->size() != __stack2->size()) return false;
00123
00124 size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
00125 return memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0;
00126 }
00127 };
00128
00129
00130 class __object_info_base
00131 {
00132 public:
00133 __object_info_base() {}
00134 __object_info_base(__stack_t __stack);
00135 __object_info_base(const __object_info_base& o);
00136 virtual ~__object_info_base() {}
00137 bool __is_valid() const { return _M_valid; }
00138 __stack_t __stack() const { return _M_stack; }
00139 virtual void __write(FILE* f) const = 0;
00140
00141 protected:
00142 __stack_t _M_stack;
00143 bool _M_valid;
00144 };
00145
00146 inline __object_info_base::__object_info_base(__stack_t __stack)
00147 {
00148 _M_stack = __stack;
00149 _M_valid = true;
00150 }
00151
00152 inline __object_info_base::__object_info_base(const __object_info_base& __o)
00153 {
00154 _M_stack = __o._M_stack;
00155 _M_valid = __o._M_valid;
00156 }
00157
00158
00159 template<typename __object_info>
00160 class __stack_info_base
00161 {
00162 public:
00163 __stack_info_base() {}
00164 __stack_info_base(const __object_info& __info) = 0;
00165 virtual ~__stack_info_base() {}
00166 void __merge(const __object_info& __info) = 0;
00167 virtual float __magnitude() const = 0;
00168 virtual const char* __get_id() const = 0;
00169 };
00170
00171 }
00172 #endif