libstdc++
|
00001 // -*- C++ -*- 00002 // 00003 // Copyright (C) 2009, 2010 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_list_to_slist.h 00032 * @brief Diagnostics for list to slist. 00033 */ 00034 00035 // Written by Changhee Jung. 00036 00037 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 00038 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1 00039 00040 #include "profile/impl/profiler.h" 00041 #include "profile/impl/profiler_node.h" 00042 #include "profile/impl/profiler_trace.h" 00043 00044 namespace __gnu_profile 00045 { 00046 class __list2slist_info 00047 : public __object_info_base 00048 { 00049 public: 00050 __list2slist_info() 00051 : _M_rewind(false), _M_operations(0) { } 00052 00053 __list2slist_info(__stack_t __stack) 00054 : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } 00055 00056 virtual ~__list2slist_info() { } 00057 00058 __list2slist_info(const __list2slist_info& __o) 00059 : __object_info_base(__o), _M_rewind(__o._M_rewind), 00060 _M_operations(__o._M_operations) { } 00061 00062 // XXX: the magnitude should be multiplied with a constant factor F, 00063 // where F is 1 when the malloc size class of list nodes is different 00064 // from the malloc size class of slist nodes. When they fall into the same 00065 // class, the only slist benefit is from having to set fewer links, so 00066 // the factor F should be much smaller, closer to 0 than to 1. 00067 // This could be implemented by passing the size classes in the config 00068 // file. For now, we always assume F to be 1. 00069 00070 float 00071 __magnitude() const 00072 { 00073 if (!_M_rewind) 00074 return _M_operations; 00075 else 00076 return 0; 00077 } 00078 00079 void 00080 __merge(const __list2slist_info&) { } 00081 00082 void 00083 __write(FILE* __f) const 00084 { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } 00085 00086 std::string 00087 __advice() const 00088 { return "change std::list to std::forward_list"; } 00089 00090 void 00091 __opr_rewind() 00092 { 00093 _M_rewind = true; 00094 _M_valid = false; 00095 } 00096 00097 void 00098 __record_operation() 00099 { ++_M_operations; } 00100 00101 bool 00102 __has_rewind() 00103 { return _M_rewind; } 00104 00105 private: 00106 bool _M_rewind; 00107 std::size_t _M_operations; 00108 }; 00109 00110 class __list2slist_stack_info 00111 : public __list2slist_info 00112 { 00113 public: 00114 __list2slist_stack_info(const __list2slist_info& __o) 00115 : __list2slist_info(__o) { } 00116 }; 00117 00118 class __trace_list_to_slist 00119 : public __trace_base<__list2slist_info, __list2slist_stack_info> 00120 { 00121 public: 00122 ~__trace_list_to_slist() { } 00123 00124 __trace_list_to_slist() 00125 : __trace_base<__list2slist_info, __list2slist_stack_info>() 00126 { __id = "list-to-slist"; } 00127 00128 void 00129 __opr_rewind(const void* __obj) 00130 { 00131 __list2slist_info* __res = __get_object_info(__obj); 00132 if (__res) 00133 __res->__opr_rewind(); 00134 } 00135 00136 void 00137 __record_operation(const void* __obj) 00138 { 00139 __list2slist_info* __res = __get_object_info(__obj); 00140 if (__res) 00141 __res->__record_operation(); 00142 } 00143 00144 void 00145 __insert(const __object_t __obj, __stack_t __stack) 00146 { __add_object(__obj, __list2slist_info(__stack)); } 00147 00148 void 00149 __destruct(const void* __obj) 00150 { 00151 if (!__is_on()) 00152 return; 00153 00154 __list2slist_info* __res = __get_object_info(__obj); 00155 if (!__res) 00156 return; 00157 00158 __retire_object(__obj); 00159 } 00160 }; 00161 00162 00163 inline void 00164 __trace_list_to_slist_init() 00165 { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } 00166 00167 inline void 00168 __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) 00169 { 00170 if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) 00171 { 00172 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)-> 00173 __collect_warnings(__warnings); 00174 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f); 00175 } 00176 } 00177 00178 inline void 00179 __trace_list_to_slist_rewind(const void* __obj) 00180 { 00181 if (!__profcxx_init()) 00182 return; 00183 00184 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj); 00185 } 00186 00187 inline void 00188 __trace_list_to_slist_operation(const void* __obj) 00189 { 00190 if (!__profcxx_init()) 00191 return; 00192 00193 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj); 00194 } 00195 00196 inline void 00197 __trace_list_to_slist_construct(const void* __obj) 00198 { 00199 if (!__profcxx_init()) 00200 return; 00201 00202 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack()); 00203 } 00204 00205 inline void 00206 __trace_list_to_slist_destruct(const void* __obj) 00207 { 00208 if (!__profcxx_init()) 00209 return; 00210 00211 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj); 00212 } 00213 00214 } // namespace __gnu_profile 00215 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */