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_trace.h 32 * @brief Data structures to represent profiling traces. 33 */ 34 35// Written by Lixia Liu and Silvius Rus. 36 37#ifndef _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 38#define _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 1 39 40#ifdef __GXX_EXPERIMENTAL_CXX0X__ 41#include <cstdlib> 42#include <cstdio> 43#include <cstring> 44#else 45#include <stdlib.h> 46#include <stdio.h> 47#include <string.h> 48#endif 49#include "profile/impl/profiler.h" 50#include "profile/impl/profiler_node.h" 51#include "profile/impl/profiler_trace.h" 52 53namespace __gnu_profile 54{ 55 56/** @brief A hash performance instrumentation line in the object table. */ 57class __hashfunc_info: public __object_info_base 58{ 59 public: 60 __hashfunc_info() 61 :_M_longest_chain(0), _M_accesses(0), _M_hops(0) {} 62 __hashfunc_info(const __hashfunc_info& o); 63 __hashfunc_info(__stack_t __stack) 64 : __object_info_base(__stack), 65 _M_longest_chain(0), _M_accesses(0), _M_hops(0){} 66 virtual ~__hashfunc_info() {} 67 68 void __merge(const __hashfunc_info& __o); 69 void __destruct(size_t __chain, size_t __accesses, size_t __hops); 70 void __write(FILE* __f) const; 71 float __magnitude() const { return static_cast<float>(_M_hops); } 72 const char* __advice() const { return strdup("change hash function"); } 73 74private: 75 size_t _M_longest_chain; 76 size_t _M_accesses; 77 size_t _M_hops; 78}; 79 80inline __hashfunc_info::__hashfunc_info(const __hashfunc_info& __o) 81 : __object_info_base(__o) 82{ 83 _M_longest_chain = __o._M_longest_chain; 84 _M_accesses = __o._M_accesses; 85 _M_hops = __o._M_hops; 86} 87 88inline void __hashfunc_info::__merge(const __hashfunc_info& __o) 89{ 90 _M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain); 91 _M_accesses += __o._M_accesses; 92 _M_hops += __o._M_hops; 93} 94 95inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses, 96 size_t __hops) 97{ 98 _M_longest_chain = std::max(_M_longest_chain, __chain); 99 _M_accesses += __accesses; 100 _M_hops += __hops; 101} 102 103/** @brief A hash performance instrumentation line in the stack table. */ 104class __hashfunc_stack_info: public __hashfunc_info { 105 public: 106 __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) {} 107}; 108 109/** @brief Hash performance instrumentation producer. */ 110class __trace_hash_func 111 : public __trace_base<__hashfunc_info, __hashfunc_stack_info> 112{ 113 public: 114 __trace_hash_func(); 115 ~__trace_hash_func() {} 116 117 // Insert a new node at construct with object, callstack and initial size. 118 void __insert(__object_t __obj, __stack_t __stack); 119 // Call at destruction/clean to set container final size. 120 void __destruct(const void* __obj, size_t __chain, 121 size_t __accesses, size_t __hops); 122}; 123 124inline __trace_hash_func::__trace_hash_func() 125 : __trace_base<__hashfunc_info, __hashfunc_stack_info>() 126{ 127 __id = "hash-distr"; 128} 129 130inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack) 131{ 132 __add_object(__obj, __hashfunc_info(__stack)); 133} 134 135inline void __hashfunc_info::__write(FILE* __f) const 136{ 137 fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); 138} 139 140inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain, 141 size_t __accesses, size_t __hops) 142{ 143 if (!__is_on()) return; 144 145 // First find the item from the live objects and update the informations. 146 __hashfunc_info* __objs = __get_object_info(__obj); 147 if (!__objs) 148 return; 149 150 __objs->__destruct(__chain, __accesses, __hops); 151 __retire_object(__obj); 152} 153 154inline void __trace_hash_func_init() 155{ 156 _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); 157} 158 159inline void __trace_hash_func_report(FILE* __f, 160 __warning_vector_t& __warnings) 161{ 162 if (_GLIBCXX_PROFILE_DATA(_S_hash_func)) { 163 _GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings); 164 _GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f); 165 } 166} 167 168inline void __trace_hash_func_construct(const void* __obj) 169{ 170 if (!__profcxx_init()) return; 171 172 _GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack()); 173} 174 175inline void __trace_hash_func_destruct(const void* __obj, size_t __chain, 176 size_t __accesses, size_t __hops) 177{ 178 if (!__profcxx_init()) return; 179 180 _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain, __accesses, 181 __hops); 182} 183 184} // namespace __gnu_profile 185#endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */ 186