# 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 */