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_node.h 25 * @brief Data structures to represent a single profiling event. 26 */ 27 28 // Written by Lixia Liu and Silvius Rus. 29 30 #ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H 31 #define _GLIBCXX_PROFILE_PROFILER_NODE_H 1 32 33 #include <cstdio> // FILE, fprintf 34 35 #include <vector> 36 #if defined _GLIBCXX_HAVE_EXECINFO_H 37 #include <execinfo.h> 38 #endif 39 40 namespace __gnu_profile 41 { 42 typedef void* __instruction_address_t; 43 typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt; 44 typedef __stack_npt* __stack_t; 45 46 std::size_t __stack_max_depth(); 47 48 inline __stack_t __get_stack()49 __get_stack() 50 { 51 #if defined _GLIBCXX_HAVE_EXECINFO_H 52 __try 53 { 54 std::size_t __max_depth = __stack_max_depth(); 55 if (__max_depth == 0) 56 return 0; 57 __stack_npt __buffer(__max_depth); 58 int __depth = backtrace(&__buffer[0], __max_depth); 59 return new(std::nothrow) __stack_npt(__buffer.begin(), 60 __buffer.begin() + __depth); 61 } 62 __catch(...) 63 { 64 return 0; 65 } 66 #else 67 return 0; 68 #endif 69 } 70 71 inline std::size_t __size(__stack_t __stack)72 __size(__stack_t __stack) 73 { 74 if (!__stack) 75 return 0; 76 else 77 return __stack->size(); 78 } 79 80 // XXX 81 inline void __write(FILE * __f,__stack_t __stack)82 __write(FILE* __f, __stack_t __stack) 83 { 84 if (!__stack) 85 return; 86 87 __stack_npt::const_iterator __it; 88 for (__it = __stack->begin(); __it != __stack->end(); ++__it) 89 std::fprintf(__f, "%p ", *__it); 90 } 91 92 /** @brief Hash function for summary trace using call stack as index. */ 93 class __stack_hash 94 { 95 public: 96 std::size_t operator()97 operator()(__stack_t __s) const 98 { 99 if (!__s) 100 return 0; 101 102 std::size_t __index = 0; 103 __stack_npt::const_iterator __it; 104 for (__it = __s->begin(); __it != __s->end(); ++__it) 105 __index += reinterpret_cast<std::size_t>(*__it); 106 return __index; 107 } 108 operator()109 bool operator() (__stack_t __stack1, __stack_t __stack2) const 110 { 111 if (!__stack1 && !__stack2) 112 return true; 113 if (!__stack1 || !__stack2) 114 return false; 115 if (__stack1->size() != __stack2->size()) 116 return false; 117 118 std::size_t __byte_size 119 = __stack1->size() * sizeof(__stack_npt::value_type); 120 return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0], 121 __byte_size) == 0; 122 } 123 }; 124 125 126 /** @brief Base class for a line in the object table. */ 127 class __object_info_base 128 { 129 public: __object_info_base(__stack_t __stack)130 __object_info_base(__stack_t __stack) 131 : _M_stack(__stack), _M_valid(true) { } 132 133 bool __is_valid()134 __is_valid() const 135 { return _M_valid; } 136 137 void __set_invalid()138 __set_invalid() 139 { _M_valid = false; } 140 141 void __merge(const __object_info_base & __o)142 __merge(const __object_info_base& __o) 143 { _M_valid &= __o._M_valid; } 144 145 __stack_t __stack()146 __stack() const 147 { return _M_stack; } 148 149 protected: 150 __stack_t _M_stack; 151 bool _M_valid; 152 }; 153 154 } // namespace __gnu_profile 155 #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */ 156