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 terms 7 // of the GNU General Public License as published by the Free Software 8 // Foundation; either version 2, or (at your option) any later 9 // version. 10 11 // This library is distributed in the hope that it will be useful, but 12 // WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License 17 // along with this library; see the file COPYING. If not, write to 18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston, 19 // MA 02111-1307, USA. 20 21 // As a special exception, you may use this file as part of a free 22 // software library without restriction. Specifically, if other files 23 // instantiate templates or use macros or inline functions from this 24 // file, or you compile this file and link it with other files to 25 // produce an executable, this file does not by itself cause the 26 // resulting executable to be covered by the GNU General Public 27 // License. This exception does not however invalidate any other 28 // reasons why the executable file might be covered by the GNU General 29 // Public License. 30 31 /** @file profile/impl/profiler_list_to_slist.h 32 * @brief Diagnostics for list to slist. 33 */ 34 35 // Written by Changhee Jung. 36 37 #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 38 #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1 39 40 #include "profile/impl/profiler.h" 41 #include "profile/impl/profiler_node.h" 42 #include "profile/impl/profiler_trace.h" 43 44 namespace __gnu_profile 45 { 46 class __list2slist_info 47 : public __object_info_base 48 { 49 public: 50 __list2slist_info() 51 : _M_rewind(false), _M_operations(0) { } 52 53 __list2slist_info(__stack_t __stack) 54 : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } 55 56 virtual ~__list2slist_info() { } 57 58 __list2slist_info(const __list2slist_info& __o) 59 : __object_info_base(__o), _M_rewind(__o._M_rewind), 60 _M_operations(__o._M_operations) { } 61 62 // XXX: the magnitude should be multiplied with a constant factor F, 63 // where F is 1 when the malloc size class of list nodes is different 64 // from the malloc size class of slist nodes. When they fall into the same 65 // class, the only slist benefit is from having to set fewer links, so 66 // the factor F should be much smaller, closer to 0 than to 1. 67 // This could be implemented by passing the size classes in the config 68 // file. For now, we always assume F to be 1. 69 70 float 71 __magnitude() const 72 { 73 if (!_M_rewind) 74 return _M_operations; 75 else 76 return 0; 77 } 78 79 void 80 __merge(const __list2slist_info&) { } 81 82 void 83 __write(FILE* __f) const 84 { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } 85 86 std::string 87 __advice() const 88 { return "change std::list to std::forward_list"; } 89 90 void 91 __opr_rewind() 92 { 93 _M_rewind = true; 94 _M_valid = false; 95 } 96 97 void 98 __record_operation() 99 { ++_M_operations; } 100 101 bool 102 __has_rewind() 103 { return _M_rewind; } 104 105 private: 106 bool _M_rewind; 107 std::size_t _M_operations; 108 }; 109 110 class __list2slist_stack_info 111 : public __list2slist_info 112 { 113 public: 114 __list2slist_stack_info(const __list2slist_info& __o) 115 : __list2slist_info(__o) { } 116 }; 117 118 class __trace_list_to_slist 119 : public __trace_base<__list2slist_info, __list2slist_stack_info> 120 { 121 public: 122 ~__trace_list_to_slist() { } 123 124 __trace_list_to_slist() 125 : __trace_base<__list2slist_info, __list2slist_stack_info>() 126 { __id = "list-to-slist"; } 127 128 void 129 __opr_rewind(const void* __obj) 130 { 131 __list2slist_info* __res = __get_object_info(__obj); 132 if (__res) 133 __res->__opr_rewind(); 134 } 135 136 void 137 __record_operation(const void* __obj) 138 { 139 __list2slist_info* __res = __get_object_info(__obj); 140 if (__res) 141 __res->__record_operation(); 142 } 143 144 void 145 __insert(const __object_t __obj, __stack_t __stack) 146 { __add_object(__obj, __list2slist_info(__stack)); } 147 148 void 149 __destruct(const void* __obj) 150 { 151 if (!__is_on()) 152 return; 153 154 __list2slist_info* __res = __get_object_info(__obj); 155 if (!__res) 156 return; 157 158 __retire_object(__obj); 159 } 160 }; 161 162 163 inline void 164 __trace_list_to_slist_init() 165 { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } 166 167 inline void 168 __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) 169 { 170 if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist)) 171 { 172 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)-> 173 __collect_warnings(__warnings); 174 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f); 175 } 176 } 177 178 inline void 179 __trace_list_to_slist_rewind(const void* __obj) 180 { 181 if (!__profcxx_init()) 182 return; 183 184 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj); 185 } 186 187 inline void 188 __trace_list_to_slist_operation(const void* __obj) 189 { 190 if (!__profcxx_init()) 191 return; 192 193 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj); 194 } 195 196 inline void 197 __trace_list_to_slist_construct(const void* __obj) 198 { 199 if (!__profcxx_init()) 200 return; 201 202 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack()); 203 } 204 205 inline void 206 __trace_list_to_slist_destruct(const void* __obj) 207 { 208 if (!__profcxx_init()) 209 return; 210 211 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj); 212 } 213 214 } // namespace __gnu_profile 215 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ 216