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