libstdc++
|
00001 // -*- C++ -*- 00002 // 00003 // Copyright (C) 2009, 2010 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 // 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License along 00021 // with this library; see the file COPYING3. If not see 00022 // <http://www.gnu.org/licenses/>. 00023 00024 /** @file profile/impl/profiler_list_to_vector.h 00025 * @brief diagnostics for list to vector. 00026 */ 00027 00028 // Written by Changhee Jung. 00029 00030 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 00031 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1 00032 00033 #include <sstream> 00034 00035 #include "profile/impl/profiler.h" 00036 #include "profile/impl/profiler_node.h" 00037 #include "profile/impl/profiler_trace.h" 00038 00039 namespace __gnu_profile 00040 { 00041 /** @brief A list-to-vector instrumentation line in the object table. */ 00042 class __list2vector_info 00043 : public __object_info_base 00044 { 00045 public: 00046 __list2vector_info() 00047 : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), 00048 _M_vector_cost(0), _M_valid(true), _M_max_size(0) { } 00049 00050 __list2vector_info(__stack_t __stack) 00051 : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), 00052 _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true), 00053 _M_max_size(0) { } 00054 00055 virtual ~__list2vector_info() { } 00056 00057 __list2vector_info(const __list2vector_info& __o) 00058 : __object_info_base(__o), _M_shift_count(__o._M_shift_count), 00059 _M_iterate(__o._M_iterate), _M_resize(__o._M_resize), 00060 _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost), 00061 _M_valid(__o._M_valid), _M_max_size(__o._M_max_size) { } 00062 00063 void 00064 __merge(const __list2vector_info& __o) 00065 { 00066 _M_shift_count += __o._M_shift_count; 00067 _M_iterate += __o._M_iterate; 00068 _M_vector_cost += __o._M_vector_cost; 00069 _M_list_cost += __o._M_list_cost; 00070 _M_valid &= __o._M_valid; 00071 _M_resize += __o._M_resize; 00072 _M_max_size = std::max( _M_max_size, __o._M_max_size); 00073 } 00074 00075 void 00076 __write(FILE* __f) const 00077 { 00078 std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, 00079 _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); 00080 } 00081 00082 float 00083 __magnitude() const 00084 { return _M_list_cost - _M_vector_cost; } 00085 00086 std::string 00087 __advice() const 00088 { 00089 std::stringstream __sstream; 00090 __sstream 00091 << "change std::list to std::vector and its initial size from 0 to " 00092 << _M_max_size; 00093 return __sstream.str(); 00094 } 00095 00096 std::size_t 00097 __shift_count() 00098 { return _M_shift_count; } 00099 00100 std::size_t 00101 __iterate() 00102 { return _M_iterate; } 00103 00104 float 00105 __list_cost() 00106 { return _M_list_cost; } 00107 00108 std::size_t 00109 __resize() 00110 { return _M_resize; } 00111 00112 void 00113 __set_list_cost(float __lc) 00114 { _M_list_cost = __lc; } 00115 00116 void 00117 __set_vector_cost(float __vc) 00118 { _M_vector_cost = __vc; } 00119 00120 bool 00121 __is_valid() 00122 { return _M_valid; } 00123 00124 void 00125 __set_invalid() 00126 { _M_valid = false; } 00127 00128 void 00129 __opr_insert(std::size_t __shift, std::size_t __size) 00130 { 00131 _M_shift_count += __shift; 00132 _M_max_size = std::max(_M_max_size, __size); 00133 } 00134 00135 void 00136 __opr_iterate(std::size_t __num) 00137 { _M_iterate += __num;} 00138 00139 void 00140 __resize(std::size_t __from, std::size_t) 00141 { _M_resize += __from; } 00142 00143 private: 00144 std::size_t _M_shift_count; 00145 std::size_t _M_iterate; 00146 std::size_t _M_resize; 00147 float _M_list_cost; 00148 float _M_vector_cost; 00149 bool _M_valid; 00150 std::size_t _M_max_size; 00151 }; 00152 00153 class __list2vector_stack_info 00154 : public __list2vector_info 00155 { 00156 public: 00157 __list2vector_stack_info(const __list2vector_info& __o) 00158 : __list2vector_info(__o) {} 00159 }; 00160 00161 class __trace_list_to_vector 00162 : public __trace_base<__list2vector_info, __list2vector_stack_info> 00163 { 00164 public: 00165 __trace_list_to_vector() 00166 : __trace_base<__list2vector_info, __list2vector_stack_info>() 00167 { __id = "list-to-vector"; } 00168 00169 ~__trace_list_to_vector() { } 00170 00171 // Insert a new node at construct with object, callstack and initial size. 00172 void 00173 __insert(__object_t __obj, __stack_t __stack) 00174 { __add_object(__obj, __list2vector_info(__stack)); } 00175 00176 // Call at destruction/clean to set container final size. 00177 void 00178 __destruct(const void* __obj) 00179 { 00180 if (!__is_on()) 00181 return; 00182 00183 __list2vector_info* __res = __get_object_info(__obj); 00184 if (!__res) 00185 return; 00186 00187 float __vc = __vector_cost(__res->__shift_count(), __res->__iterate()); 00188 float __lc = __list_cost(__res->__shift_count(), __res->__iterate()); 00189 __res->__set_vector_cost(__vc); 00190 __res->__set_list_cost(__lc); 00191 __retire_object(__obj); 00192 } 00193 00194 // Find the node in the live map. 00195 __list2vector_info* __find(const void* __obj); 00196 00197 // Collect cost of operations. 00198 void 00199 __opr_insert(const void* __obj, std::size_t __shift, std::size_t __size) 00200 { 00201 __list2vector_info* __res = __get_object_info(__obj); 00202 if (__res) 00203 __res->__opr_insert(__shift, __size); 00204 } 00205 00206 void 00207 __opr_iterate(const void* __obj, std::size_t __num) 00208 { 00209 __list2vector_info* __res = __get_object_info(__obj); 00210 if (__res) 00211 __res->__opr_iterate(__num); 00212 } 00213 00214 void 00215 __invalid_operator(const void* __obj) 00216 { 00217 __list2vector_info* __res = __get_object_info(__obj); 00218 if (__res) 00219 __res->__set_invalid(); 00220 } 00221 00222 void 00223 __resize(const void* __obj, std::size_t __from, std::size_t __to) 00224 { 00225 __list2vector_info* __res = __get_object_info(__obj); 00226 if (__res) 00227 __res->__resize(__from, __to); 00228 } 00229 00230 float 00231 __vector_cost(std::size_t __shift, std::size_t __iterate) 00232 { 00233 // The resulting vector will use a 'reserve' method. 00234 return (__shift 00235 * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value 00236 + __iterate 00237 * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value); 00238 } 00239 00240 float 00241 __list_cost(std::size_t __shift, std::size_t __iterate) 00242 { 00243 return (__shift 00244 * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value 00245 + __iterate 00246 * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value); 00247 } 00248 }; 00249 00250 00251 inline void 00252 __trace_list_to_vector_init() 00253 { _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); } 00254 00255 inline void 00256 __trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings) 00257 { 00258 if (_GLIBCXX_PROFILE_DATA(_S_list_to_vector)) 00259 { 00260 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)-> 00261 __collect_warnings(__warnings); 00262 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__write(__f); 00263 } 00264 } 00265 00266 inline void 00267 __trace_list_to_vector_construct(const void* __obj) 00268 { 00269 if (!__profcxx_init()) 00270 return; 00271 00272 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack()); 00273 } 00274 00275 inline void 00276 __trace_list_to_vector_destruct(const void* __obj) 00277 { 00278 if (!__profcxx_init()) 00279 return; 00280 00281 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj); 00282 } 00283 00284 inline void 00285 __trace_list_to_vector_insert(const void* __obj, 00286 std::size_t __shift, std::size_t __size) 00287 { 00288 if (!__profcxx_init()) 00289 return; 00290 00291 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift, 00292 __size); 00293 } 00294 00295 inline void 00296 __trace_list_to_vector_iterate(const void* __obj, std::size_t __num = 1) 00297 { 00298 if (!__profcxx_init()) 00299 return; 00300 00301 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num); 00302 } 00303 00304 inline void 00305 __trace_list_to_vector_invalid_operator(const void* __obj) 00306 { 00307 if (!__profcxx_init()) 00308 return; 00309 00310 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj); 00311 } 00312 00313 inline void 00314 __trace_list_to_vector_resize(const void* __obj, 00315 std::size_t __from, std::size_t __to) 00316 { 00317 if (!__profcxx_init()) 00318 return; 00319 00320 _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to); 00321 } 00322 00323 } // namespace __gnu_profile 00324 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */