libstdc++
profiler_map_to_unordered_map.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Copyright (C) 2009, 2010 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"
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. */
67  : public __object_info_base
68  {
69  public:
71  : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
72  _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
73 
74  __map2umap_info(__stack_t __stack)
75  : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
76  _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
77 
78  virtual ~__map2umap_info() { }
79 
81  : __object_info_base(__o), _M_insert(__o._M_insert),
82  _M_erase(__o._M_erase), _M_find(__o._M_find),
83  _M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
84  _M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
85 
86  void
87  __merge(const __map2umap_info& __o)
88  {
89  _M_insert += __o._M_insert;
90  _M_erase += __o._M_erase;
91  _M_find += __o._M_find;
92  _M_umap_cost += __o._M_umap_cost;
93  _M_map_cost += __o._M_map_cost;
94  _M_valid &= __o._M_valid;
95  }
96 
97  void
98  __write(FILE* __f) const
99  {
100  std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
101  _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
102  _M_umap_cost, _M_valid ? "valid" : "invalid");
103  }
104 
105  float
106  __magnitude() const
107  { return _M_map_cost - _M_umap_cost; }
108 
110  __advice() const
111  { return "change std::map to std::unordered_map"; }
112 
113  void
114  __record_insert(std::size_t __size, std::size_t __count)
115  {
116  _M_insert += __count;
117  _M_map_cost += __count * __map_insert_cost(__size);
118  _M_umap_cost
119  += (__count
120  * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
121  }
122 
123  void
124  __record_erase(std::size_t __size, std::size_t __count)
125  {
126  _M_erase += __count;
127  _M_map_cost += __count * __map_erase_cost(__size);
128  _M_umap_cost
129  += (__count
130  * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
131  }
132 
133  void
134  __record_find(std::size_t __size)
135  {
136  _M_find += 1;
137  _M_map_cost += __map_find_cost(__size);
138  _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
139  }
140 
141  void
142  __record_iterate(std::size_t __count)
143  {
144  _M_iterate += __count;
145  _M_map_cost
146  += (__count
147  * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
148  _M_umap_cost
149  += (__count
150  * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
151  }
152 
153  void
154  __record_invalidate()
155  { _M_valid = false; }
156 
157  private:
158  std::size_t _M_insert;
159  std::size_t _M_erase;
160  std::size_t _M_find;
161  std::size_t _M_iterate;
162  float _M_umap_cost;
163  float _M_map_cost;
164  bool _M_valid;
165  };
166 
167 
168  /** @brief A map-to-unordered_map instrumentation line in the
169  stack table. */
171  : public __map2umap_info
172  {
173  public:
175  : __map2umap_info(__o) { }
176  };
177 
178  /** @brief Map-to-unordered_map instrumentation producer. */
180  : public __trace_base<__map2umap_info, __map2umap_stack_info>
181  {
182  public:
185  { __id = "map-to-unordered-map"; }
186  };
187 
188  inline void
189  __trace_map_to_unordered_map_init()
190  { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
191 
192  inline void
193  __trace_map_to_unordered_map_report(FILE* __f,
194  __warning_vector_t& __warnings)
195  {
196  if (_GLIBCXX_PROFILE_DATA(_S_map2umap))
197  {
198  _GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
199  _GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
200  }
201  }
202 
203  inline void
204  __trace_map_to_unordered_map_construct(const void* __obj)
205  {
206  if (!__profcxx_init())
207  return;
208 
209  _GLIBCXX_PROFILE_DATA(_S_map2umap)->
210  __add_object(__obj, __map2umap_info(__get_stack()));
211  }
212 
213  inline void
214  __trace_map_to_unordered_map_destruct(const void* __obj)
215  {
216  if (!__profcxx_init())
217  return;
218 
219  _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
220  }
221 
222  inline void
223  __trace_map_to_unordered_map_insert(const void* __obj,
224  std::size_t __size, std::size_t __count)
225  {
226  if (!__profcxx_init())
227  return;
228 
229  __map2umap_info* __info
230  = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
231 
232  if (__info)
233  __info->__record_insert(__size, __count);
234  }
235 
236  inline void
237  __trace_map_to_unordered_map_erase(const void* __obj,
238  std::size_t __size, std::size_t __count)
239  {
240  if (!__profcxx_init())
241  return;
242 
243  __map2umap_info* __info
244  = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
245 
246  if (__info)
247  __info->__record_erase(__size, __count);
248  }
249 
250  inline void
251  __trace_map_to_unordered_map_find(const void* __obj, std::size_t __size)
252  {
253  if (!__profcxx_init())
254  return;
255 
256  __map2umap_info* __info
257  = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
258 
259  if (__info)
260  __info->__record_find(__size);
261  }
262 
263  inline void
264  __trace_map_to_unordered_map_iterate(const void* __obj, std::size_t __count)
265  {
266  if (!__profcxx_init())
267  return;
268 
269  __map2umap_info* __info
270  = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
271 
272  if (__info)
273  __info->__record_iterate(__count);
274  }
275 
276  inline void
277  __trace_map_to_unordered_map_invalidate(const void* __obj)
278  {
279  if (!__profcxx_init())
280  return;
281 
282  __map2umap_info* __info
283  = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
284 
285  if (__info)
286  __info->__record_invalidate();
287  }
288 
289 } // namespace __gnu_profile
290 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */