1 // -*- C++ -*- 2 // 3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the terms 7 // of the GNU General Public License as published by the Free Software 8 // Foundation; either version 2, or (at your option) any later 9 // version. 10 11 // This library is distributed in the hope that it will be useful, but 12 // WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License 17 // along with this library; see the file COPYING. If not, write to 18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston, 19 // MA 02111-1307, USA. 20 21 // As a special exception, you may use this file as part of a free 22 // software library without restriction. Specifically, if other files 23 // instantiate templates or use macros or inline functions from this 24 // file, or you compile this file and link it with other files to 25 // produce an executable, this file does not by itself cause the 26 // resulting executable to be covered by the GNU General Public 27 // License. This exception does not however invalidate any other 28 // reasons why the executable file might be covered by the GNU General 29 // Public License. 30 31 /** @file profile/impl/profiler_vector_to_list.h 32 * @brief diagnostics for vector to list. 33 */ 34 35 // Written by Lixia Liu and Silvius Rus. 36 37 #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 38 #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1 39 40 #include "profile/impl/profiler.h" 41 #include "profile/impl/profiler_node.h" 42 #include "profile/impl/profiler_trace.h" 43 44 namespace __gnu_profile 45 { 46 /** @brief A vector-to-list instrumentation line in the object table. */ 47 class __vector2list_info 48 : public __object_info_base 49 { 50 public: 51 __vector2list_info() 52 : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), 53 _M_vector_cost(0), _M_valid(true) { } 54 55 __vector2list_info(__stack_t __stack) 56 : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), 57 _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { } 58 59 virtual ~__vector2list_info() { } 60 61 __vector2list_info(const __vector2list_info& __o) 62 : __object_info_base(__o), _M_shift_count(__o._M_shift_count), 63 _M_iterate(__o._M_iterate), _M_resize(__o._M_resize), 64 _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost), 65 _M_valid(__o._M_valid) { } 66 67 void 68 __merge(const __vector2list_info& __o) 69 { 70 _M_shift_count += __o._M_shift_count; 71 _M_iterate += __o._M_iterate; 72 _M_vector_cost += __o._M_vector_cost; 73 _M_list_cost += __o._M_list_cost; 74 _M_valid &= __o._M_valid; 75 _M_resize += __o._M_resize; 76 } 77 78 void 79 __write(FILE* __f) const 80 { 81 std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, 82 _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); 83 } 84 85 float 86 __magnitude() const 87 { return _M_vector_cost - _M_list_cost; } 88 89 std::string 90 __advice() const 91 { return "change std::vector to std::list"; } 92 93 std::size_t 94 __shift_count() 95 { return _M_shift_count; } 96 97 std::size_t 98 __iterate() 99 { return _M_iterate; } 100 101 float 102 __list_cost() 103 { return _M_list_cost; } 104 105 std::size_t 106 __resize() 107 { return _M_resize; } 108 109 void 110 __set_list_cost(float __lc) 111 { _M_list_cost = __lc; } 112 113 void 114 __set_vector_cost(float __vc) 115 { _M_vector_cost = __vc; } 116 117 bool 118 __is_valid() 119 { return _M_valid; } 120 121 void 122 __set_invalid() 123 { _M_valid = false; } 124 125 void 126 __opr_insert(std::size_t __pos, std::size_t __num) 127 { _M_shift_count += __num - __pos; } 128 129 void 130 __opr_iterate(std::size_t __num) 131 { _M_iterate += __num; } 132 133 void 134 __resize(std::size_t __from, std::size_t) 135 { _M_resize += __from; } 136 137 void 138 __opr_find(std::size_t __size) 139 { 140 // Use average case complexity. 141 _M_iterate += 3.0 / 4.0 * __size; 142 } 143 144 private: 145 std::size_t _M_shift_count; 146 std::size_t _M_iterate; 147 std::size_t _M_resize; 148 float _M_list_cost; 149 float _M_vector_cost; 150 bool _M_valid; 151 }; 152 153 154 /** @brief A vector-to-list instrumentation line in the stack table. */ 155 class __vector2list_stack_info 156 : public __vector2list_info 157 { 158 public: 159 __vector2list_stack_info(const __vector2list_info& __o) 160 : __vector2list_info(__o) { } 161 }; 162 163 164 /** @brief Vector-to-list instrumentation producer. */ 165 class __trace_vector_to_list 166 : public __trace_base<__vector2list_info, __vector2list_stack_info> 167 { 168 public: 169 __trace_vector_to_list() 170 : __trace_base<__vector2list_info, __vector2list_stack_info>() 171 { __id = "vector-to-list"; } 172 173 ~__trace_vector_to_list() { } 174 175 // Insert a new node at construct with object, callstack and initial size. 176 void 177 __insert(__object_t __obj, __stack_t __stack) 178 { __add_object(__obj, __vector2list_info(__stack)); } 179 180 // Call at destruction/clean to set container final size. 181 void 182 __destruct(const void* __obj) 183 { 184 if (!__is_on()) 185 return; 186 187 __vector2list_info* __res = __get_object_info(__obj); 188 if (!__res) 189 return; 190 191 float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(), 192 __res->__resize()); 193 float __lc = __list_cost(__res->__shift_count(), __res->__iterate(), 194 __res->__resize()); 195 __res->__set_vector_cost(__vc); 196 __res->__set_list_cost(__lc); 197 198 __retire_object(__obj); 199 } 200 201 // Find the node in the live map. 202 // XXX Undefined?!? 203 __vector2list_info* __find(const void* __obj); 204 205 // Collect cost of operations. 206 void 207 __opr_insert(const void* __obj, std::size_t __pos, std::size_t __num) 208 { 209 __vector2list_info* __res = __get_object_info(__obj); 210 if (__res) 211 __res->__opr_insert(__pos, __num); 212 } 213 214 void 215 __opr_iterate(const void* __obj, std::size_t __num) 216 { 217 __vector2list_info* __res = __get_object_info(__obj); 218 if (__res) 219 __res->__opr_iterate(__num); 220 } 221 222 void 223 __invalid_operator(const void* __obj) 224 { 225 __vector2list_info* __res = __get_object_info(__obj); 226 if (__res) 227 __res->__set_invalid(); 228 } 229 230 void 231 __resize(const void* __obj, std::size_t __from, std::size_t __to) 232 { 233 __vector2list_info* __res = __get_object_info(__obj); 234 if (__res) 235 __res->__resize(__from, __to); 236 } 237 238 float 239 __vector_cost(std::size_t __shift, std::size_t __iterate, 240 std::size_t __resize) 241 { 242 return (__shift 243 * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value 244 + __iterate 245 * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value 246 + __resize 247 * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value); 248 } 249 250 float 251 __list_cost(std::size_t __shift, std::size_t __iterate, 252 std::size_t __resize) 253 { 254 return (__shift 255 * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value 256 + __iterate 257 * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value 258 + __resize 259 * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value); 260 } 261 262 void 263 __opr_find(const void* __obj, std::size_t __size) 264 { 265 __vector2list_info* __res = __get_object_info(__obj); 266 if (__res) 267 __res->__opr_find(__size); 268 } 269 }; 270 271 272 inline void 273 __trace_vector_to_list_init() 274 { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); } 275 276 inline void 277 __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings) 278 { 279 if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list)) 280 { 281 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)-> 282 __collect_warnings(__warnings); 283 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f); 284 } 285 } 286 287 inline void 288 __trace_vector_to_list_construct(const void* __obj) 289 { 290 if (!__profcxx_init()) 291 return; 292 293 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack()); 294 } 295 296 inline void 297 __trace_vector_to_list_destruct(const void* __obj) 298 { 299 if (!__profcxx_init()) 300 return; 301 302 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj); 303 } 304 305 inline void 306 __trace_vector_to_list_insert(const void* __obj, std::size_t __pos, 307 std::size_t __num) 308 { 309 if (!__profcxx_init()) 310 return; 311 312 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos, 313 __num); 314 } 315 316 inline void 317 __trace_vector_to_list_iterate(const void* __obj, std::size_t __num = 1) 318 { 319 if (!__profcxx_init()) 320 return; 321 322 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num); 323 } 324 325 inline void 326 __trace_vector_to_list_invalid_operator(const void* __obj) 327 { 328 if (!__profcxx_init()) 329 return; 330 331 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj); 332 } 333 334 inline void 335 __trace_vector_to_list_resize(const void* __obj, std::size_t __from, 336 std::size_t __to) 337 { 338 if (!__profcxx_init()) 339 return; 340 341 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to); 342 } 343 344 inline void 345 __trace_vector_to_list_find(const void* __obj, std::size_t __size) 346 { 347 if (!__profcxx_init()) 348 return; 349 350 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size); 351 } 352 353 } // namespace __gnu_profile 354 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */ 355