Home | History | Annotate | Download | only in impl
      1 // -*- C++ -*-
      2 //
      3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 2, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // You should have received a copy of the GNU General Public License
     17 // along with this library; see the file COPYING.  If not, write to
     18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
     19 // MA 02111-1307, USA.
     20 
     21 // As a special exception, you may use this file as part of a free
     22 // software library without restriction.  Specifically, if other files
     23 // instantiate templates or use macros or inline functions from this
     24 // file, or you compile this file and link it with other files to
     25 // produce an executable, this file does not by itself cause the
     26 // resulting executable to be covered by the GNU General Public
     27 // License.  This exception does not however invalidate any other
     28 // reasons why the executable file might be covered by the GNU General
     29 // Public License.
     30 
     31 /** @file profile/impl/profiler_map_to_unordered_map.h
     32  *  @brief Diagnostics for map to unordered_map.
     33  */
     34 
     35 // Written by Silvius Rus.
     36 
     37 #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
     38 #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1
     39 
     40 #include "profile/impl/profiler.h"
     41 #include "profile/impl/profiler_node.h"
     42 #include "profile/impl/profiler_trace.h"
     43 
     44 namespace __gnu_profile
     45 {
     46   inline int
     47   __log2(std::size_t __size)
     48   {
     49     for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
     50 	 -- __bit_count)
     51       if ((2 << __bit_count) & __size)
     52 	return __bit_count;
     53     return 0;
     54   }
     55 
     56   inline float
     57   __map_insert_cost(std::size_t __size)
     58   { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
     59 	    * static_cast<float>(__log2(__size))); }
     60 
     61   inline float
     62   __map_erase_cost(std::size_t __size)
     63   { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
     64 	    * static_cast<float>(__log2(__size))); }
     65 
     66   inline float
     67   __map_find_cost(std::size_t __size)
     68   { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
     69 	    * static_cast<float>(__log2(__size))); }
     70 
     71   /** @brief A map-to-unordered_map instrumentation line in the
     72       object table.  */
     73   class __map2umap_info
     74   : public __object_info_base
     75   {
     76   public:
     77     __map2umap_info()
     78     : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
     79       _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
     80 
     81     __map2umap_info(__stack_t __stack)
     82     : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
     83       _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
     84 
     85     virtual ~__map2umap_info() { }
     86 
     87     __map2umap_info(const __map2umap_info& __o)
     88     : __object_info_base(__o), _M_insert(__o._M_insert),
     89       _M_erase(__o._M_erase), _M_find(__o._M_find),
     90       _M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
     91       _M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
     92 
     93     void
     94     __merge(const __map2umap_info& __o)
     95     {
     96       _M_insert    += __o._M_insert;
     97       _M_erase     += __o._M_erase;
     98       _M_find      += __o._M_find;
     99       _M_umap_cost += __o._M_umap_cost;
    100       _M_map_cost  += __o._M_map_cost;
    101       _M_valid     &= __o._M_valid;
    102     }
    103 
    104     void
    105     __write(FILE* __f) const
    106     {
    107       std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
    108 		   _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
    109 		   _M_umap_cost, _M_valid ? "valid" : "invalid");
    110     }
    111 
    112     float
    113     __magnitude() const
    114     { return _M_map_cost - _M_umap_cost; }
    115 
    116     std::string
    117     __advice() const
    118     { return "change std::map to std::unordered_map"; }
    119 
    120     void
    121     __record_insert(std::size_t __size, std::size_t __count)
    122     {
    123       _M_insert += __count;
    124       _M_map_cost += __count * __map_insert_cost(__size);
    125       _M_umap_cost
    126 	+= (__count
    127 	    * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
    128     }
    129 
    130     void
    131     __record_erase(std::size_t __size, std::size_t __count)
    132     {
    133       _M_erase += __count;
    134       _M_map_cost += __count * __map_erase_cost(__size);
    135       _M_umap_cost
    136 	+= (__count
    137 	    * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
    138     }
    139 
    140     void
    141     __record_find(std::size_t __size)
    142     {
    143       _M_find += 1;
    144       _M_map_cost += __map_find_cost(__size);
    145       _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
    146     }
    147 
    148     void
    149     __record_iterate(std::size_t __count)
    150     {
    151       _M_iterate += __count;
    152       _M_map_cost
    153 	+= (__count
    154 	    * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
    155       _M_umap_cost
    156 	+= (__count
    157 	    * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
    158     }
    159 
    160     void
    161     __record_invalidate()
    162     { _M_valid = false; }
    163 
    164   private:
    165     std::size_t _M_insert;
    166     std::size_t _M_erase;
    167     std::size_t _M_find;
    168     std::size_t _M_iterate;
    169     float _M_umap_cost;
    170     float _M_map_cost;
    171     bool  _M_valid;
    172   };
    173 
    174 
    175   /** @brief A map-to-unordered_map instrumentation line in the
    176       stack table.  */
    177   class __map2umap_stack_info
    178   : public __map2umap_info
    179   {
    180   public:
    181     __map2umap_stack_info(const __map2umap_info& __o)
    182     : __map2umap_info(__o) { }
    183   };
    184 
    185   /** @brief Map-to-unordered_map instrumentation producer.  */
    186   class __trace_map2umap
    187   : public __trace_base<__map2umap_info, __map2umap_stack_info>
    188   {
    189   public:
    190     __trace_map2umap()
    191     : __trace_base<__map2umap_info, __map2umap_stack_info>()
    192     { __id = "map-to-unordered-map"; }
    193   };
    194 
    195   inline void
    196   __trace_map_to_unordered_map_init()
    197   { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
    198 
    199   inline void
    200   __trace_map_to_unordered_map_report(FILE* __f,
    201 				      __warning_vector_t& __warnings)
    202   {
    203     if (_GLIBCXX_PROFILE_DATA(_S_map2umap))
    204       {
    205 	_GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
    206 	_GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
    207       }
    208   }
    209 
    210   inline void
    211   __trace_map_to_unordered_map_construct(const void* __obj)
    212   {
    213     if (!__profcxx_init())
    214       return;
    215 
    216     _GLIBCXX_PROFILE_DATA(_S_map2umap)->
    217       __add_object(__obj, __map2umap_info(__get_stack()));
    218   }
    219 
    220   inline void
    221   __trace_map_to_unordered_map_destruct(const void* __obj)
    222   {
    223     if (!__profcxx_init())
    224       return;
    225 
    226     _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
    227   }
    228 
    229   inline void
    230   __trace_map_to_unordered_map_insert(const void* __obj,
    231 				      std::size_t __size, std::size_t __count)
    232   {
    233     if (!__profcxx_init())
    234       return;
    235 
    236     __map2umap_info* __info
    237       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
    238 
    239     if (__info)
    240       __info->__record_insert(__size, __count);
    241   }
    242 
    243   inline void
    244   __trace_map_to_unordered_map_erase(const void* __obj,
    245 				     std::size_t __size, std::size_t __count)
    246   {
    247     if (!__profcxx_init())
    248       return;
    249 
    250     __map2umap_info* __info
    251       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
    252 
    253     if (__info)
    254       __info->__record_erase(__size, __count);
    255   }
    256 
    257   inline void
    258   __trace_map_to_unordered_map_find(const void* __obj, std::size_t __size)
    259   {
    260     if (!__profcxx_init())
    261       return;
    262 
    263     __map2umap_info* __info
    264       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
    265 
    266     if (__info)
    267       __info->__record_find(__size);
    268   }
    269 
    270   inline void
    271   __trace_map_to_unordered_map_iterate(const void* __obj, std::size_t __count)
    272   {
    273     if (!__profcxx_init())
    274       return;
    275 
    276     __map2umap_info* __info
    277       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
    278 
    279     if (__info)
    280       __info->__record_iterate(__count);
    281   }
    282 
    283   inline void
    284   __trace_map_to_unordered_map_invalidate(const void* __obj)
    285   {
    286     if (!__profcxx_init())
    287       return;
    288 
    289     __map2umap_info* __info
    290       = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
    291 
    292     if (__info)
    293       __info->__record_invalidate();
    294   }
    295 
    296 } // namespace __gnu_profile
    297 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
    298