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_CONTAINER_SIZE_H
00038 #define _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H 1
00039
00040 #include <sstream>
00041
00042 #include "profile/impl/profiler.h"
00043 #include "profile/impl/profiler_node.h"
00044 #include "profile/impl/profiler_trace.h"
00045
00046 namespace __gnu_profile
00047 {
00048
00049 class __container_size_info
00050 : public __object_info_base
00051 {
00052 public:
00053 __container_size_info()
00054 : _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0),
00055 _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
00056 { }
00057
00058 __container_size_info(const __container_size_info& __o)
00059 : __object_info_base(__o), _M_init(__o._M_init), _M_max(__o._M_max),
00060 _M_min(__o._M_min), _M_total(__o._M_total),
00061 _M_item_min(__o._M_item_min), _M_item_max(__o._M_item_max),
00062 _M_item_total(__o._M_item_total), _M_count(__o._M_count),
00063 _M_resize(__o._M_resize), _M_cost(__o._M_cost)
00064 { }
00065
00066 __container_size_info(__stack_t __stack, std::size_t __num)
00067 : __object_info_base(__stack), _M_init(__num), _M_max(__num),
00068 _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0),
00069 _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
00070 { }
00071
00072 virtual ~__container_size_info() { }
00073
00074 void
00075 __write(FILE* __f) const
00076 {
00077 std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
00078 _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max,
00079 _M_total, _M_item_min, _M_item_max, _M_item_total);
00080 }
00081
00082 float
00083 __magnitude() const
00084 { return static_cast<float>(_M_cost); }
00085
00086 std::string
00087 __advice() const
00088 {
00089 std::stringstream __message;
00090 if (_M_init < _M_item_max)
00091 __message << "change initial container size from " << _M_init
00092 << " to " << _M_item_max;
00093 return __message.str();
00094 }
00095
00096 void
00097 __merge(const __container_size_info& __o)
00098 {
00099 _M_init = std::max(_M_init, __o._M_init);
00100 _M_max = std::max(_M_max, __o._M_max);
00101 _M_item_max = std::max(_M_item_max, __o._M_item_max);
00102 _M_min = std::min(_M_min, __o._M_min);
00103 _M_item_min = std::min(_M_item_min, __o._M_item_min);
00104 _M_total += __o._M_total;
00105 _M_item_total += __o._M_item_total;
00106 _M_count += __o._M_count;
00107 _M_cost += __o._M_cost;
00108 _M_resize += __o._M_resize;
00109 }
00110
00111
00112 void
00113 __destruct(std::size_t __num, std::size_t __inum)
00114 {
00115 _M_max = std::max(_M_max, __num);
00116 _M_item_max = std::max(_M_item_max, __inum);
00117 if (_M_min == 0)
00118 {
00119 _M_min = __num;
00120 _M_item_min = __inum;
00121 }
00122 else
00123 {
00124 _M_min = std::min(_M_min, __num);
00125 _M_item_min = std::min(_M_item_min, __inum);
00126 }
00127 _M_total += __num;
00128 _M_item_total += __inum;
00129 _M_count += 1;
00130 }
00131
00132
00133 float
00134 __resize_cost(std::size_t __from, std::size_t)
00135 { return __from; }
00136
00137
00138 void
00139 __resize(std::size_t __from, std::size_t __to)
00140 {
00141 _M_cost += this->__resize_cost(__from, __to);
00142 _M_resize += 1;
00143 _M_max = std::max(_M_max, __to);
00144 }
00145
00146 private:
00147 std::size_t _M_init;
00148 std::size_t _M_max;
00149 std::size_t _M_min;
00150 std::size_t _M_total;
00151 std::size_t _M_item_min;
00152 std::size_t _M_item_max;
00153 std::size_t _M_item_total;
00154 std::size_t _M_count;
00155 std::size_t _M_resize;
00156 std::size_t _M_cost;
00157 };
00158
00159
00160
00161 class __container_size_stack_info
00162 : public __container_size_info
00163 {
00164 public:
00165 __container_size_stack_info(const __container_size_info& __o)
00166 : __container_size_info(__o) { }
00167 };
00168
00169
00170
00171 class __trace_container_size
00172 : public __trace_base<__container_size_info, __container_size_stack_info>
00173 {
00174 public:
00175 ~__trace_container_size() { }
00176
00177 __trace_container_size()
00178 : __trace_base<__container_size_info, __container_size_stack_info>() { };
00179
00180
00181 void
00182 __insert(const __object_t __obj, __stack_t __stack, std::size_t __num)
00183 { __add_object(__obj, __container_size_info(__stack, __num)); }
00184
00185
00186 void
00187 __construct(const void* __obj, std::size_t __inum);
00188
00189
00190 void
00191 __destruct(const void* __obj, std::size_t __num, std::size_t __inum)
00192 {
00193 if (!__is_on())
00194 return;
00195
00196 __object_t __obj_handle = static_cast<__object_t>(__obj);
00197
00198 __container_size_info* __object_info = __get_object_info(__obj_handle);
00199 if (!__object_info)
00200 return;
00201
00202 __object_info->__destruct(__num, __inum);
00203 __retire_object(__obj_handle);
00204 }
00205
00206
00207 void
00208 __resize(const void* __obj, int __from, int __to)
00209 {
00210 if (!__is_on())
00211 return;
00212
00213 __container_size_info* __object_info = __get_object_info(__obj);
00214 if (!__object_info)
00215 return;
00216
00217 __object_info->__resize(__from, __to);
00218 }
00219 };
00220
00221 }
00222 #endif