Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*-
  2. //
  3. // Copyright (C) 2009-2015 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
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. //
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License along
  21. // with this library; see the file COPYING3.  If not see
  22. // <http://www.gnu.org/licenses/>.
  23.  
  24. /** @file profile/impl/profiler_map_to_unordered_map.h
  25.  *  @brief Diagnostics for map to unordered_map.
  26.  */
  27.  
  28. // Written by Silvius Rus.
  29.  
  30. #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
  31. #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1
  32.  
  33. #include "profile/impl/profiler.h"
  34. #include "profile/impl/profiler_node.h"
  35. #include "profile/impl/profiler_trace.h"
  36.  
  37. namespace __gnu_profile
  38. {
  39.   inline int
  40.   __log2(std::size_t __size)
  41.   {
  42.     for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
  43.          -- __bit_count)
  44.       if ((2 << __bit_count) & __size)
  45.         return __bit_count;
  46.     return 0;
  47.   }
  48.  
  49.   inline float
  50.   __map_insert_cost(std::size_t __size)
  51.   { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
  52.             * static_cast<float>(__log2(__size))); }
  53.  
  54.   inline float
  55.   __map_erase_cost(std::size_t __size)
  56.   { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
  57.             * static_cast<float>(__log2(__size))); }
  58.  
  59.   inline float
  60.   __map_find_cost(std::size_t __size)
  61.   { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
  62.             * static_cast<float>(__log2(__size))); }
  63.  
  64.   /** @brief A map-to-unordered_map instrumentation line in the
  65.       object table.  */
  66.   class __map2umap_info
  67.   : public __object_info_base
  68.   {
  69.   public:
  70.     __map2umap_info(__stack_t __stack)
  71.     : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
  72.       _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0)
  73.     { }
  74.  
  75.     void
  76.     __merge(const __map2umap_info& __o)
  77.     {
  78.       __object_info_base::__merge(__o);
  79.       _M_insert         += __o._M_insert;
  80.       _M_erase          += __o._M_erase;
  81.       _M_find           += __o._M_find;
  82.       _M_iterate        += __o._M_iterate;
  83.       _M_umap_cost      += __o._M_umap_cost;
  84.       _M_map_cost       += __o._M_map_cost;
  85.     }
  86.  
  87.     void
  88.     __write(FILE* __f) const
  89.     {
  90.       std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n",
  91.                    _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
  92.                    _M_umap_cost);
  93.     }
  94.  
  95.     float
  96.     __magnitude() const
  97.     { return _M_map_cost - _M_umap_cost; }
  98.  
  99.     std::string
  100.     __advice() const
  101.     { return "prefer an unordered container"; }
  102.  
  103.     void
  104.     __record_insert(std::size_t __size, std::size_t __count)
  105.     {
  106.       ++_M_insert;
  107.       if (__count)
  108.         {
  109.           _M_map_cost += __count * __map_insert_cost(__size);
  110.           _M_umap_cost
  111.             += (__count
  112.                 * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
  113.         }
  114.     }
  115.  
  116.     void
  117.     __record_erase(std::size_t __size, std::size_t __count)
  118.     {
  119.       ++_M_erase;
  120.       if (__count)
  121.         {
  122.           _M_map_cost += __count * __map_erase_cost(__size);
  123.           _M_umap_cost
  124.             += (__count
  125.                 * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
  126.         }
  127.     }
  128.  
  129.     void
  130.     __record_find(std::size_t __size)
  131.     {
  132.       ++_M_find;
  133.       _M_map_cost += __map_find_cost(__size);
  134.       _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
  135.     }
  136.  
  137.     void
  138.     __record_iterate(int __count)
  139.     { __gnu_cxx::__atomic_add(&_M_iterate, __count); }
  140.  
  141.     void
  142.     __set_iterate_costs()
  143.     {
  144.       _M_umap_cost
  145.         += (_M_iterate
  146.             * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
  147.       _M_map_cost
  148.         += (_M_iterate
  149.             * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
  150.     }
  151.  
  152.   private:
  153.     std::size_t _M_insert;
  154.     std::size_t _M_erase;
  155.     std::size_t _M_find;
  156.     mutable _Atomic_word _M_iterate;
  157.     float _M_umap_cost;
  158.     float _M_map_cost;
  159.   };
  160.  
  161.  
  162.   /** @brief A map-to-unordered_map instrumentation line in the
  163.       stack table.  */
  164.   class __map2umap_stack_info
  165.   : public __map2umap_info
  166.   {
  167.   public:
  168.     __map2umap_stack_info(const __map2umap_info& __o)
  169.     : __map2umap_info(__o) { }
  170.   };
  171.  
  172.   /** @brief Map-to-unordered_map instrumentation producer.  */
  173.   class __trace_map2umap
  174.   : public __trace_base<__map2umap_info, __map2umap_stack_info>
  175.   {
  176.   public:
  177.     __trace_map2umap()
  178.     : __trace_base<__map2umap_info, __map2umap_stack_info>()
  179.     { __id = "ordered-to-unordered"; }
  180.  
  181.     // Call at destruction/clean to set container final size.
  182.     void
  183.     __destruct(__map2umap_info* __obj_info)
  184.     {
  185.       __obj_info->__set_iterate_costs();
  186.       __retire_object(__obj_info);
  187.     }
  188.   };
  189.  
  190.   inline void
  191.   __trace_map_to_unordered_map_init()
  192.   { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
  193.  
  194.   inline void
  195.   __trace_map_to_unordered_map_free()
  196.   { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); }
  197.  
  198.   inline void
  199.   __trace_map_to_unordered_map_report(FILE* __f,
  200.                                       __warning_vector_t& __warnings)
  201.   { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); }
  202.  
  203.   inline __map2umap_info*
  204.   __trace_map_to_unordered_map_construct()
  205.   {
  206.     if (!__profcxx_init())
  207.       return 0;
  208.  
  209.     if (!__reentrance_guard::__get_in())
  210.       return 0;
  211.  
  212.     __reentrance_guard __get_out;
  213.     return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack());
  214.   }
  215.  
  216.   inline void
  217.   __trace_map_to_unordered_map_insert(__map2umap_info* __info,
  218.                                       std::size_t __size, std::size_t __count)
  219.   {
  220.     if (!__info)
  221.       return;
  222.  
  223.     __info->__record_insert(__size, __count);
  224.   }
  225.  
  226.   inline void
  227.   __trace_map_to_unordered_map_erase(__map2umap_info* __info,
  228.                                      std::size_t __size, std::size_t __count)
  229.   {
  230.     if (!__info)
  231.       return;
  232.  
  233.     __info->__record_erase(__size, __count);
  234.   }
  235.  
  236.   inline void
  237.   __trace_map_to_unordered_map_find(__map2umap_info* __info,
  238.                                     std::size_t __size)
  239.   {
  240.     if (!__info)
  241.       return;
  242.  
  243.     __info->__record_find(__size);
  244.   }
  245.  
  246.   inline void
  247.   __trace_map_to_unordered_map_iterate(__map2umap_info* __info,
  248.                                        int)
  249.   {
  250.     if (!__info)
  251.       return;
  252.  
  253.     // We only collect if an iteration took place no matter in what side.
  254.     __info->__record_iterate(1);
  255.   }
  256.  
  257.   inline void
  258.   __trace_map_to_unordered_map_invalidate(__map2umap_info* __info)
  259.   {
  260.     if (!__info)
  261.       return;
  262.  
  263.     __info->__set_invalid();
  264.   }
  265.  
  266.   inline void
  267.   __trace_map_to_unordered_map_destruct(__map2umap_info* __info)
  268.   {
  269.     if (!__info)
  270.       return;
  271.  
  272.     _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info);
  273.   }
  274. } // namespace __gnu_profile
  275. #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
  276.