libstdc++
profiler_map_to_unordered_map.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_map_to_unordered_map.h
00032  *  @brief Diagnostics for map to unordered_map.
00033  */
00034 
00035 // Written by Silvius Rus.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
00038 #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_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   inline int
00047   __log2(std::size_t __size)
00048   {
00049     for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
00050      -- __bit_count) 
00051       if ((2 << __bit_count) & __size)
00052     return __bit_count;
00053     return 0;
00054   }
00055 
00056   inline float
00057   __map_insert_cost(std::size_t __size)
00058   { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value 
00059         * static_cast<float>(__log2(__size))); }
00060 
00061   inline float
00062   __map_erase_cost(std::size_t __size)
00063   { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
00064         * static_cast<float>(__log2(__size))); }
00065 
00066   inline float
00067   __map_find_cost(std::size_t __size)
00068   { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
00069         * static_cast<float>(__log2(__size))); }
00070 
00071   /** @brief A map-to-unordered_map instrumentation line in the 
00072       object table.  */
00073   class __map2umap_info
00074   : public __object_info_base
00075   {
00076   public:
00077     __map2umap_info()
00078     : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
00079       _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
00080     
00081     __map2umap_info(__stack_t __stack)
00082     : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0), 
00083       _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
00084 
00085     virtual ~__map2umap_info() { }
00086 
00087     __map2umap_info(const __map2umap_info& __o)
00088     : __object_info_base(__o), _M_insert(__o._M_insert),
00089       _M_erase(__o._M_erase), _M_find(__o._M_find),
00090       _M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
00091       _M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
00092 
00093     void
00094     __merge(const __map2umap_info& __o)
00095     {
00096       _M_insert    += __o._M_insert;
00097       _M_erase     += __o._M_erase;
00098       _M_find      += __o._M_find;
00099       _M_umap_cost += __o._M_umap_cost;
00100       _M_map_cost  += __o._M_map_cost;
00101       _M_valid     &= __o._M_valid;
00102     }
00103 
00104     void
00105     __write(FILE* __f) const
00106     {
00107       std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
00108            _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
00109            _M_umap_cost, _M_valid ? "valid" : "invalid");
00110     }
00111 
00112     float
00113     __magnitude() const
00114     { return _M_map_cost - _M_umap_cost; }
00115 
00116     std::string
00117     __advice() const
00118     { return "change std::map to std::unordered_map"; }
00119 
00120     void
00121     __record_insert(std::size_t __size, std::size_t __count)
00122     {
00123       _M_insert += __count;
00124       _M_map_cost += __count * __map_insert_cost(__size);
00125       _M_umap_cost
00126     += (__count
00127         * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
00128     }
00129 
00130     void
00131     __record_erase(std::size_t __size, std::size_t __count)
00132     {
00133       _M_erase += __count;
00134       _M_map_cost += __count * __map_erase_cost(__size);
00135       _M_umap_cost
00136     += (__count
00137         * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
00138     }
00139 
00140     void
00141     __record_find(std::size_t __size)
00142     {
00143       _M_find += 1;
00144       _M_map_cost += __map_find_cost(__size);
00145       _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
00146     }
00147 
00148     void
00149     __record_iterate(std::size_t __count)
00150     {
00151       _M_iterate += __count;
00152       _M_map_cost
00153     += (__count
00154         * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
00155       _M_umap_cost
00156     += (__count
00157         * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
00158     }
00159 
00160     void
00161     __record_invalidate()
00162     { _M_valid = false; }
00163 
00164   private:
00165     std::size_t _M_insert;
00166     std::size_t _M_erase;
00167     std::size_t _M_find;
00168     std::size_t _M_iterate;
00169     float _M_umap_cost;
00170     float _M_map_cost;
00171     bool  _M_valid;
00172   };
00173 
00174 
00175   /** @brief A map-to-unordered_map instrumentation line in the 
00176       stack table.  */
00177   class __map2umap_stack_info 
00178   : public __map2umap_info
00179   {
00180   public:
00181     __map2umap_stack_info(const __map2umap_info& __o)
00182     : __map2umap_info(__o) { }
00183   };
00184 
00185   /** @brief Map-to-unordered_map instrumentation producer.  */
00186   class __trace_map2umap
00187   : public __trace_base<__map2umap_info, __map2umap_stack_info> 
00188   {
00189   public:
00190     __trace_map2umap()
00191     : __trace_base<__map2umap_info, __map2umap_stack_info>()
00192     { __id = "map-to-unordered-map"; }
00193   };
00194 
00195   inline void
00196   __trace_map_to_unordered_map_init()
00197   { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
00198 
00199   inline void
00200   __trace_map_to_unordered_map_report(FILE* __f,
00201                       __warning_vector_t& __warnings)
00202   {
00203     if (_GLIBCXX_PROFILE_DATA(_S_map2umap)) 
00204       {
00205     _GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
00206     _GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
00207       }
00208   }
00209 
00210   inline void
00211   __trace_map_to_unordered_map_construct(const void* __obj)
00212   {
00213     if (!__profcxx_init())
00214       return;
00215 
00216     _GLIBCXX_PROFILE_DATA(_S_map2umap)->
00217       __add_object(__obj, __map2umap_info(__get_stack()));
00218   }
00219 
00220   inline void
00221   __trace_map_to_unordered_map_destruct(const void* __obj)
00222   {
00223     if (!__profcxx_init())
00224       return;
00225 
00226     _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
00227   }
00228 
00229   inline void
00230   __trace_map_to_unordered_map_insert(const void* __obj, 
00231                       std::size_t __size, std::size_t __count)
00232   {
00233     if (!__profcxx_init())
00234       return;
00235 
00236     __map2umap_info* __info
00237       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
00238 
00239     if (__info)
00240       __info->__record_insert(__size, __count);
00241   }
00242 
00243   inline void
00244   __trace_map_to_unordered_map_erase(const void* __obj, 
00245                      std::size_t __size, std::size_t __count)
00246   {
00247     if (!__profcxx_init()) 
00248       return;
00249 
00250     __map2umap_info* __info 
00251       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
00252 
00253     if (__info)
00254       __info->__record_erase(__size, __count);
00255   }
00256 
00257   inline void
00258   __trace_map_to_unordered_map_find(const void* __obj, std::size_t __size)
00259   {
00260     if (!__profcxx_init())
00261       return;
00262 
00263     __map2umap_info* __info
00264       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
00265 
00266     if (__info)
00267       __info->__record_find(__size);
00268   }
00269 
00270   inline void
00271   __trace_map_to_unordered_map_iterate(const void* __obj, std::size_t __count)
00272   {
00273     if (!__profcxx_init())
00274       return;
00275 
00276     __map2umap_info* __info
00277       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
00278     
00279     if (__info)
00280       __info->__record_iterate(__count);
00281   }
00282 
00283   inline void
00284   __trace_map_to_unordered_map_invalidate(const void* __obj)
00285   {
00286     if (!__profcxx_init())
00287       return;
00288 
00289     __map2umap_info* __info
00290       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
00291 
00292     if (__info)
00293       __info->__record_invalidate();
00294   }
00295 
00296 } // namespace __gnu_profile
00297 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */