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_list_to_slist.h 25 * @brief Diagnostics for list to slist. 26 */ 27 28 // Written by Changhee Jung. 29 30 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 31 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1 32 33 #include "profile/impl/profiler.h" 34 #include "profile/impl/profiler_node.h" 35 #include "profile/impl/profiler_trace.h" 36 37 namespace __gnu_profile 38 { 39 class __list2slist_info 40 : public __object_info_base 41 { 42 public: 43 __list2slist_info() 44 : _M_rewind(false), _M_operations(0) { } 45 46 __list2slist_info(__stack_t __stack) 47 : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } 48 49 virtual ~__list2slist_info() { } 50 51 __list2slist_info(const __list2slist_info& __o) 52 : __object_info_base(__o), _M_rewind(__o._M_rewind), 53 _M_operations(__o._M_operations) { } 54 55 // XXX: the magnitude should be multiplied with a constant factor F, 56 // where F is 1 when the malloc size class of list nodes is different 57 // from the malloc size class of slist nodes. When they fall into the same 58 // class, the only slist benefit is from having to set fewer links, so 59 // the factor F should be much smaller, closer to 0 than to 1. 60 // This could be implemented by passing the size classes in the config 61 // file. For now, we always assume F to be 1. 62 63 float 64 __magnitude() const 65 { 66 if (!_M_rewind) 67 return _M_operations; 68 else 69 return 0; 70 } 71 72 void 73 __merge(const __list2slist_info&) { } 74 75 void 76 __write(FILE* __f) const 77 { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } 78 79 std::string 80 __advice() const 81 { return "change std::list to std::forward_list"; } 82 83 void 84 __opr_rewind() 85 { 86 _M_rewind = true; 87 _M_valid = false; 88 } 89 90 void 91 __record_operation() 92 { ++_M_operations; } 93 94 bool 95 __has_rewind() 96 { return _M_rewind; } 97 98 private: 99 bool _M_rewind; 100 std::size_t _M_operations; 101 }; 102 103 class __list2slist_stack_info 104 : public __list2slist_info 105 { 106 public: 107 __list2slist_stack_info(const __list2slist_info& __o) 108 : __list2slist_info(__o) { } 109 }; 110 111 class __trace_list_to_slist 112 : public __trace_base<__list2slist_info, __list2slist_stack_info> 113 { 114 public: 115 ~__trace_list_to_slist() { } 116 117 __trace_list_to_slist() 118 : __trace_base<__list2slist_info, __list2slist_stack_info>() 119 { __id = "list-to-slist"; } 120 121 void 122 __opr_rewind(const void* __obj) 123 { 124 __list2slist_info* __res = __get_object_info(__obj); 125 if (__res) 126 __res->__opr_rewind(); 127 } 128 129 void 130 __record_operation(const void* __obj) 131 { 132 __list2slist_info* __res = __get_object_info(__obj); 133 if (__res) 134 __res->__record_operation(); 135 } 136 137 void 138 __insert(const __object_t __obj, __stack_t __stack) 139 { __add_object(__obj, __list2slist_info(__stack)); } 140 141 void 142 __destruct(const void* __obj) 143 { 144 if (!__is_on()) 145 return; 146 147 __list2slist_info* __res = __get_object_info(__obj); 148 if (!__res) 149 return; 150 151 __retire_object(__obj); 152 } 153 }; 154 155 156 inline void 157 __trace_list_to_slist_init() 158 { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } 159 160 inline void 161 __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) 162 { 163 if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) 164 { 165 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)-> 166 __collect_warnings(__warnings); 167 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f); 168 } 169 } 170 171 inline void 172 __trace_list_to_slist_rewind(const void* __obj) 173 { 174 if (!__profcxx_init()) 175 return; 176 177 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj); 178 } 179 180 inline void 181 __trace_list_to_slist_operation(const void* __obj) 182 { 183 if (!__profcxx_init()) 184 return; 185 186 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj); 187 } 188 189 inline void 190 __trace_list_to_slist_construct(const void* __obj) 191 { 192 if (!__profcxx_init()) 193 return; 194 195 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack()); 196 } 197 198 inline void 199 __trace_list_to_slist_destruct(const void* __obj) 200 { 201 if (!__profcxx_init()) 202 return; 203 204 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj); 205 } 206 207 } // namespace __gnu_profile 208 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ 209