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