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