libstdc++
profiler_vector_to_list.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 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 #include "profile/impl/profiler.h"
00041 #include "profile/impl/profiler_node.h"
00042 #include "profile/impl/profiler_trace.h"
00043 
00044 namespace __gnu_profile
00045 {
00046   /** @brief A vector-to-list instrumentation line in the object table.  */
00047   class __vector2list_info
00048   : public __object_info_base
00049   {
00050   public:
00051     __vector2list_info()
00052     : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
00053       _M_vector_cost(0), _M_valid(true) { }
00054 
00055     __vector2list_info(__stack_t __stack)
00056     : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
00057       _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { }
00058 
00059     virtual ~__vector2list_info() { }
00060 
00061     __vector2list_info(const __vector2list_info& __o)
00062     : __object_info_base(__o), _M_shift_count(__o._M_shift_count),
00063       _M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
00064       _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
00065       _M_valid(__o._M_valid) { }
00066 
00067     void
00068     __merge(const __vector2list_info& __o)
00069     {
00070       _M_shift_count  += __o._M_shift_count;
00071       _M_iterate      += __o._M_iterate;
00072       _M_vector_cost  += __o._M_vector_cost;
00073       _M_list_cost    += __o._M_list_cost;
00074       _M_valid        &= __o._M_valid;
00075       _M_resize       += __o._M_resize;
00076     }
00077 
00078     void
00079     __write(FILE* __f) const
00080     {
00081       std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count,
00082            _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
00083     }
00084 
00085     float
00086     __magnitude() const
00087     { return _M_vector_cost - _M_list_cost; }
00088 
00089     std::string
00090     __advice() const 
00091     { return "change std::vector to std::list"; }
00092 
00093     std::size_t
00094     __shift_count()
00095     { return _M_shift_count; }
00096 
00097     std::size_t
00098     __iterate()
00099     { return _M_iterate; }
00100 
00101     float
00102     __list_cost()
00103     { return _M_list_cost; }
00104 
00105     std::size_t
00106     __resize()
00107     { return _M_resize; }
00108 
00109     void
00110     __set_list_cost(float __lc)
00111     { _M_list_cost = __lc; }
00112     
00113     void
00114     __set_vector_cost(float __vc)
00115     { _M_vector_cost = __vc; }
00116     
00117     bool
00118     __is_valid()
00119     { return _M_valid; }
00120     
00121     void
00122     __set_invalid()
00123     { _M_valid = false; }
00124 
00125     void
00126     __opr_insert(std::size_t __pos, std::size_t __num)
00127     { _M_shift_count += __num - __pos; }
00128 
00129     void
00130     __opr_iterate(std::size_t __num)
00131     { _M_iterate += __num; }
00132 
00133     void
00134     __resize(std::size_t __from, std::size_t)
00135     { _M_resize += __from; }
00136 
00137     void
00138     __opr_find(std::size_t __size)
00139     {
00140       // Use average case complexity.
00141       _M_iterate += 3.0 / 4.0 * __size;
00142     }
00143 
00144   private:
00145     std::size_t _M_shift_count;
00146     std::size_t _M_iterate;
00147     std::size_t _M_resize;
00148     float _M_list_cost;
00149     float _M_vector_cost;
00150     bool  _M_valid;
00151   };
00152 
00153 
00154   /** @brief A vector-to-list instrumentation line in the stack table.  */
00155   class __vector2list_stack_info
00156   : public __vector2list_info
00157   {
00158   public:
00159     __vector2list_stack_info(const __vector2list_info& __o) 
00160     : __vector2list_info(__o) { }
00161   };
00162 
00163 
00164   /** @brief Vector-to-list instrumentation producer.  */
00165   class __trace_vector_to_list
00166   : public __trace_base<__vector2list_info, __vector2list_stack_info> 
00167   {
00168   public:
00169     __trace_vector_to_list()
00170     : __trace_base<__vector2list_info, __vector2list_stack_info>()
00171     { __id = "vector-to-list"; }
00172 
00173     ~__trace_vector_to_list() { }
00174 
00175     // Insert a new node at construct with object, callstack and initial size. 
00176     void
00177     __insert(__object_t __obj, __stack_t __stack)
00178     { __add_object(__obj, __vector2list_info(__stack)); }
00179 
00180     // Call at destruction/clean to set container final size.
00181     void
00182     __destruct(const void* __obj)
00183     {
00184       if (!__is_on())
00185     return;
00186 
00187       __vector2list_info* __res = __get_object_info(__obj);
00188       if (!__res)
00189     return;
00190 
00191       float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
00192                  __res->__resize());
00193       float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
00194                    __res->__resize());
00195       __res->__set_vector_cost(__vc);
00196       __res->__set_list_cost(__lc);
00197 
00198       __retire_object(__obj);
00199     }
00200 
00201     // Find the node in the live map.
00202     // XXX Undefined?!?
00203     __vector2list_info* __find(const void* __obj);
00204 
00205     // Collect cost of operations.
00206     void
00207     __opr_insert(const void* __obj, std::size_t __pos, std::size_t __num)
00208     {
00209       __vector2list_info* __res = __get_object_info(__obj);
00210       if (__res)
00211     __res->__opr_insert(__pos, __num);
00212     }
00213 
00214     void
00215     __opr_iterate(const void* __obj, std::size_t __num)
00216     {
00217       __vector2list_info* __res = __get_object_info(__obj);
00218       if (__res)
00219     __res->__opr_iterate(__num);
00220     }
00221 
00222     void
00223     __invalid_operator(const void* __obj)
00224     {
00225       __vector2list_info* __res = __get_object_info(__obj);
00226       if (__res)
00227     __res->__set_invalid();
00228     }
00229 
00230     void
00231     __resize(const void* __obj, std::size_t __from, std::size_t __to)
00232     {
00233       __vector2list_info* __res = __get_object_info(__obj);
00234       if (__res)
00235     __res->__resize(__from, __to);
00236     }
00237 
00238     float
00239     __vector_cost(std::size_t __shift, std::size_t __iterate,
00240           std::size_t __resize)
00241     {
00242       return (__shift
00243           * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
00244           + __iterate
00245           * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
00246           + __resize
00247           * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value);
00248     }
00249 
00250     float
00251     __list_cost(std::size_t __shift, std::size_t __iterate,
00252         std::size_t __resize)
00253     {
00254       return (__shift
00255           * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
00256           + __iterate
00257           * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
00258           + __resize
00259           * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
00260     }
00261 
00262     void
00263     __opr_find(const void* __obj, std::size_t __size)
00264     {
00265       __vector2list_info* __res = __get_object_info(__obj);
00266       if (__res)
00267     __res->__opr_find(__size);
00268     }
00269   };
00270 
00271 
00272   inline void
00273   __trace_vector_to_list_init()
00274   { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); }
00275 
00276   inline void
00277   __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
00278   {
00279     if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list))
00280       {
00281     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->
00282       __collect_warnings(__warnings);
00283     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
00284       }
00285   }
00286 
00287   inline void
00288   __trace_vector_to_list_construct(const void* __obj)
00289   {
00290     if (!__profcxx_init())
00291       return;
00292 
00293     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
00294   }
00295 
00296   inline void
00297   __trace_vector_to_list_destruct(const void* __obj)
00298   {
00299     if (!__profcxx_init())
00300       return;
00301 
00302     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
00303   }
00304 
00305   inline void
00306   __trace_vector_to_list_insert(const void* __obj, std::size_t __pos,
00307                 std::size_t __num)
00308   {
00309     if (!__profcxx_init())
00310       return;
00311 
00312     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos,
00313                                __num);
00314   }
00315 
00316   inline void
00317   __trace_vector_to_list_iterate(const void* __obj, std::size_t __num = 1)
00318   {
00319     if (!__profcxx_init())
00320       return;
00321 
00322     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
00323   }
00324 
00325   inline void
00326   __trace_vector_to_list_invalid_operator(const void* __obj)
00327   {
00328     if (!__profcxx_init())
00329       return;
00330 
00331     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
00332   }
00333 
00334   inline void
00335   __trace_vector_to_list_resize(const void* __obj, std::size_t __from,
00336                 std::size_t __to)
00337   {
00338     if (!__profcxx_init())
00339       return;
00340 
00341     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
00342   }
00343 
00344   inline void
00345   __trace_vector_to_list_find(const void* __obj, std::size_t __size)
00346   {
00347     if (!__profcxx_init())
00348       return;
00349 
00350     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
00351   }
00352 
00353 } // namespace __gnu_profile
00354 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */