]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/profile/impl/profiler_container_size.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / profile / impl / profiler_container_size.h
1 // -*- C++ -*-
2 //
3 // Copyright (C) 2009-2016 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 */