Subversion Repositories Kolibri OS

Rev

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_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(__stack_t __stack)
  47.     : __object_info_base(__stack), _M_init(0), _M_max(0),
  48.       _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0),
  49.       _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
  50.     { }
  51.  
  52.     void
  53.     __write(FILE* __f) const
  54.     {
  55.       std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
  56.                    _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max,
  57.                    _M_total, _M_item_min, _M_item_max, _M_item_total);
  58.     }
  59.  
  60.     float
  61.     __magnitude() const
  62.     { return static_cast<float>(_M_cost); }
  63.  
  64.     std::string
  65.     __advice() const
  66.     {
  67.       std::stringstream __message;
  68.       if (_M_init < _M_item_max)
  69.         __message << "change initial container size from " << _M_init
  70.                   << " to " << _M_item_max;
  71.       return __message.str();
  72.     }
  73.  
  74.     void
  75.     __init(std::size_t __num)
  76.     {
  77.       _M_init = __num;
  78.       _M_max = __num;
  79.     }
  80.  
  81.     void
  82.     __merge(const __container_size_info& __o)
  83.     {
  84.       __object_info_base::__merge(__o);
  85.       _M_init        = std::max(_M_init, __o._M_init);
  86.       _M_max         = std::max(_M_max, __o._M_max);
  87.       _M_item_max    = std::max(_M_item_max, __o._M_item_max);
  88.       _M_min         = std::min(_M_min, __o._M_min);
  89.       _M_item_min    = std::min(_M_item_min, __o._M_item_min);
  90.       _M_total      += __o._M_total;
  91.       _M_item_total += __o._M_item_total;
  92.       _M_count      += __o._M_count;
  93.       _M_cost       += __o._M_cost;
  94.       _M_resize     += __o._M_resize;
  95.     }
  96.  
  97.     // Call if a container is destructed or cleaned.
  98.     void
  99.     __destruct(std::size_t __num, std::size_t __inum)
  100.     {
  101.       _M_max = std::max(_M_max, __num);
  102.       _M_item_max = std::max(_M_item_max, __inum);
  103.       if (_M_min == 0)
  104.         {
  105.           _M_min = __num;
  106.           _M_item_min = __inum;
  107.         }
  108.       else
  109.         {
  110.           _M_min = std::min(_M_min, __num);
  111.           _M_item_min = std::min(_M_item_min, __inum);
  112.         }
  113.  
  114.       _M_total += __num;
  115.       _M_item_total += __inum;
  116.       _M_count += 1;
  117.     }
  118.  
  119.     // Estimate the cost of resize/rehash.
  120.     float
  121.     __resize_cost(std::size_t __from, std::size_t)
  122.     { return __from; }
  123.  
  124.     // Call if container is resized.
  125.     void
  126.     __resize(std::size_t __from, std::size_t __to)
  127.     {
  128.       _M_cost += this->__resize_cost(__from, __to);
  129.       _M_resize += 1;
  130.       _M_max = std::max(_M_max, __to);
  131.     }
  132.  
  133.   private:
  134.     std::size_t _M_init;
  135.     std::size_t _M_max;  // range of # buckets
  136.     std::size_t _M_min;
  137.     std::size_t _M_total;
  138.     std::size_t _M_item_min;  // range of # items
  139.     std::size_t _M_item_max;
  140.     std::size_t _M_item_total;
  141.     std::size_t _M_count;
  142.     std::size_t _M_resize;
  143.     std::size_t _M_cost;
  144.   };
  145.  
  146.   /** @brief A container size instrumentation line in the stack table.  */
  147.   class __container_size_stack_info
  148.   : public __container_size_info
  149.   {
  150.   public:
  151.     __container_size_stack_info(const __container_size_info& __o)
  152.     : __container_size_info(__o) { }
  153.   };
  154.  
  155.   /** @brief Container size instrumentation trace producer.  */
  156.   class __trace_container_size
  157.   : public __trace_base<__container_size_info, __container_size_stack_info>
  158.   {
  159.   public:
  160.     ~__trace_container_size() { }
  161.  
  162.     __trace_container_size()
  163.     : __trace_base<__container_size_info, __container_size_stack_info>() { };
  164.  
  165.     // Insert a new node at construct with object, callstack and initial size.
  166.     __container_size_info*
  167.     __insert(__stack_t __stack, std::size_t __num)
  168.     {
  169.       __container_size_info* __ret =  __add_object(__stack);
  170.       if (__ret)
  171.         __ret->__init(__num);
  172.       return __ret;
  173.     }
  174.  
  175.     // Call at destruction/clean to set container final size.
  176.     void
  177.     __destruct(__container_size_info* __obj_info,
  178.                std::size_t __num, std::size_t __inum)
  179.     {
  180.       __obj_info->__destruct(__num, __inum);
  181.       __retire_object(__obj_info);
  182.     }
  183.   };
  184.  
  185. } // namespace __gnu_profile
  186. #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
  187.