# profiler_vector_to_list.h

Go to the documentation of this file.

    00001 // -*- C++ -*-
    00002 //
    00003 // Copyright (C) 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the terms
    00007 // of the GNU General Public License as published by the Free Software
    00008 // Foundation; either version 2, or (at your option) any later
    00009 // version.
    00010
    00011 // This library is distributed in the hope that it will be useful, but
    00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014 // General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License
    00017 // along with this library; see the file COPYING.  If not, write to
    00018 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
    00019 // MA 02111-1307, USA.
    00020
    00021 // As a special exception, you may use this file as part of a free
    00022 // software library without restriction.  Specifically, if other files
    00023 // instantiate templates or use macros or inline functions from this
    00024 // file, or you compile this file and link it with other files to
    00025 // produce an executable, this file does not by itself cause the
    00026 // resulting executable to be covered by the GNU General Public
    00027 // License.  This exception does not however invalidate any other
    00028 // reasons why the executable file might be covered by the GNU General
    00029 // Public License.
    00030
    00031 /** @file profile/impl/profiler_vector_to_list.h
    00032  *  @brief diagnostics for vector to list.
    00033  */
    00034
    00035 // Written by Lixia Liu and Silvius Rus.
    00036
    00037 #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H
    00038 #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1
    00039
    00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00041 #include <cstdio>
    00042 #include <cstdlib>
    00043 #include <cstring>
    00044 #else
    00045 #include <stdio.h>
    00046 #include <stdint.h>
    00047 #include <string.h>
    00048 #endif
    00049 #include "profile/impl/profiler.h"
    00050 #include "profile/impl/profiler_node.h"
    00051 #include "profile/impl/profiler_trace.h"
    00052
    00053 namespace __gnu_profile
    00054 {
    00055
    00056 /** @brief A vector-to-list instrumentation line in the object table.  */
    00057 class __vector2list_info: public __object_info_base
    00058 {
    00059  public:
    00060   __vector2list_info()
    00061       :_M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
    00062        _M_vector_cost(0), _M_valid(true) {}
    00063   __vector2list_info(__stack_t __stack)
    00064       : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
    00065         _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) {}
    00066   virtual ~__vector2list_info() {}
    00067   __vector2list_info(const __vector2list_info& __o);
    00068   void __merge(const __vector2list_info& __o);
    00069   void __write(FILE* __f) const;
    00070   float __magnitude() const { return _M_vector_cost - _M_list_cost; }
    00071   const char* __advice() const
    00072   { return strdup("change std::vector to std::list"); }
    00073
    00074   size_t __shift_count() { return _M_shift_count; }
    00075   size_t __iterate()   { return _M_iterate; }
    00076   float __list_cost() { return _M_list_cost; }
    00077   size_t __resize() { return _M_resize; }
    00078   void __set_list_cost(float __lc) { _M_list_cost = __lc; }
    00079   void __set_vector_cost(float __vc) { _M_vector_cost = __vc; }
    00080   bool __is_valid() { return _M_valid; }
    00081   void __set_invalid() { _M_valid = false; }
    00082
    00083   void __opr_insert(size_t __pos, size_t __num);
    00084   void __opr_iterate(size_t __num);
    00085   void __resize(size_t __from, size_t __to);
    00086   void __opr_find(size_t __size);
    00087
    00088 private:
    00089   size_t _M_shift_count;
    00090   size_t _M_iterate;
    00091   size_t _M_resize;
    00092   float _M_list_cost;
    00093   float _M_vector_cost;
    00094   bool  _M_valid;
    00095 };
    00096
    00097 inline __vector2list_info::__vector2list_info(const __vector2list_info& __o)
    00098     : __object_info_base(__o)
    00099 {
    00100   _M_shift_count  = __o._M_shift_count;
    00101   _M_iterate      = __o._M_iterate;
    00102   _M_vector_cost  = __o._M_vector_cost;
    00103   _M_list_cost    = __o._M_list_cost;
    00104   _M_valid        = __o._M_valid;
    00105   _M_resize       = __o._M_resize;
    00106 }
    00107
    00108 inline void __vector2list_info::__merge(const __vector2list_info& __o)
    00109 {
    00110   _M_shift_count  += __o._M_shift_count;
    00111   _M_iterate      += __o._M_iterate;
    00112   _M_vector_cost  += __o._M_vector_cost;
    00113   _M_list_cost    += __o._M_list_cost;
    00114   _M_valid        &= __o._M_valid;
    00115   _M_resize       += __o._M_resize;
    00116 }
    00117
    00118 inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num)
    00119 {
    00120   _M_shift_count += __num - __pos;
    00121 }
    00122
    00123 inline void __vector2list_info::__resize(size_t __from, size_t __to)
    00124 {
    00125   _M_resize += __from;
    00126 }
    00127
    00128 inline void __vector2list_info::__opr_iterate(size_t __num)
    00129 {
    00130   _M_iterate += __num;
    00131 }
    00132
    00133 inline void __vector2list_info::__opr_find(size_t __size)
    00134 {
    00135   // Use average case complexity.
    00136   _M_iterate += 3.0 / 4.0 * __size;
    00137 }
    00138
    00139 /** @brief A vector-to-list instrumentation line in the stack table.  */
    00140 class __vector2list_stack_info: public __vector2list_info {
    00141  public:
    00142   __vector2list_stack_info(const __vector2list_info& __o)
    00143       : __vector2list_info(__o) {}
    00144 };
    00145
    00146 /** @brief Vector-to-list instrumentation producer.  */
    00147 class __trace_vector_to_list
    00148     : public __trace_base<__vector2list_info, __vector2list_stack_info>
    00149 {
    00150  public:
    00151   __trace_vector_to_list();
    00152   ~__trace_vector_to_list() {}
    00153
    00154   // Insert a new node at construct with object, callstack and initial size.
    00155   void __insert(__object_t __obj, __stack_t __stack);
    00156   // Call at destruction/clean to set container final size.
    00157   void __destruct(const void* __obj);
    00158
    00159   // Find the node in the live map.
    00160   __vector2list_info* __find(const void* __obj);
    00161
    00162   // Collect cost of operations.
    00163   void __opr_insert(const void* __obj, size_t __pos, size_t __num);
    00164   void __opr_iterate(const void* __obj, size_t __num);
    00165   void __invalid_operator(const void* __obj);
    00166   void __resize(const void* __obj, size_t __from, size_t __to);
    00167   float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
    00168   float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
    00169   void __opr_find(const void* __obj, size_t __size);
    00170 };
    00171
    00172 inline __trace_vector_to_list::__trace_vector_to_list()
    00173     : __trace_base<__vector2list_info, __vector2list_stack_info>()
    00174 {
    00175   __id = "vector-to-list";
    00176 }
    00177
    00178 inline void __trace_vector_to_list::__insert(__object_t __obj,
    00179                                              __stack_t __stack)
    00180 {
    00181   __add_object(__obj, __vector2list_info(__stack));
    00182 }
    00183
    00184 inline void __vector2list_info::__write(FILE* __f) const
    00185 {
    00186   fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
    00187           _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
    00188 }
    00189
    00190 inline float __trace_vector_to_list::__vector_cost(size_t __shift,
    00191                                                    size_t __iterate,
    00192                                                    size_t __resize)
    00193 {
    00194   return (
    00195       __shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
    00196       + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
    00197       + __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value
    00198       );
    00199 }
    00200
    00201 inline float __trace_vector_to_list::__list_cost(size_t __shift,
    00202                                                  size_t __iterate,
    00203                                                  size_t __resize)
    00204 {
    00205   return (
    00206       __shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
    00207       + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
    00208       + __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
    00209 }
    00210
    00211 inline void __trace_vector_to_list::__destruct(const void* __obj)
    00212 {
    00213   if (!__is_on())
    00214     return;
    00215
    00216  __vector2list_info* __res = __get_object_info(__obj);
    00217   if (!__res)
    00218     return;
    00219
    00220   float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
    00221                              __res->__resize());
    00222   float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
    00223                            __res->__resize());
    00224   __res->__set_vector_cost(__vc);
    00225   __res->__set_list_cost(__lc);
    00226
    00227   __retire_object(__obj);
    00228 }
    00229
    00230 inline void __trace_vector_to_list::__opr_insert(const void* __obj,
    00231                                                  size_t __pos, size_t __num)
    00232 {
    00233   __vector2list_info* __res = __get_object_info(__obj);
    00234   if (__res)
    00235     __res->__opr_insert(__pos, __num);
    00236 }
    00237
    00238 inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
    00239                                                   size_t __num)
    00240 {
    00241   __vector2list_info* __res = __get_object_info(__obj);
    00242   if (__res)
    00243     __res->__opr_iterate(__num);
    00244 }
    00245
    00246 inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
    00247 {
    00248   __vector2list_info* __res = __get_object_info(__obj);
    00249   if (__res)
    00250     __res->__set_invalid();
    00251 }
    00252
    00253 inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from,
    00254                                              size_t __to)
    00255 {
    00256   __vector2list_info* __res = __get_object_info(__obj);
    00257   if (__res)
    00258     __res->__resize(__from, __to);
    00259 }
    00260
    00261 inline void __trace_vector_to_list::__opr_find(const void* __obj,
    00262                                                size_t __size)
    00263 {
    00264   __vector2list_info* __res = __get_object_info(__obj);
    00265   if (__res)
    00266     __res->__opr_find(__size);
    00267 }
    00268
    00269 inline void __trace_vector_to_list_init()
    00270 {
    00271   _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list();
    00272 }
    00273
    00274 inline void __trace_vector_to_list_report(FILE* __f,
    00275                                           __warning_vector_t& __warnings)
    00276 {
    00277   if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list)) {
    00278     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__collect_warnings(__warnings);
    00279     _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
    00280   }
    00281 }
    00282
    00283 inline void __trace_vector_to_list_construct(const void* __obj)
    00284 {
    00285   if (!__profcxx_init()) return;
    00286
    00287   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
    00288 }
    00289
    00290 inline void __trace_vector_to_list_destruct(const void* __obj)
    00291 {
    00292   if (!__profcxx_init()) return;
    00293
    00294   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
    00295 }
    00296
    00297 inline void __trace_vector_to_list_insert(const void* __obj,
    00298                                           size_t __pos, size_t __num)
    00299 {
    00300   if (!__profcxx_init()) return;
    00301
    00302   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos, __num);
    00303 }
    00304
    00305
    00306 inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num = 1)
    00307 {
    00308   if (!__profcxx_init()) return;
    00309
    00310   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
    00311 }
    00312
    00313 inline void __trace_vector_to_list_invalid_operator(const void* __obj)
    00314 {
    00315   if (!__profcxx_init()) return;
    00316
    00317   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
    00318 }
    00319
    00320 inline void __trace_vector_to_list_resize(const void* __obj,
    00321                                           size_t __from, size_t __to)
    00322 {
    00323   if (!__profcxx_init()) return;
    00324
    00325   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
    00326 }
    00327
    00328 inline void __trace_vector_to_list_find(const void* __obj, size_t __size)
    00329 {
    00330   if (!__profcxx_init()) return;
    00331
    00332   _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
    00333 }
    00334
    00335 } // namespace __gnu_profile
    00336 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */