136ac495dSmrg // -*- C++ -*- 236ac495dSmrg // 3*c0a68be4Smrg // Copyright (C) 2009-2019 Free Software Foundation, Inc. 436ac495dSmrg // 536ac495dSmrg // This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg // software; you can redistribute it and/or modify it under the 736ac495dSmrg // terms of the GNU General Public License as published by the 836ac495dSmrg // Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg // any later version. 1036ac495dSmrg // 1136ac495dSmrg // This library is distributed in the hope that it will be useful, 1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg // GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg // 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg // You should have received a copy of the GNU General Public License along 2136ac495dSmrg // with this library; see the file COPYING3. If not see 2236ac495dSmrg // <http://www.gnu.org/licenses/>. 2336ac495dSmrg 2436ac495dSmrg /** @file profile/impl/profiler_node.h 2536ac495dSmrg * @brief Data structures to represent a single profiling event. 2636ac495dSmrg */ 2736ac495dSmrg 2836ac495dSmrg // Written by Lixia Liu and Silvius Rus. 2936ac495dSmrg 3036ac495dSmrg #ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H 3136ac495dSmrg #define _GLIBCXX_PROFILE_PROFILER_NODE_H 1 3236ac495dSmrg 3336ac495dSmrg #include <cstdio> // FILE, fprintf 3436ac495dSmrg 3536ac495dSmrg #include <vector> 3636ac495dSmrg #if defined _GLIBCXX_HAVE_EXECINFO_H 3736ac495dSmrg #include <execinfo.h> 3836ac495dSmrg #endif 3936ac495dSmrg 4036ac495dSmrg namespace __gnu_profile 4136ac495dSmrg { 4236ac495dSmrg typedef void* __instruction_address_t; 4336ac495dSmrg typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt; 4436ac495dSmrg typedef __stack_npt* __stack_t; 4536ac495dSmrg 4636ac495dSmrg std::size_t __stack_max_depth(); 4736ac495dSmrg 4836ac495dSmrg inline __stack_t __get_stack()4936ac495dSmrg __get_stack() 5036ac495dSmrg { 5136ac495dSmrg #if defined _GLIBCXX_HAVE_EXECINFO_H 5236ac495dSmrg __try 5336ac495dSmrg { 5436ac495dSmrg std::size_t __max_depth = __stack_max_depth(); 5536ac495dSmrg if (__max_depth == 0) 5636ac495dSmrg return 0; 5736ac495dSmrg __stack_npt __buffer(__max_depth); 5836ac495dSmrg int __depth = backtrace(&__buffer[0], __max_depth); 5936ac495dSmrg return new(std::nothrow) __stack_npt(__buffer.begin(), 6036ac495dSmrg __buffer.begin() + __depth); 6136ac495dSmrg } 6236ac495dSmrg __catch(...) 6336ac495dSmrg { 6436ac495dSmrg return 0; 6536ac495dSmrg } 6636ac495dSmrg #else 6736ac495dSmrg return 0; 6836ac495dSmrg #endif 6936ac495dSmrg } 7036ac495dSmrg 7136ac495dSmrg inline std::size_t __size(__stack_t __stack)7236ac495dSmrg __size(__stack_t __stack) 7336ac495dSmrg { 7436ac495dSmrg if (!__stack) 7536ac495dSmrg return 0; 7636ac495dSmrg else 7736ac495dSmrg return __stack->size(); 7836ac495dSmrg } 7936ac495dSmrg 8036ac495dSmrg // XXX 8136ac495dSmrg inline void __write(FILE * __f,__stack_t __stack)8236ac495dSmrg __write(FILE* __f, __stack_t __stack) 8336ac495dSmrg { 8436ac495dSmrg if (!__stack) 8536ac495dSmrg return; 8636ac495dSmrg 8736ac495dSmrg __stack_npt::const_iterator __it; 8836ac495dSmrg for (__it = __stack->begin(); __it != __stack->end(); ++__it) 8936ac495dSmrg std::fprintf(__f, "%p ", *__it); 9036ac495dSmrg } 9136ac495dSmrg 9236ac495dSmrg /** @brief Hash function for summary trace using call stack as index. */ 9336ac495dSmrg class __stack_hash 9436ac495dSmrg { 9536ac495dSmrg public: 9636ac495dSmrg std::size_t operator()9736ac495dSmrg operator()(__stack_t __s) const 9836ac495dSmrg { 9936ac495dSmrg if (!__s) 10036ac495dSmrg return 0; 10136ac495dSmrg 10236ac495dSmrg std::size_t __index = 0; 10336ac495dSmrg __stack_npt::const_iterator __it; 10436ac495dSmrg for (__it = __s->begin(); __it != __s->end(); ++__it) 10536ac495dSmrg __index += reinterpret_cast<std::size_t>(*__it); 10636ac495dSmrg return __index; 10736ac495dSmrg } 10836ac495dSmrg operator()10936ac495dSmrg bool operator() (__stack_t __stack1, __stack_t __stack2) const 11036ac495dSmrg { 11136ac495dSmrg if (!__stack1 && !__stack2) 11236ac495dSmrg return true; 11336ac495dSmrg if (!__stack1 || !__stack2) 11436ac495dSmrg return false; 11536ac495dSmrg if (__stack1->size() != __stack2->size()) 11636ac495dSmrg return false; 11736ac495dSmrg 11836ac495dSmrg std::size_t __byte_size 11936ac495dSmrg = __stack1->size() * sizeof(__stack_npt::value_type); 12036ac495dSmrg return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0], 12136ac495dSmrg __byte_size) == 0; 12236ac495dSmrg } 12336ac495dSmrg }; 12436ac495dSmrg 12536ac495dSmrg 12636ac495dSmrg /** @brief Base class for a line in the object table. */ 12736ac495dSmrg class __object_info_base 12836ac495dSmrg { 12936ac495dSmrg public: __object_info_base(__stack_t __stack)13036ac495dSmrg __object_info_base(__stack_t __stack) 13136ac495dSmrg : _M_stack(__stack), _M_valid(true) { } 13236ac495dSmrg 13336ac495dSmrg bool __is_valid()13436ac495dSmrg __is_valid() const 13536ac495dSmrg { return _M_valid; } 13636ac495dSmrg 13736ac495dSmrg void __set_invalid()13836ac495dSmrg __set_invalid() 13936ac495dSmrg { _M_valid = false; } 14036ac495dSmrg 14136ac495dSmrg void __merge(const __object_info_base & __o)14236ac495dSmrg __merge(const __object_info_base& __o) 14336ac495dSmrg { _M_valid &= __o._M_valid; } 14436ac495dSmrg 14536ac495dSmrg __stack_t __stack()14636ac495dSmrg __stack() const 14736ac495dSmrg { return _M_stack; } 14836ac495dSmrg 14936ac495dSmrg protected: 15036ac495dSmrg __stack_t _M_stack; 15136ac495dSmrg bool _M_valid; 15236ac495dSmrg }; 15336ac495dSmrg 15436ac495dSmrg } // namespace __gnu_profile 15536ac495dSmrg #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */ 156