libstdc++
profiler_list_to_vector.h
Go to the documentation of this file.
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__ */