1 // -*- C++ -*- 2 // 3 // Copyright (C) 2009-2018 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(__stack_t __stack) 44 : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } 45 46 // XXX: the magnitude should be multiplied with a constant factor F, 47 // where F is 1 when the malloc size class of list nodes is different 48 // from the malloc size class of slist nodes. When they fall into the same 49 // class, the only slist benefit is from having to set fewer links, so 50 // the factor F should be much smaller, closer to 0 than to 1. 51 // This could be implemented by passing the size classes in the config 52 // file. For now, we always assume F to be 1. 53 54 float 55 __magnitude() const 56 { 57 if (!_M_rewind) 58 return _M_operations; 59 else 60 return 0; 61 } 62 63 void 64 __write(FILE* __f) const 65 { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } 66 67 std::string 68 __advice() const 69 { return "change std::list to std::forward_list"; } 70 71 void 72 __opr_rewind() 73 { 74 _M_rewind = true; 75 __set_invalid(); 76 } 77 78 void 79 __record_operation() 80 { ++_M_operations; } 81 82 bool 83 __has_rewind() 84 { return _M_rewind; } 85 86 private: 87 bool _M_rewind; 88 std::size_t _M_operations; 89 }; 90 91 class __list2slist_stack_info 92 : public __list2slist_info 93 { 94 public: 95 __list2slist_stack_info(const __list2slist_info& __o) 96 : __list2slist_info(__o) { } 97 }; 98 99 class __trace_list_to_slist 100 : public __trace_base<__list2slist_info, __list2slist_stack_info> 101 { 102 public: 103 ~__trace_list_to_slist() { } 104 105 __trace_list_to_slist() 106 : __trace_base<__list2slist_info, __list2slist_stack_info>() 107 { __id = "list-to-slist"; } 108 109 void 110 __destruct(__list2slist_info* __obj_info) 111 { __retire_object(__obj_info); } 112 }; 113 114 115 inline void 116 __trace_list_to_slist_init() 117 { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } 118 119 inline void 120 __trace_list_to_slist_free() 121 { delete _GLIBCXX_PROFILE_DATA(_S_list_to_slist); } 122 123 inline void 124 __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) 125 { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_slist), __f, __warnings); } 126 127 inline __list2slist_info* 128 __trace_list_to_slist_construct() 129 { 130 if (!__profcxx_init()) 131 return 0; 132 133 if (!__reentrance_guard::__get_in()) 134 return 0; 135 136 __reentrance_guard __get_out; 137 return _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__add_object(__get_stack()); 138 } 139 140 inline void 141 __trace_list_to_slist_rewind(__list2slist_info* __obj_info) 142 { 143 if (!__obj_info) 144 return; 145 146 __obj_info->__opr_rewind(); 147 } 148 149 inline void 150 __trace_list_to_slist_operation(__list2slist_info* __obj_info) 151 { 152 if (!__obj_info) 153 return; 154 155 __obj_info->__record_operation(); 156 } 157 158 inline void 159 __trace_list_to_slist_destruct(__list2slist_info* __obj_info) 160 { 161 if (!__obj_info) 162 return; 163 164 _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj_info); 165 } 166 167 } // namespace __gnu_profile 168 #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ 169