Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*-
  2. //
  3. // Copyright (C) 2009-2013 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_container_size.h
  25.  *  @brief Diagnostics for container sizes.
  26.  */
  27.  
  28. // Written by Lixia Liu and Silvius Rus.
  29.  
  30. #ifndef _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H
  31. #define _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_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 container size instrumentation line in the object table.  */
  42.   class __container_size_info
  43.   : public __object_info_base
  44.   {
  45.   public:
  46.     __container_size_info()
  47.     : _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0),
  48.       _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
  49.     { }
  50.  
  51.     __container_size_info(const __container_size_info& __o)
  52.     : __object_info_base(__o), _M_init(__o._M_init), _M_max(__o._M_max),
  53.       _M_min(__o._M_min), _M_total(__o._M_total),
  54.       _M_item_min(__o._M_item_min), _M_item_max(__o._M_item_max),
  55.       _M_item_total(__o._M_item_total), _M_count(__o._M_count),
  56.       _M_resize(__o._M_resize), _M_cost(__o._M_cost)
  57.     { }
  58.  
  59.     __container_size_info(__stack_t __stack, std::size_t __num)
  60.     : __object_info_base(__stack), _M_init(__num), _M_max(__num),
  61.       _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0),
  62.       _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
  63.     { }
  64.  
  65.     virtual ~__container_size_info() { }
  66.  
  67.     void
  68.     __write(FILE* __f) const
  69.     {
  70.       std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
  71.                    _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max,
  72.                    _M_total, _M_item_min, _M_item_max, _M_item_total);
  73.     }
  74.  
  75.     float
  76.     __magnitude() const
  77.     { return static_cast<float>(_M_cost); }
  78.  
  79.     std::string
  80.     __advice() const
  81.     {
  82.       std::stringstream __message;
  83.       if (_M_init < _M_item_max)
  84.         __message << "change initial container size from " << _M_init
  85.                   << " to " << _M_item_max;
  86.       return __message.str();
  87.     }
  88.  
  89.     void
  90.     __merge(const __container_size_info& __o)
  91.     {
  92.       _M_init        = std::max(_M_init, __o._M_init);
  93.       _M_max         = std::max(_M_max, __o._M_max);
  94.       _M_item_max    = std::max(_M_item_max, __o._M_item_max);
  95.       _M_min         = std::min(_M_min, __o._M_min);
  96.       _M_item_min    = std::min(_M_item_min, __o._M_item_min);
  97.       _M_total      += __o._M_total;
  98.       _M_item_total += __o._M_item_total;
  99.       _M_count      += __o._M_count;
  100.       _M_cost       += __o._M_cost;
  101.       _M_resize     += __o._M_resize;
  102.     }
  103.  
  104.     // Call if a container is destructed or cleaned.
  105.     void
  106.     __destruct(std::size_t __num, std::size_t __inum)
  107.     {
  108.       _M_max = std::max(_M_max, __num);
  109.       _M_item_max = std::max(_M_item_max, __inum);
  110.       if (_M_min == 0)
  111.         {
  112.           _M_min = __num;
  113.           _M_item_min = __inum;
  114.         }
  115.       else
  116.         {
  117.           _M_min = std::min(_M_min, __num);
  118.           _M_item_min = std::min(_M_item_min, __inum);
  119.         }
  120.       _M_total += __num;
  121.       _M_item_total += __inum;
  122.       _M_count += 1;
  123.     }
  124.  
  125.     // Estimate the cost of resize/rehash.
  126.     float
  127.     __resize_cost(std::size_t __from, std::size_t)
  128.     { return __from; }
  129.  
  130.     // Call if container is resized.
  131.     void
  132.     __resize(std::size_t __from, std::size_t __to)
  133.     {
  134.       _M_cost += this->__resize_cost(__from, __to);
  135.       _M_resize += 1;
  136.       _M_max = std::max(_M_max, __to);
  137.     }
  138.  
  139.   private:
  140.     std::size_t _M_init;
  141.     std::size_t _M_max;  // range of # buckets
  142.     std::size_t _M_min;
  143.     std::size_t _M_total;
  144.     std::size_t _M_item_min;  // range of # items
  145.     std::size_t _M_item_max;
  146.     std::size_t _M_item_total;
  147.     std::size_t _M_count;
  148.     std::size_t _M_resize;
  149.     std::size_t _M_cost;
  150.   };
  151.  
  152.  
  153.   /** @brief A container size instrumentation line in the stack table.  */
  154.   class __container_size_stack_info
  155.   : public __container_size_info
  156.   {
  157.   public:
  158.     __container_size_stack_info(const __container_size_info& __o)
  159.     : __container_size_info(__o) { }
  160.   };
  161.  
  162.  
  163.   /** @brief Container size instrumentation trace producer.  */
  164.   class __trace_container_size
  165.   : public __trace_base<__container_size_info, __container_size_stack_info>
  166.   {
  167.   public:
  168.     ~__trace_container_size() { }
  169.  
  170.     __trace_container_size()
  171.     : __trace_base<__container_size_info, __container_size_stack_info>() { };
  172.  
  173.     // Insert a new node at construct with object, callstack and initial size.
  174.     void
  175.     __insert(const __object_t __obj, __stack_t __stack, std::size_t __num)
  176.     { __add_object(__obj, __container_size_info(__stack, __num)); }
  177.  
  178.     // XXX Undefined?
  179.     void
  180.     __construct(const void* __obj, std::size_t __inum);
  181.  
  182.     // Call at destruction/clean to set container final size.
  183.     void
  184.     __destruct(const void* __obj, std::size_t __num, std::size_t __inum)
  185.     {
  186.       if (!__is_on())
  187.         return;
  188.  
  189.       __object_t __obj_handle = static_cast<__object_t>(__obj);
  190.  
  191.       __container_size_info* __object_info = __get_object_info(__obj_handle);
  192.       if (!__object_info)
  193.         return;
  194.  
  195.       __object_info->__destruct(__num, __inum);
  196.       __retire_object(__obj_handle);
  197.     }
  198.  
  199.     // Call at resize to set resize/cost information.
  200.     void
  201.     __resize(const void* __obj, int __from, int __to)
  202.     {
  203.       if (!__is_on())
  204.         return;
  205.  
  206.       __container_size_info* __object_info = __get_object_info(__obj);
  207.       if (!__object_info)
  208.         return;
  209.  
  210.       __object_info->__resize(__from, __to);
  211.     }
  212.   };
  213.  
  214. } // namespace __gnu_profile
  215. #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
  216.