libstdc++
|
00001 // -*- C++ -*- 00002 // 00003 // Copyright (C) 2009-2015 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 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 // 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License along 00021 // with this library; see the file COPYING3. If not see 00022 // <http://www.gnu.org/licenses/>. 00023 00024 /** @file profile/impl/profiler_vector_to_list.h 00025 * @brief diagnostics for vector to list. 00026 */ 00027 00028 // Written by Lixia Liu and Silvius Rus. 00029 00030 #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 00031 #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1 00032 00033 #include "profile/impl/profiler.h" 00034 #include "profile/impl/profiler_node.h" 00035 #include "profile/impl/profiler_trace.h" 00036 00037 namespace __gnu_profile 00038 { 00039 /** @brief A vector-to-list instrumentation line in the object table. */ 00040 class __vector2list_info 00041 : public __object_info_base 00042 { 00043 public: 00044 __vector2list_info(__stack_t __stack) 00045 : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), 00046 _M_resize(0), _M_list_cost(0), _M_vector_cost(0) 00047 { } 00048 00049 void 00050 __merge(const __vector2list_info& __o) 00051 { 00052 __object_info_base::__merge(__o); 00053 _M_shift_count += __o._M_shift_count; 00054 _M_iterate += __o._M_iterate; 00055 _M_vector_cost += __o._M_vector_cost; 00056 _M_list_cost += __o._M_list_cost; 00057 _M_resize += __o._M_resize; 00058 } 00059 00060 void 00061 __write(FILE* __f) const 00062 { 00063 std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, 00064 _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); 00065 } 00066 00067 float 00068 __magnitude() const 00069 { return _M_vector_cost - _M_list_cost; } 00070 00071 std::string 00072 __advice() const 00073 { return "change std::vector to std::list"; } 00074 00075 std::size_t 00076 __shift_count() 00077 { return _M_shift_count; } 00078 00079 std::size_t 00080 __iterate() 00081 { return _M_iterate; } 00082 00083 float 00084 __list_cost() 00085 { return _M_list_cost; } 00086 00087 std::size_t 00088 __resize() 00089 { return _M_resize; } 00090 00091 void 00092 __set_list_cost(float __lc) 00093 { _M_list_cost = __lc; } 00094 00095 void 00096 __set_vector_cost(float __vc) 00097 { _M_vector_cost = __vc; } 00098 00099 void 00100 __opr_insert(std::size_t __pos, std::size_t __num) 00101 { _M_shift_count += __num - __pos; } 00102 00103 void 00104 __opr_iterate(int __num) 00105 { __gnu_cxx::__atomic_add(&_M_iterate, __num); } 00106 00107 void 00108 __resize(std::size_t __from, std::size_t) 00109 { _M_resize += __from; } 00110 00111 private: 00112 std::size_t _M_shift_count; 00113 mutable _Atomic_word _M_iterate; 00114 std::size_t _M_resize; 00115 float _M_list_cost; 00116 float _M_vector_cost; 00117 }; 00118 00119 00120 /** @brief A vector-to-list instrumentation line in the stack table. */ 00121 class __vector2list_stack_info 00122 : public __vector2list_info 00123 { 00124 public: 00125 __vector2list_stack_info(const __vector2list_info& __o) 00126 : __vector2list_info(__o) { } 00127 }; 00128 00129 00130 /** @brief Vector-to-list instrumentation producer. */ 00131 class __trace_vector_to_list 00132 : public __trace_base<__vector2list_info, __vector2list_stack_info> 00133 { 00134 public: 00135 __trace_vector_to_list() 00136 : __trace_base<__vector2list_info, __vector2list_stack_info>() 00137 { __id = "vector-to-list"; } 00138 00139 ~__trace_vector_to_list() { } 00140 00141 // Call at destruction/clean to set container final size. 00142 void 00143 __destruct(__vector2list_info* __obj_info) 00144 { 00145 float __vc = __vector_cost(__obj_info->__shift_count(), 00146 __obj_info->__iterate(), 00147 __obj_info->__resize()); 00148 float __lc = __list_cost(__obj_info->__shift_count(), 00149 __obj_info->__iterate(), 00150 __obj_info->__resize()); 00151 __obj_info->__set_vector_cost(__vc); 00152 __obj_info->__set_list_cost(__lc); 00153 00154 __retire_object(__obj_info); 00155 } 00156 00157 // Collect cost of operations. 00158 float 00159 __vector_cost(std::size_t __shift, std::size_t __iterate, 00160 std::size_t __resize) 00161 { 00162 return (__shift 00163 * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value 00164 + __iterate 00165 * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value 00166 + __resize 00167 * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value); 00168 } 00169 00170 float 00171 __list_cost(std::size_t __shift, std::size_t __iterate, 00172 std::size_t __resize) 00173 { 00174 return (__shift 00175 * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value 00176 + __iterate 00177 * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value 00178 + __resize 00179 * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value); 00180 } 00181 }; 00182 00183 00184 inline void 00185 __trace_vector_to_list_init() 00186 { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); } 00187 00188 inline void 00189 __trace_vector_to_list_free() 00190 { delete _GLIBCXX_PROFILE_DATA(_S_vector_to_list); } 00191 00192 inline void 00193 __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings) 00194 { __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_to_list), __f, __warnings); } 00195 00196 inline __vector2list_info* 00197 __trace_vector_to_list_construct() 00198 { 00199 if (!__profcxx_init()) 00200 return 0; 00201 00202 if (!__reentrance_guard::__get_in()) 00203 return 0; 00204 00205 __reentrance_guard __get_out; 00206 return _GLIBCXX_PROFILE_DATA(_S_vector_to_list) 00207 ->__add_object(__get_stack()); 00208 } 00209 00210 inline void 00211 __trace_vector_to_list_insert(__vector2list_info* __obj_info, 00212 std::size_t __pos, 00213 std::size_t __num) 00214 { 00215 if (!__obj_info) 00216 return; 00217 00218 __obj_info->__opr_insert(__pos, __num); 00219 } 00220 00221 inline void 00222 __trace_vector_to_list_iterate(__vector2list_info* __obj_info, int) 00223 { 00224 if (!__obj_info) 00225 return; 00226 00227 // We only collect if an iteration took place no matter in what side. 00228 __obj_info->__opr_iterate(1); 00229 } 00230 00231 inline void 00232 __trace_vector_to_list_invalid_operator(__vector2list_info* __obj_info) 00233 { 00234 if (!__obj_info) 00235 return; 00236 00237 __obj_info->__set_invalid(); 00238 } 00239 00240 inline void 00241 __trace_vector_to_list_resize(__vector2list_info* __obj_info, 00242 std::size_t __from, 00243 std::size_t __to) 00244 { 00245 if (!__obj_info) 00246 return; 00247 00248 __obj_info->__resize(__from, __to); 00249 } 00250 00251 inline void 00252 __trace_vector_to_list_destruct(__vector2list_info* __obj_info) 00253 { 00254 if (!__obj_info) 00255 return; 00256 00257 _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj_info); 00258 } 00259 00260 } // namespace __gnu_profile 00261 #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */