profiler_vector_to_list.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Copyright (C) 2009 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 terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 2, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this library; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00019 // MA 02111-1307, USA.
00020 
00021 // As a special exception, you may use this file as part of a free
00022 // software library without restriction.  Specifically, if other files
00023 // instantiate templates or use macros or inline functions from this
00024 // file, or you compile this file and link it with other files to
00025 // produce an executable, this file does not by itself cause the
00026 // resulting executable to be covered by the GNU General Public
00027 // License.  This exception does not however invalidate any other
00028 // reasons why the executable file might be covered by the GNU General
00029 // Public License.
00030 
00031 /** @file profile/impl/profiler_vector_to_list.h
00032  *  @brief diagnostics for vector to list.
00033  */
00034 
00035 // Written by Lixia Liu and Silvius Rus.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H
00038 #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1
00039 
00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstdio>
00042 #include <cstdlib>
00043 #include <cstring>
00044 #else
00045 #include <stdio.h>
00046 #include <stdint.h>
00047 #include <string.h>
00048 #endif
00049 #include "profile/impl/profiler.h"
00050 #include "profile/impl/profiler_node.h"
00051 #include "profile/impl/profiler_trace.h"
00052 
00053 namespace __gnu_profile
00054 {
00055 
00056 /** @brief A vector-to-list instrumentation line in the object table.  */
00057 class __vector2list_info: public __object_info_base
00058 {
00059  public:
00060   __vector2list_info()
00061       :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
00062        _M_vector_cost(0), _M_valid(true) {}
00063   __vector2list_info(__stack_t __stack)
00064       : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
00065         _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) {} 
00066   virtual ~__vector2list_info() {}
00067   __vector2list_info(const __vector2list_info& __o);
00068   void __merge(const __vector2list_info& __o);
00069   void __write(FILE* __f) const;
00070   float __magnitude() const { return _M_vector_cost - _M_list_cost; }
00071   const char* __advice() const 
00072   { return strdup("change std::vector to std::list"); }
00073 
00074   size_t __shift_count() { return _M_shift_count; }
00075   size_t __iterate()   { return _M_iterate; }
00076   float __list_cost() { return _M_list_cost; }
00077   size_t __resize() { return _M_resize; }
00078   void __set_list_cost(float __lc) { _M_list_cost = __lc; }
00079   void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
00080   bool __is_valid() { return _M_valid; }
00081   void __set_invalid() { _M_valid = false; }
00082 
00083   void __opr_insert(size_t __pos, size_t __num);
00084   void __opr_iterate(size_t __num);
00085   void __resize(size_t __from, size_t __to);
00086   void __opr_find(size_t __size);
00087 
00088 private:
00089   size_t _M_shift_count;
00090   size_t _M_iterate;
00091   size_t _M_resize;
00092   float _M_list_cost;
00093   float _M_vector_cost;
00094   bool  _M_valid;
00095 };
00096 
00097 inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
00098     : __object_info_base(__o)
00099 {
00100   _M_shift_count  = __o._M_shift_count;
00101   _M_iterate      = __o._M_iterate;
00102   _M_vector_cost  = __o._M_vector_cost;
00103   _M_list_cost    = __o._M_list_cost;
00104   _M_valid        = __o._M_valid;
00105   _M_resize       = __o._M_resize;
00106 }
00107 
00108 inline void __vector2list_info::__merge(const __vector2list_info& __o)
00109 {
00110   _M_shift_count  += __o._M_shift_count;
00111   _M_iterate      += __o._M_iterate;
00112   _M_vector_cost  += __o._M_vector_cost;
00113   _M_list_cost    += __o._M_list_cost;
00114   _M_valid        &= __o._M_valid;
00115   _M_resize       += __o._M_resize;
00116 }
00117 
00118 inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num)
00119 {
00120   _M_shift_count += __num - __pos;
00121 }
00122 
00123 inline void __vector2list_info::__resize(size_t __from, size_t __to)
00124 {
00125   _M_resize += __from;
00126 }
00127 
00128 inline void __vector2list_info::__opr_iterate(size_t __num)
00129 { 
00130   _M_iterate += __num; 
00131 }
00132 
00133 inline void __vector2list_info::__opr_find(size_t __size)
00134 {
00135   // Use average case complexity.
00136   _M_iterate += 3.0 / 4.0 * __size;
00137 }
00138 
00139 /** @brief A vector-to-list instrumentation line in the stack table.  */
00140 class __vector2list_stack_info: public __vector2list_info {
00141  public:
00142   __vector2list_stack_info(const __vector2list_info& __o) 
00143       : __vector2list_info(__o) {}
00144 };
00145 
00146 /** @brief Vector-to-list instrumentation producer.  */
00147 class __trace_vector_to_list
00148     : public __trace_base<__vector2list_info, __vector2list_stack_info> 
00149 {
00150  public:
00151   __trace_vector_to_list();
00152   ~__trace_vector_to_list() {}
00153 
00154   // Insert a new node at construct with object, callstack and initial size. 
00155   void __insert(__object_t __obj, __stack_t __stack);
00156   // Call at destruction/clean to set container final size.
00157   void __destruct(const void* __obj);
00158 
00159   // Find the node in the live map.
00160   __vector2list_info* __find(const void* __obj);
00161 
00162   // Collect cost of operations.
00163   void __opr_insert(const void* __obj, size_t __pos, size_t __num);
00164   void __opr_iterate(const void* __obj, size_t __num);
00165   void __invalid_operator(const void* __obj);
00166   void __resize(const void* __obj, size_t __from, size_t __to);
00167   float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
00168   float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
00169   void __opr_find(const void* __obj, size_t __size);
00170 };
00171 
00172 inline __trace_vector_to_list::__trace_vector_to_list()
00173     : __trace_base<__vector2list_info, __vector2list_stack_info>()
00174 {
00175   __id = "vector-to-list";
00176 }
00177 
00178 inline void __trace_vector_to_list::__insert(__object_t __obj,
00179                                              __stack_t __stack)
00180 {
00181   __add_object(__obj, __vector2list_info(__stack));
00182 }
00183 
00184 inline void __vector2list_info::__write(FILE* __f) const
00185 {
00186   fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
00187           _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
00188 }
00189 
00190 inline float __trace_vector_to_list::__vector_cost(size_t __shift, 
00191                                                    size_t __iterate,
00192                                                    size_t __resize)
00193 {
00194   return (
00195       __shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
00196       + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
00197       + __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value
00198       );
00199 }
00200 
00201 inline float __trace_vector_to_list::__list_cost(size_t __shift, 
00202                                                  size_t __iterate,
00203                                                  size_t __resize)
00204 {
00205   return (
00206       __shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
00207       + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
00208       + __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
00209 }
00210 
00211 inline void __trace_vector_to_list::__destruct(const void* __obj)
00212 {
00213   if (!__is_on())
00214     return;
00215 
00216  __vector2list_info* __res = __get_object_info(__obj);
00217   if (!__res)
00218     return;
00219 
00220   float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
00221                              __res->__resize());
00222   float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
00223                            __res->__resize());
00224   __res->__set_vector_cost(__vc);
00225   __res->__set_list_cost(__lc);
00226 
00227   __retire_object(__obj);
00228 }
00229 
00230 inline void __trace_vector_to_list::__opr_insert(const void* __obj, 
00231                                                  size_t __pos, size_t __num)
00232 {
00233   __vector2list_info* __res = __get_object_info(__obj);
00234   if (__res)
00235     __res->__opr_insert(__pos, __num);
00236 }
00237 
00238 inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
00239                                                   size_t __num)
00240 {
00241   __vector2list_info* __res = __get_object_info(__obj);
00242   if (__res)
00243     __res->__opr_iterate(__num);
00244 }
00245 
00246 inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
00247 {
00248   __vector2list_info* __res = __get_object_info(__obj);
00249   if (__res)
00250     __res->__set_invalid();
00251 }
00252 
00253 inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from, 
00254                                              size_t __to)
00255 {
00256   __vector2list_info* __res = __get_object_info(__obj);
00257   if (__res)
00258     __res->__resize(__from, __to);
00259 }
00260 
00261 inline void __trace_vector_to_list::__opr_find(const void* __obj,
00262                                                size_t __size)
00263 {
00264   __vector2list_info* __res = __get_object_info(__obj);
00265   if (__res)
00266     __res->__opr_find(__size);
00267 }
00268 
00269 inline void __trace_vector_to_list_init()
00270 {
00271   _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list();
00272 }
00273 
00274 inline void __trace_vector_to_list_report(FILE* __f, 
00275                                           __warning_vector_t& __warnings)
00276 {
00277   if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list)) {
00278     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__collect_warnings(__warnings);
00279     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
00280   }
00281 }
00282 
00283 inline void __trace_vector_to_list_construct(const void* __obj)
00284 {
00285   if (!__profcxx_init()) return;
00286 
00287   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
00288 }
00289 
00290 inline void __trace_vector_to_list_destruct(const void* __obj)
00291 {
00292   if (!__profcxx_init()) return;
00293 
00294   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
00295 }
00296 
00297 inline void __trace_vector_to_list_insert(const void* __obj, 
00298                                           size_t __pos, size_t __num)
00299 {
00300   if (!__profcxx_init()) return;
00301 
00302   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos, __num);
00303 }
00304 
00305 
00306 inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num = 1)
00307 {
00308   if (!__profcxx_init()) return;
00309 
00310   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
00311 }
00312 
00313 inline void __trace_vector_to_list_invalid_operator(const void* __obj)
00314 {
00315   if (!__profcxx_init()) return;
00316 
00317   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
00318 }
00319 
00320 inline void __trace_vector_to_list_resize(const void* __obj, 
00321                                           size_t __from, size_t __to)
00322 {
00323   if (!__profcxx_init()) return;
00324 
00325   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
00326 }
00327 
00328 inline void __trace_vector_to_list_find(const void* __obj, size_t __size)
00329 {
00330   if (!__profcxx_init()) return;
00331 
00332   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
00333 }
00334 
00335 } // namespace __gnu_profile
00336 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */