libstdc++
profiler_list_to_slist.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_list_to_slist.h
00032  *  @brief Diagnostics for list to slist.
00033  */
00034 
00035 // Written by Changhee Jung.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H
00038 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_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   class __list2slist_info
00047   : public __object_info_base
00048   {
00049   public:
00050     __list2slist_info()
00051     : _M_rewind(false), _M_operations(0) { }
00052   
00053     __list2slist_info(__stack_t __stack)
00054     : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { }
00055 
00056     virtual ~__list2slist_info() { }
00057 
00058     __list2slist_info(const __list2slist_info& __o)
00059     : __object_info_base(__o), _M_rewind(__o._M_rewind),
00060       _M_operations(__o._M_operations) { }
00061   
00062     // XXX: the magnitude should be multiplied with a constant factor F,
00063     // where F is 1 when the malloc size class of list nodes is different
00064     // from the malloc size class of slist nodes.  When they fall into the same
00065     // class, the only slist benefit is from having to set fewer links, so
00066     // the factor F should be much smaller, closer to 0 than to 1.
00067     // This could be implemented by passing the size classes in the config 
00068     // file.  For now, we always assume F to be 1.
00069 
00070     float
00071     __magnitude() const
00072     {
00073       if (!_M_rewind)
00074     return _M_operations;
00075       else
00076     return 0;
00077     }
00078     
00079     void
00080     __merge(const __list2slist_info&) { }
00081 
00082     void
00083     __write(FILE* __f) const
00084     { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); }
00085 
00086     std::string
00087     __advice() const
00088     { return "change std::list to std::forward_list"; }
00089 
00090     void
00091     __opr_rewind()
00092     {
00093       _M_rewind = true;
00094       _M_valid = false;
00095     }
00096 
00097     void
00098     __record_operation()
00099     { ++_M_operations; }
00100 
00101     bool
00102     __has_rewind()
00103     { return _M_rewind; }
00104 
00105   private:
00106     bool _M_rewind;
00107     std::size_t _M_operations;
00108   };
00109 
00110   class __list2slist_stack_info
00111   : public __list2slist_info
00112   {
00113   public:
00114     __list2slist_stack_info(const __list2slist_info& __o) 
00115     : __list2slist_info(__o) { }
00116   };
00117 
00118   class __trace_list_to_slist
00119   : public __trace_base<__list2slist_info, __list2slist_stack_info> 
00120   {
00121   public:
00122     ~__trace_list_to_slist() { }
00123 
00124     __trace_list_to_slist()
00125     : __trace_base<__list2slist_info, __list2slist_stack_info>()
00126     { __id = "list-to-slist"; }
00127 
00128     void
00129     __opr_rewind(const void* __obj)
00130     {
00131       __list2slist_info* __res = __get_object_info(__obj);
00132       if (__res)
00133     __res->__opr_rewind();
00134     }
00135 
00136     void
00137     __record_operation(const void* __obj)
00138     {
00139       __list2slist_info* __res = __get_object_info(__obj);
00140       if (__res)
00141     __res->__record_operation();
00142     }
00143 
00144     void
00145     __insert(const __object_t __obj, __stack_t __stack)
00146     { __add_object(__obj, __list2slist_info(__stack)); }
00147   
00148     void
00149     __destruct(const void* __obj)
00150     {
00151       if (!__is_on())
00152     return;
00153 
00154       __list2slist_info* __res = __get_object_info(__obj);
00155       if (!__res)
00156     return;
00157 
00158       __retire_object(__obj);
00159     }
00160   };
00161 
00162 
00163   inline void
00164   __trace_list_to_slist_init()
00165   { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); }
00166 
00167   inline void
00168   __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings)
00169   {
00170     if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist))
00171       {
00172     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->
00173       __collect_warnings(__warnings);
00174     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f);
00175       }
00176   }
00177 
00178   inline void
00179   __trace_list_to_slist_rewind(const void* __obj) 
00180   {
00181     if (!__profcxx_init())
00182       return;
00183 
00184     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
00185   }
00186 
00187   inline void
00188   __trace_list_to_slist_operation(const void* __obj) 
00189   {
00190     if (!__profcxx_init())
00191       return;
00192 
00193     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
00194   }
00195 
00196   inline void
00197   __trace_list_to_slist_construct(const void* __obj)
00198   {
00199     if (!__profcxx_init())
00200       return;
00201 
00202     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
00203   }
00204 
00205   inline void
00206   __trace_list_to_slist_destruct(const void* __obj)
00207   {
00208     if (!__profcxx_init())
00209       return;
00210 
00211     _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
00212   }
00213 
00214 } // namespace __gnu_profile
00215 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */