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_list_to_vector.h
  25.  *  @brief diagnostics for list to vector.
  26.  */
  27.  
  28. // Written by Changhee Jung.
  29.  
  30. #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H
  31. #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1
  32.  
  33. #include <sstream>
  34.  
  35. #include "profile/impl/profiler.h"
  36. #include "profile/impl/profiler_node.h"
  37. #include "profile/impl/profiler_trace.h"
  38.  
  39. namespace __gnu_profile
  40. {
  41.   /** @brief A list-to-vector instrumentation line in the object table.  */
  42.   class __list2vector_info
  43.   : public __object_info_base
  44.   {
  45.   public:
  46.     __list2vector_info(__stack_t __stack)
  47.     : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
  48.       _M_resize(0), _M_list_cost(0), _M_vector_cost(0),
  49.       _M_max_size(0) { }
  50.  
  51.     void
  52.     __merge(const __list2vector_info& __o)
  53.     {
  54.       __object_info_base::__merge(__o);
  55.       _M_shift_count  += __o._M_shift_count;
  56.       _M_iterate      += __o._M_iterate;
  57.       _M_vector_cost  += __o._M_vector_cost;
  58.       _M_list_cost    += __o._M_list_cost;
  59.       _M_resize       += __o._M_resize;
  60.       _M_max_size     = std::max( _M_max_size, __o._M_max_size);
  61.     }
  62.  
  63.     void
  64.     __write(FILE* __f) const
  65.     {
  66.       std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count,
  67.                    _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
  68.     }
  69.  
  70.     float
  71.     __magnitude() const
  72.     { return _M_list_cost - _M_vector_cost; }
  73.  
  74.     std::string
  75.     __advice() const
  76.     {
  77.       std::stringstream __sstream;
  78.       __sstream
  79.         << "change std::list to std::vector and its initial size from 0 to "
  80.         << _M_max_size;
  81.       return __sstream.str();
  82.     }
  83.  
  84.     std::size_t
  85.     __shift_count()
  86.     { return _M_shift_count; }
  87.  
  88.     std::size_t
  89.     __iterate()
  90.     { return _M_iterate; }
  91.  
  92.     float
  93.     __list_cost()
  94.     { return _M_list_cost; }
  95.  
  96.     std::size_t
  97.     __resize()
  98.     { return _M_resize; }
  99.  
  100.     void
  101.     __set_list_cost(float __lc)
  102.     { _M_list_cost = __lc; }
  103.    
  104.     void
  105.     __set_vector_cost(float __vc)
  106.     { _M_vector_cost = __vc; }
  107.    
  108.     void
  109.     __opr_insert(std::size_t __shift, std::size_t __size)
  110.     {
  111.       _M_shift_count += __shift;
  112.       _M_max_size = std::max(_M_max_size, __size);
  113.     }
  114.  
  115.     void
  116.     __opr_iterate(int __num)
  117.     { __gnu_cxx::__atomic_add(&_M_iterate, __num); }
  118.  
  119.     void
  120.     __resize(std::size_t __from, std::size_t)
  121.     { _M_resize += __from; }
  122.  
  123.   private:
  124.     std::size_t _M_shift_count;
  125.     mutable _Atomic_word _M_iterate;
  126.     std::size_t _M_resize;
  127.     float _M_list_cost;
  128.     float _M_vector_cost;
  129.     std::size_t _M_max_size;
  130.   };
  131.  
  132.   class __list2vector_stack_info
  133.   : public __list2vector_info
  134.   {
  135.   public:
  136.     __list2vector_stack_info(const __list2vector_info& __o)
  137.     : __list2vector_info(__o) {}
  138.   };
  139.  
  140.   class __trace_list_to_vector
  141.   : public __trace_base<__list2vector_info, __list2vector_stack_info>
  142.   {
  143.   public:
  144.     __trace_list_to_vector()
  145.     : __trace_base<__list2vector_info, __list2vector_stack_info>()
  146.     { __id = "list-to-vector"; }
  147.  
  148.     ~__trace_list_to_vector() { }
  149.  
  150.     // Call at destruction/clean to set container final size.
  151.     void
  152.     __destruct(__list2vector_info* __obj_info)
  153.     {
  154.       float __vc = __vector_cost(__obj_info->__shift_count(),
  155.                                  __obj_info->__iterate());
  156.       float __lc = __list_cost(__obj_info->__shift_count(),
  157.                                __obj_info->__iterate());
  158.       __obj_info->__set_vector_cost(__vc);
  159.       __obj_info->__set_list_cost(__lc);
  160.       __retire_object(__obj_info);
  161.     }
  162.  
  163.     // Collect cost of operations.
  164.     float
  165.     __vector_cost(std::size_t __shift, std::size_t __iterate)
  166.     {
  167.       // The resulting vector will use a 'reserve' method.
  168.       return (__shift
  169.               * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
  170.               + __iterate
  171.               * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value);
  172.     }
  173.  
  174.     float
  175.     __list_cost(std::size_t __shift, std::size_t __iterate)
  176.     {
  177.       return (__shift
  178.               * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
  179.               + __iterate
  180.               * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value);
  181.     }
  182.   };
  183.  
  184.  
  185.   inline void
  186.   __trace_list_to_vector_init()
  187.   { _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); }
  188.  
  189.   inline void
  190.   __trace_list_to_vector_free()
  191.   { delete _GLIBCXX_PROFILE_DATA(_S_list_to_vector); }
  192.  
  193.   inline void
  194.   __trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings)
  195.   { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_vector), __f, __warnings); }
  196.  
  197.   inline __list2vector_info*
  198.   __trace_list_to_vector_construct()
  199.   {
  200.     if (!__profcxx_init())
  201.       return 0;
  202.  
  203.     if (!__reentrance_guard::__get_in())
  204.       return 0;
  205.  
  206.     __reentrance_guard __get_out;
  207.     return _GLIBCXX_PROFILE_DATA(_S_list_to_vector)
  208.       ->__add_object(__get_stack());
  209.   }
  210.  
  211.   inline void
  212.   __trace_list_to_vector_insert(__list2vector_info* __obj_info,
  213.                                 std::size_t __shift, std::size_t __size)
  214.   {
  215.     if (!__obj_info)
  216.       return;
  217.  
  218.     __obj_info->__opr_insert(__shift, __size);
  219.   }
  220.  
  221.   inline void
  222.   __trace_list_to_vector_iterate(__list2vector_info* __obj_info,
  223.                                  int)
  224.   {
  225.     if (!__obj_info)
  226.       return;
  227.  
  228.     // We only collect if an iteration took place no matter in what side.
  229.     __obj_info->__opr_iterate(1);
  230.   }
  231.  
  232.   inline void
  233.   __trace_list_to_vector_invalid_operator(__list2vector_info* __obj_info)
  234.   {
  235.     if (!__obj_info)
  236.       return;
  237.  
  238.     __obj_info->__set_invalid();
  239.   }
  240.  
  241.   inline void
  242.   __trace_list_to_vector_resize(__list2vector_info* __obj_info,
  243.                                 std::size_t __from, std::size_t __to)
  244.   {
  245.     if (!__obj_info)
  246.       return;
  247.  
  248.     __obj_info->__resize(__from, __to);
  249.   }
  250.  
  251.   inline void
  252.   __trace_list_to_vector_destruct(__list2vector_info* __obj_info)
  253.   {
  254.     if (!__obj_info)
  255.       return;
  256.  
  257.     _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj_info);
  258.   }
  259.  
  260. } // namespace __gnu_profile
  261. #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */
  262.