summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/profile/impl
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/profile/impl')
-rw-r--r--libstdc++-v3/include/profile/impl/profiler.h402
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_algos.h111
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_container_size.h215
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hash_func.h174
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hashtable_size.h98
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_list_to_slist.h208
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_list_to_vector.h324
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h290
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_node.h166
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_state.h66
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_trace.h659
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_size.h97
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_to_list.h347
13 files changed, 3157 insertions, 0 deletions
diff --git a/libstdc++-v3/include/profile/impl/profiler.h b/libstdc++-v3/include/profile/impl/profiler.h
new file mode 100644
index 000000000..49785bbee
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler.h
@@ -0,0 +1,402 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler.h
+ * @brief Interface of the profiling runtime library.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_H
+#define _GLIBCXX_PROFILE_PROFILER_H 1
+
+#include <bits/c++config.h>
+
+// Mechanism to define data with inline linkage.
+#define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name) \
+ inline __type& \
+ __get_##__name() \
+ { \
+ static __type __name; \
+ return __name; \
+ }
+#define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \
+ inline __type& __get_##__name() { \
+ static __type __name(__initial_value); \
+ return __name; \
+ }
+#define _GLIBCXX_PROFILE_DATA(__name) \
+ __get_##__name()
+
+namespace __gnu_profile
+{
+ /** @brief Reentrance guard.
+ *
+ * Mechanism to protect all __gnu_profile operations against recursion,
+ * multithreaded and exception reentrance.
+ */
+ struct __reentrance_guard
+ {
+ static bool
+ __get_in()
+ {
+ if (__inside() == true)
+ return false;
+ else
+ {
+ __inside() = true;
+ return true;
+ }
+ }
+
+ static bool&
+ __inside()
+ {
+ static __thread bool _S_inside(false);
+ return _S_inside;
+ }
+
+ __reentrance_guard() { }
+ ~__reentrance_guard() { __inside() = false; }
+ };
+
+#define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...) \
+ { \
+ if (__gnu_profile::__reentrance_guard::__get_in()) \
+ { \
+ __gnu_profile::__reentrance_guard __get_out; \
+ __x; \
+ } \
+ }
+
+ // Forward declarations of implementation functions.
+ // Don't use any __gnu_profile:: in user code.
+ // Instead, use the __profcxx... macros, which offer guarded access.
+ bool __turn_on();
+ bool __turn_off();
+ bool __is_invalid();
+ bool __is_on();
+ bool __is_off();
+ void __report(void);
+ void __trace_hashtable_size_resize(const void*, std::size_t, std::size_t);
+ void __trace_hashtable_size_destruct(const void*, std::size_t, std::size_t);
+ void __trace_hashtable_size_construct(const void*, std::size_t);
+ void __trace_vector_size_resize(const void*, std::size_t, std::size_t);
+ void __trace_vector_size_destruct(const void*, std::size_t, std::size_t);
+ void __trace_vector_size_construct(const void*, std::size_t);
+ void __trace_hash_func_destruct(const void*, std::size_t, std::size_t,
+ std::size_t);
+ void __trace_hash_func_construct(const void*);
+ void __trace_vector_to_list_destruct(const void*);
+ void __trace_vector_to_list_construct(const void*);
+ void __trace_vector_to_list_insert(const void*, std::size_t, std::size_t);
+ void __trace_vector_to_list_iterate(const void*, std::size_t);
+ void __trace_vector_to_list_invalid_operator(const void*);
+ void __trace_vector_to_list_resize(const void*, std::size_t, std::size_t);
+ void __trace_vector_to_list_find(const void*, std::size_t);
+
+ void __trace_list_to_slist_destruct(const void*);
+ void __trace_list_to_slist_construct(const void*);
+ void __trace_list_to_slist_rewind(const void*);
+ void __trace_list_to_slist_operation(const void*);
+
+ void __trace_list_to_vector_destruct(const void*);
+ void __trace_list_to_vector_construct(const void*);
+ void __trace_list_to_vector_insert(const void*, std::size_t, std::size_t);
+ void __trace_list_to_vector_iterate(const void*, std::size_t);
+ void __trace_list_to_vector_invalid_operator(const void*);
+ void __trace_list_to_vector_resize(const void*, std::size_t, std::size_t);
+
+ void __trace_list_to_set_destruct(const void*);
+ void __trace_list_to_set_construct(const void*);
+ void __trace_list_to_set_insert(const void*, std::size_t, std::size_t);
+ void __trace_list_to_set_iterate(const void*, std::size_t);
+ void __trace_list_to_set_invalid_operator(const void*);
+ void __trace_list_to_set_find(const void*, std::size_t);
+
+ void __trace_map_to_unordered_map_construct(const void*);
+ void __trace_map_to_unordered_map_invalidate(const void*);
+ void __trace_map_to_unordered_map_insert(const void*, std::size_t,
+ std::size_t);
+ void __trace_map_to_unordered_map_erase(const void*, std::size_t,
+ std::size_t);
+ void __trace_map_to_unordered_map_iterate(const void*, std::size_t);
+ void __trace_map_to_unordered_map_find(const void*, std::size_t);
+ void __trace_map_to_unordered_map_destruct(const void*);
+} // namespace __gnu_profile
+
+// Master switch turns on all diagnostics that are not explicitly turned off.
+#ifdef _GLIBCXX_PROFILE
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
+#define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
+#define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
+#define _GLIBCXX_PROFILE_INEFFICIENT_HASH
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
+#define _GLIBCXX_PROFILE_VECTOR_TO_LIST
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST
+#define _GLIBCXX_PROFILE_LIST_TO_SLIST
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR
+#define _GLIBCXX_PROFILE_LIST_TO_VECTOR
+#endif
+#ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP
+#define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
+#endif
+#endif
+
+// Expose global management routines to user code.
+#ifdef _GLIBCXX_PROFILE
+#define __profcxx_report() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__report())
+#define __profcxx_turn_on() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_on())
+#define __profcxx_turn_off() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_off())
+#define __profcxx_is_invalid() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_invalid())
+#define __profcxx_is_on() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_on())
+#define __profcxx__is_off() \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_off())
+#else
+#define __profcxx_report()
+#define __profcxx_turn_on()
+#define __profcxx_turn_off()
+#define __profcxx_is_invalid()
+#define __profcxx_is_on()
+#define __profcxx_is_off()
+#endif
+
+// Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
+#if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
+ || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE))
+#define __profcxx_hashtable_resize(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_hashtable_size_resize(__x))
+#define __profcxx_hashtable_destruct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_hashtable_size_destruct(__x))
+#define __profcxx_hashtable_construct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_hashtable_size_construct(__x))
+#else
+#define __profcxx_hashtable_resize(__x...)
+#define __profcxx_hashtable_destruct(__x...)
+#define __profcxx_hashtable_construct(__x...)
+#endif
+
+// Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
+#if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
+ || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE))
+#define __profcxx_vector_resize(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_size_resize(__x))
+#define __profcxx_vector_destruct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_size_destruct(__x))
+#define __profcxx_vector_construct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_size_construct(__x))
+#else
+#define __profcxx_vector_resize(__x...)
+#define __profcxx_vector_destruct(__x...)
+#define __profcxx_vector_construct(__x...)
+#endif
+
+// Turn on/off instrumentation for INEFFICIENT_HASH.
+#if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
+#define __profcxx_hashtable_construct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_hash_func_construct(__x))
+#define __profcxx_hashtable_destruct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_hash_func_destruct(__x))
+#else
+#define __profcxx_hashtable_destruct2(__x...)
+#define __profcxx_hashtable_construct2(__x...)
+#endif
+
+// Turn on/off instrumentation for VECTOR_TO_LIST.
+#if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
+#define __profcxx_vector_construct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_construct(__x))
+#define __profcxx_vector_destruct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_destruct(__x))
+#define __profcxx_vector_insert(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_insert(__x))
+#define __profcxx_vector_iterate(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_iterate(__x))
+#define __profcxx_vector_invalid_operator(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_invalid_operator(__x))
+#define __profcxx_vector_resize2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_resize(__x))
+#define __profcxx_vector_find(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_vector_to_list_find(__x))
+#else
+#define __profcxx_vector_destruct2(__x...)
+#define __profcxx_vector_construct2(__x...)
+#define __profcxx_vector_insert(__x...)
+#define __profcxx_vector_iterate(__x...)
+#define __profcxx_vector_invalid_operator(__x...)
+#define __profcxx_vector_resize2(__x...)
+#define __profcxx_vector_find(__x...)
+#endif
+
+// Turn on/off instrumentation for LIST_TO_VECTOR.
+#if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR)
+#define __profcxx_list_construct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_vector_construct(__x))
+#define __profcxx_list_destruct2(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_vector_destruct(__x))
+#define __profcxx_list_insert(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_vector_insert(__x))
+#define __profcxx_list_iterate(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_vector_iterate(__x))
+#define __profcxx_list_invalid_operator(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_vector_invalid_operator(__x))
+#else
+#define __profcxx_list_destruct2(__x...)
+#define __profcxx_list_construct2(__x...)
+#define __profcxx_list_insert(__x...)
+#define __profcxx_list_iterate(__x...)
+#define __profcxx_list_invalid_operator(__x...)
+#endif
+
+// Turn on/off instrumentation for LIST_TO_SLIST.
+#if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST)
+#define __profcxx_list_rewind(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_slist_rewind(__x))
+#define __profcxx_list_operation(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_slist_operation(__x))
+#define __profcxx_list_destruct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_slist_destruct(__x))
+#define __profcxx_list_construct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_list_to_slist_construct(__x))
+#else
+#define __profcxx_list_rewind(__x...)
+#define __profcxx_list_operation(__x...)
+#define __profcxx_list_destruct(__x...)
+#define __profcxx_list_construct(__x...)
+#endif
+
+// Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
+#if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP)
+#define __profcxx_map_to_unordered_map_construct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_construct(__x))
+#define __profcxx_map_to_unordered_map_destruct(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_destruct(__x))
+#define __profcxx_map_to_unordered_map_insert(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_insert(__x))
+#define __profcxx_map_to_unordered_map_erase(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_erase(__x))
+#define __profcxx_map_to_unordered_map_iterate(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_iterate(__x))
+#define __profcxx_map_to_unordered_map_invalidate(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_invalidate(__x))
+#define __profcxx_map_to_unordered_map_find(__x...) \
+ _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
+ __gnu_profile::__trace_map_to_unordered_map_find(__x))
+#else
+#define __profcxx_map_to_unordered_map_construct(__x...) \
+
+#define __profcxx_map_to_unordered_map_destruct(__x...)
+#define __profcxx_map_to_unordered_map_insert(__x...)
+#define __profcxx_map_to_unordered_map_erase(__x...)
+#define __profcxx_map_to_unordered_map_iterate(__x...)
+#define __profcxx_map_to_unordered_map_invalidate(__x...)
+#define __profcxx_map_to_unordered_map_find(__x...)
+#endif
+
+// Set default values for compile-time customizable variables.
+#ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
+#define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
+#endif
+#ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
+#define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT"
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
+#define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
+ "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
+#define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
+#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
+#endif
+#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
+#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
+ "_GLIBCXX_PROFILE_MAX_STACK_DEPTH"
+#endif
+#ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
+#define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC (1 << 28)
+#endif
+#ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
+#define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
+ "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
+#endif
+
+// Instrumentation hook implementations.
+#include "profile/impl/profiler_hash_func.h"
+#include "profile/impl/profiler_hashtable_size.h"
+#include "profile/impl/profiler_map_to_unordered_map.h"
+#include "profile/impl/profiler_vector_size.h"
+#include "profile/impl/profiler_vector_to_list.h"
+#include "profile/impl/profiler_list_to_slist.h"
+#include "profile/impl/profiler_list_to_vector.h"
+
+#endif // _GLIBCXX_PROFILE_PROFILER_H
diff --git a/libstdc++-v3/include/profile/impl/profiler_algos.h b/libstdc++-v3/include/profile/impl/profiler_algos.h
new file mode 100644
index 000000000..977afaa80
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_algos.h
@@ -0,0 +1,111 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_algos.h
+ * @brief Algorithms used by the profile extension.
+ *
+ * This file is needed to avoid including <algorithm> or <bits/stl_algo.h>.
+ * Including those files would result in recursive includes.
+ * These implementations are oversimplified. In general, efficiency may be
+ * sacrificed to minimize maintenance overhead.
+ */
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_ALGOS_H
+#define _GLIBCXX_PROFILE_PROFILER_ALGOS_H 1
+
+namespace __gnu_profile
+{
+ /* Helper for __top_n. Insert in sorted vector, but not beyond Nth elem. */
+ template<typename _Container>
+ void
+ __insert_top_n(_Container& __output,
+ const typename _Container::value_type& __value,
+ typename _Container::size_type __n)
+ {
+ typename _Container::iterator __it = __output.begin();
+ typename _Container::size_type __count = 0;
+
+ // Skip up to N - 1 elements larger than VALUE.
+ // XXX: Could do binary search for random iterators.
+ while (true)
+ {
+ if (__count >= __n)
+ // VALUE is not in top N.
+ return;
+
+ if (__it == __output.end())
+ break;
+
+ if (*__it < __value)
+ break;
+
+ ++__it;
+ ++__count;
+ }
+
+ __output.insert(__it, __value);
+ }
+
+ /* Copy the top N elements in INPUT, sorted in reverse order, to OUTPUT. */
+ template<typename _Container>
+ void
+ __top_n(const _Container& __input, _Container& __output,
+ typename _Container::size_type __n)
+ {
+ __output.clear();
+ typename _Container::const_iterator __it;
+ for (__it = __input.begin(); __it != __input.end(); ++__it)
+ __insert_top_n(__output, *__it, __n);
+ }
+
+ /* Simplified clone of std::for_each. */
+ template<typename _InputIterator, typename _Function>
+ _Function
+ __for_each(_InputIterator __first, _InputIterator __last, _Function __f)
+ {
+ for (; __first != __last; ++__first)
+ __f(*__first);
+ return __f;
+ }
+
+ /* Simplified clone of std::remove. */
+ template<typename _ForwardIterator, typename _Tp>
+ _ForwardIterator
+ __remove(_ForwardIterator __first, _ForwardIterator __last,
+ const _Tp& __value)
+ {
+ if(__first == __last)
+ return __first;
+ _ForwardIterator __result = __first;
+ ++__first;
+ for(; __first != __last; ++__first)
+ if(!(*__first == __value))
+ {
+ *__result = *__first;
+ ++__result;
+ }
+ return __result;
+ }
+} // namespace __gnu_profile
+
+#endif /* _GLIBCXX_PROFILE_PROFILER_ALGOS_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_container_size.h b/libstdc++-v3/include/profile/impl/profiler_container_size.h
new file mode 100644
index 000000000..26b2c72c2
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_container_size.h
@@ -0,0 +1,215 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_container_size.h
+ * @brief Diagnostics for container sizes.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H
+#define _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H 1
+
+#include <sstream>
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ /** @brief A container size instrumentation line in the object table. */
+ class __container_size_info
+ : public __object_info_base
+ {
+ public:
+ __container_size_info()
+ : _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0),
+ _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
+ { }
+
+ __container_size_info(const __container_size_info& __o)
+ : __object_info_base(__o), _M_init(__o._M_init), _M_max(__o._M_max),
+ _M_min(__o._M_min), _M_total(__o._M_total),
+ _M_item_min(__o._M_item_min), _M_item_max(__o._M_item_max),
+ _M_item_total(__o._M_item_total), _M_count(__o._M_count),
+ _M_resize(__o._M_resize), _M_cost(__o._M_cost)
+ { }
+
+ __container_size_info(__stack_t __stack, std::size_t __num)
+ : __object_info_base(__stack), _M_init(__num), _M_max(__num),
+ _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0),
+ _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0)
+ { }
+
+ virtual ~__container_size_info() { }
+
+ void
+ __write(FILE* __f) const
+ {
+ std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n",
+ _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max,
+ _M_total, _M_item_min, _M_item_max, _M_item_total);
+ }
+
+ float
+ __magnitude() const
+ { return static_cast<float>(_M_cost); }
+
+ std::string
+ __advice() const
+ {
+ std::stringstream __message;
+ if (_M_init < _M_item_max)
+ __message << "change initial container size from " << _M_init
+ << " to " << _M_item_max;
+ return __message.str();
+ }
+
+ void
+ __merge(const __container_size_info& __o)
+ {
+ _M_init = std::max(_M_init, __o._M_init);
+ _M_max = std::max(_M_max, __o._M_max);
+ _M_item_max = std::max(_M_item_max, __o._M_item_max);
+ _M_min = std::min(_M_min, __o._M_min);
+ _M_item_min = std::min(_M_item_min, __o._M_item_min);
+ _M_total += __o._M_total;
+ _M_item_total += __o._M_item_total;
+ _M_count += __o._M_count;
+ _M_cost += __o._M_cost;
+ _M_resize += __o._M_resize;
+ }
+
+ // Call if a container is destructed or cleaned.
+ void
+ __destruct(std::size_t __num, std::size_t __inum)
+ {
+ _M_max = std::max(_M_max, __num);
+ _M_item_max = std::max(_M_item_max, __inum);
+ if (_M_min == 0)
+ {
+ _M_min = __num;
+ _M_item_min = __inum;
+ }
+ else
+ {
+ _M_min = std::min(_M_min, __num);
+ _M_item_min = std::min(_M_item_min, __inum);
+ }
+ _M_total += __num;
+ _M_item_total += __inum;
+ _M_count += 1;
+ }
+
+ // Estimate the cost of resize/rehash.
+ float
+ __resize_cost(std::size_t __from, std::size_t)
+ { return __from; }
+
+ // Call if container is resized.
+ void
+ __resize(std::size_t __from, std::size_t __to)
+ {
+ _M_cost += this->__resize_cost(__from, __to);
+ _M_resize += 1;
+ _M_max = std::max(_M_max, __to);
+ }
+
+ private:
+ std::size_t _M_init;
+ std::size_t _M_max; // range of # buckets
+ std::size_t _M_min;
+ std::size_t _M_total;
+ std::size_t _M_item_min; // range of # items
+ std::size_t _M_item_max;
+ std::size_t _M_item_total;
+ std::size_t _M_count;
+ std::size_t _M_resize;
+ std::size_t _M_cost;
+ };
+
+
+ /** @brief A container size instrumentation line in the stack table. */
+ class __container_size_stack_info
+ : public __container_size_info
+ {
+ public:
+ __container_size_stack_info(const __container_size_info& __o)
+ : __container_size_info(__o) { }
+ };
+
+
+ /** @brief Container size instrumentation trace producer. */
+ class __trace_container_size
+ : public __trace_base<__container_size_info, __container_size_stack_info>
+ {
+ public:
+ ~__trace_container_size() { }
+
+ __trace_container_size()
+ : __trace_base<__container_size_info, __container_size_stack_info>() { };
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void
+ __insert(const __object_t __obj, __stack_t __stack, std::size_t __num)
+ { __add_object(__obj, __container_size_info(__stack, __num)); }
+
+ // XXX Undefined?
+ void
+ __construct(const void* __obj, std::size_t __inum);
+
+ // Call at destruction/clean to set container final size.
+ void
+ __destruct(const void* __obj, std::size_t __num, std::size_t __inum)
+ {
+ if (!__is_on())
+ return;
+
+ __object_t __obj_handle = static_cast<__object_t>(__obj);
+
+ __container_size_info* __object_info = __get_object_info(__obj_handle);
+ if (!__object_info)
+ return;
+
+ __object_info->__destruct(__num, __inum);
+ __retire_object(__obj_handle);
+ }
+
+ // Call at resize to set resize/cost information.
+ void
+ __resize(const void* __obj, int __from, int __to)
+ {
+ if (!__is_on())
+ return;
+
+ __container_size_info* __object_info = __get_object_info(__obj);
+ if (!__object_info)
+ return;
+
+ __object_info->__resize(__from, __to);
+ }
+ };
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_hash_func.h b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
new file mode 100644
index 000000000..7ff11cd03
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
@@ -0,0 +1,174 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_hash_func.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H
+#define _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ /** @brief A hash performance instrumentation line in the object table. */
+ class __hashfunc_info
+ : public __object_info_base
+ {
+ public:
+ __hashfunc_info()
+ : _M_longest_chain(0), _M_accesses(0), _M_hops(0) { }
+
+ __hashfunc_info(const __hashfunc_info& __o)
+ : __object_info_base(__o), _M_longest_chain(__o._M_longest_chain),
+ _M_accesses(__o._M_accesses), _M_hops(__o._M_hops) { }
+
+ __hashfunc_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_longest_chain(0),
+ _M_accesses(0), _M_hops(0) { }
+
+ virtual ~__hashfunc_info() { }
+
+ void
+ __merge(const __hashfunc_info& __o)
+ {
+ _M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain);
+ _M_accesses += __o._M_accesses;
+ _M_hops += __o._M_hops;
+ }
+
+ void
+ __destruct(std::size_t __chain, std::size_t __accesses,
+ std::size_t __hops)
+ {
+ _M_longest_chain = std::max(_M_longest_chain, __chain);
+ _M_accesses += __accesses;
+ _M_hops += __hops;
+ }
+
+ void
+ __write(FILE* __f) const
+ { std::fprintf(__f, "%Zu %Zu %Zu\n", _M_hops,
+ _M_accesses, _M_longest_chain); }
+
+ float
+ __magnitude() const
+ { return static_cast<float>(_M_hops); }
+
+ std::string
+ __advice() const
+ { return "change hash function"; }
+
+ private:
+ std::size_t _M_longest_chain;
+ std::size_t _M_accesses;
+ std::size_t _M_hops;
+ };
+
+
+ /** @brief A hash performance instrumentation line in the stack table. */
+ class __hashfunc_stack_info
+ : public __hashfunc_info
+ {
+ public:
+ __hashfunc_stack_info(const __hashfunc_info& __o)
+ : __hashfunc_info(__o) { }
+ };
+
+
+ /** @brief Hash performance instrumentation producer. */
+ class __trace_hash_func
+ : public __trace_base<__hashfunc_info, __hashfunc_stack_info>
+ {
+ public:
+ __trace_hash_func()
+ : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
+ { __id = "hash-distr"; }
+
+ ~__trace_hash_func() {}
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void
+ __insert(__object_t __obj, __stack_t __stack)
+ { __add_object(__obj, __hashfunc_info(__stack)); }
+
+ // Call at destruction/clean to set container final size.
+ void
+ __destruct(const void* __obj, std::size_t __chain,
+ std::size_t __accesses, std::size_t __hops)
+ {
+ if (!__is_on())
+ return;
+
+ // First find the item from the live objects and update the informations.
+ __hashfunc_info* __objs = __get_object_info(__obj);
+ if (!__objs)
+ return;
+
+ __objs->__destruct(__chain, __accesses, __hops);
+ __retire_object(__obj);
+ }
+ };
+
+
+ inline void
+ __trace_hash_func_init()
+ { _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); }
+
+ inline void
+ __trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_hash_func))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_hash_func)->__collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_hash_func)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_hash_func_construct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_hash_func)->__insert(__obj, __get_stack());
+ }
+
+ inline void
+ __trace_hash_func_destruct(const void* __obj, std::size_t __chain,
+ std::size_t __accesses, std::size_t __hops)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj, __chain,
+ __accesses, __hops);
+ }
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
new file mode 100644
index 000000000..8557a6073
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_hashtable_size.h
+ * @brief Collection of hashtable size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H
+#define _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_container_size.h"
+
+namespace __gnu_profile
+{
+ /** @brief Hashtable size instrumentation trace producer. */
+ class __trace_hashtable_size
+ : public __trace_container_size
+ {
+ public:
+ __trace_hashtable_size()
+ : __trace_container_size()
+ { __id = "hashtable-size"; }
+ };
+
+ inline void
+ __trace_hashtable_size_init()
+ { _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); }
+
+ inline void
+ __trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_hashtable_size))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->
+ __collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_hashtable_size_construct(const void* __obj, std::size_t __num)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__insert(__obj, __get_stack(),
+ __num);
+ }
+
+ inline void
+ __trace_hashtable_size_destruct(const void* __obj, std::size_t __num,
+ std::size_t __inum)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__destruct(__obj, __num, __inum);
+ }
+
+ inline void
+ __trace_hashtable_size_resize(const void* __obj, std::size_t __from,
+ std::size_t __to)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
+ }
+
+} // namespace __gnu_profile
+
+#endif /* _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h
new file mode 100644
index 000000000..2195ccf90
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h
@@ -0,0 +1,208 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_list_to_slist.h
+ * @brief Diagnostics for list to slist.
+ */
+
+// Written by Changhee Jung.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H
+#define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ class __list2slist_info
+ : public __object_info_base
+ {
+ public:
+ __list2slist_info()
+ : _M_rewind(false), _M_operations(0) { }
+
+ __list2slist_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { }
+
+ virtual ~__list2slist_info() { }
+
+ __list2slist_info(const __list2slist_info& __o)
+ : __object_info_base(__o), _M_rewind(__o._M_rewind),
+ _M_operations(__o._M_operations) { }
+
+ // XXX: the magnitude should be multiplied with a constant factor F,
+ // where F is 1 when the malloc size class of list nodes is different
+ // from the malloc size class of slist nodes. When they fall into the same
+ // class, the only slist benefit is from having to set fewer links, so
+ // the factor F should be much smaller, closer to 0 than to 1.
+ // This could be implemented by passing the size classes in the config
+ // file. For now, we always assume F to be 1.
+
+ float
+ __magnitude() const
+ {
+ if (!_M_rewind)
+ return _M_operations;
+ else
+ return 0;
+ }
+
+ void
+ __merge(const __list2slist_info&) { }
+
+ void
+ __write(FILE* __f) const
+ { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); }
+
+ std::string
+ __advice() const
+ { return "change std::list to std::forward_list"; }
+
+ void
+ __opr_rewind()
+ {
+ _M_rewind = true;
+ _M_valid = false;
+ }
+
+ void
+ __record_operation()
+ { ++_M_operations; }
+
+ bool
+ __has_rewind()
+ { return _M_rewind; }
+
+ private:
+ bool _M_rewind;
+ std::size_t _M_operations;
+ };
+
+ class __list2slist_stack_info
+ : public __list2slist_info
+ {
+ public:
+ __list2slist_stack_info(const __list2slist_info& __o)
+ : __list2slist_info(__o) { }
+ };
+
+ class __trace_list_to_slist
+ : public __trace_base<__list2slist_info, __list2slist_stack_info>
+ {
+ public:
+ ~__trace_list_to_slist() { }
+
+ __trace_list_to_slist()
+ : __trace_base<__list2slist_info, __list2slist_stack_info>()
+ { __id = "list-to-slist"; }
+
+ void
+ __opr_rewind(const void* __obj)
+ {
+ __list2slist_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_rewind();
+ }
+
+ void
+ __record_operation(const void* __obj)
+ {
+ __list2slist_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__record_operation();
+ }
+
+ void
+ __insert(const __object_t __obj, __stack_t __stack)
+ { __add_object(__obj, __list2slist_info(__stack)); }
+
+ void
+ __destruct(const void* __obj)
+ {
+ if (!__is_on())
+ return;
+
+ __list2slist_info* __res = __get_object_info(__obj);
+ if (!__res)
+ return;
+
+ __retire_object(__obj);
+ }
+ };
+
+
+ inline void
+ __trace_list_to_slist_init()
+ { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); }
+
+ inline void
+ __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_list_to_slist))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->
+ __collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_list_to_slist_rewind(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__opr_rewind(__obj);
+ }
+
+ inline void
+ __trace_list_to_slist_operation(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__record_operation(__obj);
+ }
+
+ inline void
+ __trace_list_to_slist_construct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__insert(__obj, __get_stack());
+ }
+
+ inline void
+ __trace_list_to_slist_destruct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj);
+ }
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h b/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h
new file mode 100644
index 000000000..b3840a747
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h
@@ -0,0 +1,324 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_list_to_vector.h
+ * @brief diagnostics for list to vector.
+ */
+
+// Written by Changhee Jung.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H
+#define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1
+
+#include <sstream>
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ /** @brief A list-to-vector instrumentation line in the object table. */
+ class __list2vector_info
+ : public __object_info_base
+ {
+ public:
+ __list2vector_info()
+ : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
+ _M_vector_cost(0), _M_valid(true), _M_max_size(0) { }
+
+ __list2vector_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
+ _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true),
+ _M_max_size(0) { }
+
+ virtual ~__list2vector_info() { }
+
+ __list2vector_info(const __list2vector_info& __o)
+ : __object_info_base(__o), _M_shift_count(__o._M_shift_count),
+ _M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
+ _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
+ _M_valid(__o._M_valid), _M_max_size(__o._M_max_size) { }
+
+ void
+ __merge(const __list2vector_info& __o)
+ {
+ _M_shift_count += __o._M_shift_count;
+ _M_iterate += __o._M_iterate;
+ _M_vector_cost += __o._M_vector_cost;
+ _M_list_cost += __o._M_list_cost;
+ _M_valid &= __o._M_valid;
+ _M_resize += __o._M_resize;
+ _M_max_size = std::max( _M_max_size, __o._M_max_size);
+ }
+
+ void
+ __write(FILE* __f) const
+ {
+ std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count,
+ _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+ }
+
+ float
+ __magnitude() const
+ { return _M_list_cost - _M_vector_cost; }
+
+ std::string
+ __advice() const
+ {
+ std::stringstream __sstream;
+ __sstream
+ << "change std::list to std::vector and its initial size from 0 to "
+ << _M_max_size;
+ return __sstream.str();
+ }
+
+ std::size_t
+ __shift_count()
+ { return _M_shift_count; }
+
+ std::size_t
+ __iterate()
+ { return _M_iterate; }
+
+ float
+ __list_cost()
+ { return _M_list_cost; }
+
+ std::size_t
+ __resize()
+ { return _M_resize; }
+
+ void
+ __set_list_cost(float __lc)
+ { _M_list_cost = __lc; }
+
+ void
+ __set_vector_cost(float __vc)
+ { _M_vector_cost = __vc; }
+
+ bool
+ __is_valid()
+ { return _M_valid; }
+
+ void
+ __set_invalid()
+ { _M_valid = false; }
+
+ void
+ __opr_insert(std::size_t __shift, std::size_t __size)
+ {
+ _M_shift_count += __shift;
+ _M_max_size = std::max(_M_max_size, __size);
+ }
+
+ void
+ __opr_iterate(std::size_t __num)
+ { _M_iterate += __num;}
+
+ void
+ __resize(std::size_t __from, std::size_t)
+ { _M_resize += __from; }
+
+ private:
+ std::size_t _M_shift_count;
+ std::size_t _M_iterate;
+ std::size_t _M_resize;
+ float _M_list_cost;
+ float _M_vector_cost;
+ bool _M_valid;
+ std::size_t _M_max_size;
+ };
+
+ class __list2vector_stack_info
+ : public __list2vector_info
+ {
+ public:
+ __list2vector_stack_info(const __list2vector_info& __o)
+ : __list2vector_info(__o) {}
+ };
+
+ class __trace_list_to_vector
+ : public __trace_base<__list2vector_info, __list2vector_stack_info>
+ {
+ public:
+ __trace_list_to_vector()
+ : __trace_base<__list2vector_info, __list2vector_stack_info>()
+ { __id = "list-to-vector"; }
+
+ ~__trace_list_to_vector() { }
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void
+ __insert(__object_t __obj, __stack_t __stack)
+ { __add_object(__obj, __list2vector_info(__stack)); }
+
+ // Call at destruction/clean to set container final size.
+ void
+ __destruct(const void* __obj)
+ {
+ if (!__is_on())
+ return;
+
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (!__res)
+ return;
+
+ float __vc = __vector_cost(__res->__shift_count(), __res->__iterate());
+ float __lc = __list_cost(__res->__shift_count(), __res->__iterate());
+ __res->__set_vector_cost(__vc);
+ __res->__set_list_cost(__lc);
+ __retire_object(__obj);
+ }
+
+ // Find the node in the live map.
+ __list2vector_info* __find(const void* __obj);
+
+ // Collect cost of operations.
+ void
+ __opr_insert(const void* __obj, std::size_t __shift, std::size_t __size)
+ {
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_insert(__shift, __size);
+ }
+
+ void
+ __opr_iterate(const void* __obj, std::size_t __num)
+ {
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_iterate(__num);
+ }
+
+ void
+ __invalid_operator(const void* __obj)
+ {
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+ }
+
+ void
+ __resize(const void* __obj, std::size_t __from, std::size_t __to)
+ {
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+ }
+
+ float
+ __vector_cost(std::size_t __shift, std::size_t __iterate)
+ {
+ // The resulting vector will use a 'reserve' method.
+ return (__shift
+ * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
+ + __iterate
+ * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value);
+ }
+
+ float
+ __list_cost(std::size_t __shift, std::size_t __iterate)
+ {
+ return (__shift
+ * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
+ + __iterate
+ * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value);
+ }
+ };
+
+
+ inline void
+ __trace_list_to_vector_init()
+ { _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); }
+
+ inline void
+ __trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_list_to_vector))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->
+ __collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_list_to_vector_construct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__insert(__obj, __get_stack());
+ }
+
+ inline void
+ __trace_list_to_vector_destruct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj);
+ }
+
+ inline void
+ __trace_list_to_vector_insert(const void* __obj,
+ std::size_t __shift, std::size_t __size)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_insert(__obj, __shift,
+ __size);
+ }
+
+ inline void
+ __trace_list_to_vector_iterate(const void* __obj, std::size_t __num = 1)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__opr_iterate(__obj, __num);
+ }
+
+ inline void
+ __trace_list_to_vector_invalid_operator(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__invalid_operator(__obj);
+ }
+
+ inline void
+ __trace_list_to_vector_resize(const void* __obj,
+ std::size_t __from, std::size_t __to)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__resize(__obj, __from, __to);
+ }
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */
diff --git a/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
new file mode 100644
index 000000000..e232effe8
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
@@ -0,0 +1,290 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_map_to_unordered_map.h
+ * @brief Diagnostics for map to unordered_map.
+ */
+
+// Written by Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
+#define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ inline int
+ __log2(std::size_t __size)
+ {
+ for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
+ -- __bit_count)
+ if ((2 << __bit_count) & __size)
+ return __bit_count;
+ return 0;
+ }
+
+ inline float
+ __map_insert_cost(std::size_t __size)
+ { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
+ * static_cast<float>(__log2(__size))); }
+
+ inline float
+ __map_erase_cost(std::size_t __size)
+ { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
+ * static_cast<float>(__log2(__size))); }
+
+ inline float
+ __map_find_cost(std::size_t __size)
+ { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
+ * static_cast<float>(__log2(__size))); }
+
+ /** @brief A map-to-unordered_map instrumentation line in the
+ object table. */
+ class __map2umap_info
+ : public __object_info_base
+ {
+ public:
+ __map2umap_info()
+ : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
+ _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
+
+ __map2umap_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
+ _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0), _M_valid(true) { }
+
+ virtual ~__map2umap_info() { }
+
+ __map2umap_info(const __map2umap_info& __o)
+ : __object_info_base(__o), _M_insert(__o._M_insert),
+ _M_erase(__o._M_erase), _M_find(__o._M_find),
+ _M_iterate(__o._M_iterate), _M_umap_cost(__o._M_umap_cost),
+ _M_map_cost(__o._M_map_cost), _M_valid(__o._M_valid) { }
+
+ void
+ __merge(const __map2umap_info& __o)
+ {
+ _M_insert += __o._M_insert;
+ _M_erase += __o._M_erase;
+ _M_find += __o._M_find;
+ _M_umap_cost += __o._M_umap_cost;
+ _M_map_cost += __o._M_map_cost;
+ _M_valid &= __o._M_valid;
+ }
+
+ void
+ __write(FILE* __f) const
+ {
+ std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
+ _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
+ _M_umap_cost, _M_valid ? "valid" : "invalid");
+ }
+
+ float
+ __magnitude() const
+ { return _M_map_cost - _M_umap_cost; }
+
+ std::string
+ __advice() const
+ { return "change std::map to std::unordered_map"; }
+
+ void
+ __record_insert(std::size_t __size, std::size_t __count)
+ {
+ _M_insert += __count;
+ _M_map_cost += __count * __map_insert_cost(__size);
+ _M_umap_cost
+ += (__count
+ * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
+ }
+
+ void
+ __record_erase(std::size_t __size, std::size_t __count)
+ {
+ _M_erase += __count;
+ _M_map_cost += __count * __map_erase_cost(__size);
+ _M_umap_cost
+ += (__count
+ * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
+ }
+
+ void
+ __record_find(std::size_t __size)
+ {
+ _M_find += 1;
+ _M_map_cost += __map_find_cost(__size);
+ _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
+ }
+
+ void
+ __record_iterate(std::size_t __count)
+ {
+ _M_iterate += __count;
+ _M_map_cost
+ += (__count
+ * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
+ _M_umap_cost
+ += (__count
+ * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
+ }
+
+ void
+ __record_invalidate()
+ { _M_valid = false; }
+
+ private:
+ std::size_t _M_insert;
+ std::size_t _M_erase;
+ std::size_t _M_find;
+ std::size_t _M_iterate;
+ float _M_umap_cost;
+ float _M_map_cost;
+ bool _M_valid;
+ };
+
+
+ /** @brief A map-to-unordered_map instrumentation line in the
+ stack table. */
+ class __map2umap_stack_info
+ : public __map2umap_info
+ {
+ public:
+ __map2umap_stack_info(const __map2umap_info& __o)
+ : __map2umap_info(__o) { }
+ };
+
+ /** @brief Map-to-unordered_map instrumentation producer. */
+ class __trace_map2umap
+ : public __trace_base<__map2umap_info, __map2umap_stack_info>
+ {
+ public:
+ __trace_map2umap()
+ : __trace_base<__map2umap_info, __map2umap_stack_info>()
+ { __id = "map-to-unordered-map"; }
+ };
+
+ inline void
+ __trace_map_to_unordered_map_init()
+ { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
+
+ inline void
+ __trace_map_to_unordered_map_report(FILE* __f,
+ __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_map2umap))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_map_to_unordered_map_construct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->
+ __add_object(__obj, __map2umap_info(__get_stack()));
+ }
+
+ inline void
+ __trace_map_to_unordered_map_destruct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__retire_object(__obj);
+ }
+
+ inline void
+ __trace_map_to_unordered_map_insert(const void* __obj,
+ std::size_t __size, std::size_t __count)
+ {
+ if (!__profcxx_init())
+ return;
+
+ __map2umap_info* __info
+ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
+
+ if (__info)
+ __info->__record_insert(__size, __count);
+ }
+
+ inline void
+ __trace_map_to_unordered_map_erase(const void* __obj,
+ std::size_t __size, std::size_t __count)
+ {
+ if (!__profcxx_init())
+ return;
+
+ __map2umap_info* __info
+ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
+
+ if (__info)
+ __info->__record_erase(__size, __count);
+ }
+
+ inline void
+ __trace_map_to_unordered_map_find(const void* __obj, std::size_t __size)
+ {
+ if (!__profcxx_init())
+ return;
+
+ __map2umap_info* __info
+ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
+
+ if (__info)
+ __info->__record_find(__size);
+ }
+
+ inline void
+ __trace_map_to_unordered_map_iterate(const void* __obj, std::size_t __count)
+ {
+ if (!__profcxx_init())
+ return;
+
+ __map2umap_info* __info
+ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
+
+ if (__info)
+ __info->__record_iterate(__count);
+ }
+
+ inline void
+ __trace_map_to_unordered_map_invalidate(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ __map2umap_info* __info
+ = _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
+
+ if (__info)
+ __info->__record_invalidate();
+ }
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_node.h b/libstdc++-v3/include/profile/impl/profiler_node.h
new file mode 100644
index 000000000..acc0cb5bf
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_node.h
@@ -0,0 +1,166 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_node.h
+ * @brief Data structures to represent a single profiling event.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H
+#define _GLIBCXX_PROFILE_PROFILER_NODE_H 1
+
+#include <cstdio> // FILE, fprintf
+
+#include <vector>
+#if defined _GLIBCXX_HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+namespace __gnu_profile
+{
+ typedef const void* __object_t;
+ typedef void* __instruction_address_t;
+ typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt;
+ typedef __stack_npt* __stack_t;
+
+ std::size_t __stack_max_depth();
+
+ inline __stack_t
+ __get_stack()
+ {
+#if defined _GLIBCXX_HAVE_EXECINFO_H
+ std::size_t __max_depth = __stack_max_depth();
+ if (__max_depth == 0)
+ return 0;
+ __stack_npt __buffer(__max_depth);
+ int __depth = backtrace(&__buffer[0], __max_depth);
+ __stack_t __stack = new __stack_npt(__depth);
+ __builtin_memcpy(&(*__stack)[0], &__buffer[0],
+ __depth * sizeof(__object_t));
+ return __stack;
+#else
+ return 0;
+#endif
+ }
+
+ inline std::size_t
+ __size(__stack_t __stack)
+ {
+ if (!__stack)
+ return 0;
+ else
+ return __stack->size();
+ }
+
+ // XXX
+ inline void
+ __write(FILE* __f, __stack_t __stack)
+ {
+ if (!__stack)
+ return;
+
+ __stack_npt::const_iterator __it;
+ for (__it = __stack->begin(); __it != __stack->end(); ++__it)
+ std::fprintf(__f, "%p ", *__it);
+ }
+
+ /** @brief Hash function for summary trace using call stack as index. */
+ class __stack_hash
+ {
+ public:
+ std::size_t
+ operator()(__stack_t __s) const
+ {
+ if (!__s)
+ return 0;
+
+ __UINTPTR_TYPE__ __index = 0;
+ __stack_npt::const_iterator __it;
+ for (__it = __s->begin(); __it != __s->end(); ++__it)
+ __index += reinterpret_cast<__UINTPTR_TYPE__>(*__it);
+ return __index;
+ }
+
+ bool operator() (__stack_t __stack1, __stack_t __stack2) const
+ {
+ if (!__stack1 && !__stack2)
+ return true;
+ if (!__stack1 || !__stack2)
+ return false;
+ if (__stack1->size() != __stack2->size())
+ return false;
+
+ std::size_t __byte_size
+ = __stack1->size() * sizeof(__stack_npt::value_type);
+ return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0],
+ __byte_size) == 0;
+ }
+ };
+
+
+ /** @brief Base class for a line in the object table. */
+ class __object_info_base
+ {
+ public:
+ __object_info_base() { }
+
+ __object_info_base(__stack_t __stack)
+ : _M_stack(__stack), _M_valid(true) { }
+
+ __object_info_base(const __object_info_base& __o)
+ : _M_stack(__o._M_stack), _M_valid(__o._M_valid) { }
+
+ virtual ~__object_info_base() { }
+
+ bool
+ __is_valid() const
+ { return _M_valid; }
+
+ __stack_t
+ __stack() const
+ { return _M_stack; }
+
+ virtual void __write(FILE* __f) const = 0;
+
+ protected:
+ __stack_t _M_stack;
+ bool _M_valid;
+ };
+
+
+ /** @brief Base class for a line in the stack table. */
+ template<typename __object_info>
+ class __stack_info_base
+ {
+ public:
+ __stack_info_base() { }
+ __stack_info_base(const __object_info& __info) = 0;
+ virtual ~__stack_info_base() {}
+ void __merge(const __object_info& __info) = 0;
+ virtual float __magnitude() const = 0;
+ virtual const char* __get_id() const = 0;
+ };
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_state.h b/libstdc++-v3/include/profile/impl/profiler_state.h
new file mode 100644
index 000000000..1f39df548
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_state.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_state.h
+ * @brief Global profiler state.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H
+#define _GLIBCXX_PROFILE_PROFILER_STATE_H 1
+
+namespace __gnu_profile
+{
+ enum __state_type { __ON, __OFF, __INVALID };
+
+ _GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID);
+
+ inline bool
+ __turn(__state_type __s)
+ { return (_GLIBCXX_PROFILE_DATA(__state)
+ == __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state),
+ __INVALID, __s)); }
+
+ inline bool
+ __turn_on()
+ { return __turn(__ON); }
+
+ inline bool
+ __turn_off()
+ { return __turn(__OFF); }
+
+ inline bool
+ __is_on()
+ { return _GLIBCXX_PROFILE_DATA(__state) == __ON; }
+
+ inline bool
+ __is_off()
+ { return _GLIBCXX_PROFILE_DATA(__state) == __OFF; }
+
+ inline bool
+ __is_invalid()
+ { return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; }
+
+} // end namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_trace.h b/libstdc++-v3/include/profile/impl/profiler_trace.h
new file mode 100644
index 000000000..dadc5cac5
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_trace.h
@@ -0,0 +1,659 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H
+#define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1
+
+#include <cstdio> // fopen, fclose, fprintf, FILE
+#include <cerrno>
+#include <cstdlib> // atof, atoi, strtol, getenv, atexit, abort
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_C::unordered_map
+#include <unordered_map>
+#else
+#include <tr1/unordered_map>
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
+#endif
+
+#include <ext/concurrence.h>
+#include <fstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "profile/impl/profiler_algos.h"
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_node.h"
+
+namespace __gnu_profile
+{
+ /** @brief Internal environment. Values can be set one of two ways:
+ 1. In config file "var = value". The default config file path is
+ libstdcxx-profile.conf.
+ 2. By setting process environment variables. For instance, in a Bash
+ shell you can set the unit cost of iterating through a map like this:
+ export __map_iterate_cost_factor=5.0.
+ If a value is set both in the input file and through an environment
+ variable, the environment value takes precedence. */
+ typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t;
+
+ _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);
+
+ /** @brief Master lock. */
+ _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock);
+
+ /** @brief Representation of a warning. */
+ struct __warning_data
+ {
+ float __magnitude;
+ __stack_t __context;
+ const char* __warning_id;
+ std::string __warning_message;
+
+ __warning_data()
+ : __magnitude(0.0), __context(0), __warning_id(0) { }
+
+ __warning_data(float __m, __stack_t __c, const char* __id,
+ const std::string& __msg)
+ : __magnitude(__m), __context(__c), __warning_id(__id),
+ __warning_message(__msg) { }
+
+ bool
+ operator<(const __warning_data& __other) const
+ { return __magnitude < __other.__magnitude; }
+ };
+
+ typedef std::_GLIBCXX_STD_C::vector<__warning_data> __warning_vector_t;
+
+ // Defined in profiler_<diagnostic name>.h.
+ class __trace_hash_func;
+ class __trace_hashtable_size;
+ class __trace_map2umap;
+ class __trace_vector_size;
+ class __trace_vector_to_list;
+ class __trace_list_to_slist;
+ class __trace_list_to_vector;
+ void __trace_vector_size_init();
+ void __trace_hashtable_size_init();
+ void __trace_hash_func_init();
+ void __trace_vector_to_list_init();
+ void __trace_list_to_slist_init();
+ void __trace_list_to_vector_init();
+ void __trace_map_to_unordered_map_init();
+ void __trace_vector_size_report(FILE*, __warning_vector_t&);
+ void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
+ void __trace_hash_func_report(FILE*, __warning_vector_t&);
+ void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
+ void __trace_list_to_slist_report(FILE*, __warning_vector_t&);
+ void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
+ void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
+
+ struct __cost_factor
+ {
+ const char* __env_var;
+ float __value;
+ };
+
+ typedef std::_GLIBCXX_STD_C::vector<__cost_factor*> __cost_factor_vector;
+
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0);
+ _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0);
+
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor,
+ {"__vector_shift_cost_factor", 1.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
+ {"__vector_iterate_cost_factor", 1.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
+ {"__vector_resize_cost_factor", 1.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
+ {"__list_shift_cost_factor", 0.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
+ {"__list_iterate_cost_factor", 10.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
+ {"__list_resize_cost_factor", 0.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
+ {"__map_insert_cost_factor", 1.5});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
+ {"__map_erase_cost_factor", 1.5});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
+ {"__map_find_cost_factor", 1});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
+ {"__map_iterate_cost_factor", 2.3});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
+ {"__umap_insert_cost_factor", 12.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
+ {"__umap_erase_cost_factor", 12.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
+ {"__umap_find_cost_factor", 10.0});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
+ {"__umap_iterate_cost_factor", 1.7});
+ _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0);
+
+ _GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
+ _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
+ _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_warn_count,
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT);
+ _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_stack_depth,
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
+ _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_mem,
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
+
+ inline std::size_t
+ __stack_max_depth()
+ { return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth); }
+
+ inline std::size_t
+ __max_mem()
+ { return _GLIBCXX_PROFILE_DATA(_S_max_mem); }
+
+ /** @brief Base class for all trace producers. */
+ template<typename __object_info, typename __stack_info>
+ class __trace_base
+ {
+ public:
+ // Do not pick the initial size too large, as we don't know which
+ // diagnostics are more active.
+ __trace_base()
+ : __object_table(10000), __stack_table(10000),
+ __stack_table_byte_size(0), __id(0) { }
+
+ virtual ~__trace_base() { }
+
+ void __add_object(__object_t object, __object_info __info);
+ __object_info* __get_object_info(__object_t __object);
+ void __retire_object(__object_t __object);
+ void __write(FILE* __f);
+ void __collect_warnings(__warning_vector_t& __warnings);
+
+ private:
+ __gnu_cxx::__mutex __object_table_lock;
+ __gnu_cxx::__mutex __stack_table_lock;
+ typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t,
+ __object_info> __object_table_t;
+ typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info,
+ __stack_hash,
+ __stack_hash> __stack_table_t;
+ __object_table_t __object_table;
+ __stack_table_t __stack_table;
+ std::size_t __stack_table_byte_size;
+
+ protected:
+ const char* __id;
+ };
+
+ template<typename __object_info, typename __stack_info>
+ void
+ __trace_base<__object_info, __stack_info>::
+ __collect_warnings(__warning_vector_t& __warnings)
+ {
+ for (typename __stack_table_t::iterator __it
+ = __stack_table.begin(); __it != __stack_table.end(); ++__it)
+ __warnings.push_back(__warning_data((*__it).second.__magnitude(),
+ (*__it).first, __id,
+ (*__it).second.__advice()));
+ }
+
+ template<typename __object_info, typename __stack_info>
+ void
+ __trace_base<__object_info, __stack_info>::
+ __add_object(__object_t __object, __object_info __info)
+ {
+ if (__max_mem() == 0
+ || __object_table.size() * sizeof(__object_info) <= __max_mem())
+ {
+ this->__object_table_lock.lock();
+ __object_table.insert(typename __object_table_t::
+ value_type(__object, __info));
+ this->__object_table_lock.unlock();
+ }
+ }
+
+ template<typename __object_info, typename __stack_info>
+ __object_info*
+ __trace_base<__object_info, __stack_info>::
+ __get_object_info(__object_t __object)
+ {
+ // XXX: Revisit this to see if we can decrease mutex spans.
+ // Without this mutex, the object table could be rehashed during an
+ // insertion on another thread, which could result in a segfault.
+ this->__object_table_lock.lock();
+ typename __object_table_t::iterator __object_it
+ = __object_table.find(__object);
+
+ if (__object_it == __object_table.end())
+ {
+ this->__object_table_lock.unlock();
+ return 0;
+ }
+ else
+ {
+ this->__object_table_lock.unlock();
+ return &__object_it->second;
+ }
+ }
+
+ template<typename __object_info, typename __stack_info>
+ void
+ __trace_base<__object_info, __stack_info>::
+ __retire_object(__object_t __object)
+ {
+ this->__object_table_lock.lock();
+ this->__stack_table_lock.lock();
+ typename __object_table_t::iterator __object_it
+ = __object_table.find(__object);
+
+ if (__object_it != __object_table.end())
+ {
+ const __object_info& __info = __object_it->second;
+ const __stack_t& __stack = __info.__stack();
+ typename __stack_table_t::iterator __stack_it
+ = __stack_table.find(__stack);
+
+ if (__stack_it == __stack_table.end())
+ {
+ // First occurence of this call context.
+ if (__max_mem() == 0 || __stack_table_byte_size < __max_mem())
+ {
+ __stack_table_byte_size
+ += (sizeof(__instruction_address_t) * __size(__stack)
+ + sizeof(__stack) + sizeof(__stack_info));
+ __stack_table.insert(make_pair(__stack,
+ __stack_info(__info)));
+ }
+ }
+ else
+ {
+ // Merge object info into info summary for this call context.
+ __stack_it->second.__merge(__info);
+ delete __stack;
+ }
+ __object_table.erase(__object);
+ }
+
+ this->__object_table_lock.unlock();
+ this->__stack_table_lock.unlock();
+ }
+
+ template<typename __object_info, typename __stack_info>
+ void
+ __trace_base<__object_info, __stack_info>::
+ __write(FILE* __f)
+ {
+ for (typename __stack_table_t::iterator __it
+ = __stack_table.begin(); __it != __stack_table.end(); ++__it)
+ if (__it->second.__is_valid())
+ {
+ std::fprintf(__f, __id);
+ std::fprintf(__f, "|");
+ __gnu_profile::__write(__f, __it->first);
+ std::fprintf(__f, "|");
+ __it->second.__write(__f);
+ }
+ }
+
+ inline std::size_t
+ __env_to_size_t(const char* __env_var, std::size_t __default_value)
+ {
+ char* __env_value = std::getenv(__env_var);
+ if (__env_value)
+ {
+ errno = 0;
+ long __converted_value = std::strtol(__env_value, 0, 10);
+ if (errno || __converted_value < 0)
+ {
+ std::fprintf(stderr,
+ "Bad value for environment variable '%s'.\n",
+ __env_var);
+ std::abort();
+ }
+ else
+ return static_cast<std::size_t>(__converted_value);
+ }
+ else
+ return __default_value;
+ }
+
+ inline void
+ __set_max_stack_trace_depth()
+ {
+ _GLIBCXX_PROFILE_DATA(_S_max_stack_depth)
+ = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
+ _GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
+ }
+
+ inline void
+ __set_max_mem()
+ {
+ _GLIBCXX_PROFILE_DATA(_S_max_mem)
+ = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
+ _GLIBCXX_PROFILE_DATA(_S_max_mem));
+ }
+
+ inline int
+ __log_magnitude(float __f)
+ {
+ const float __log_base = 10.0;
+ int __result = 0;
+ int __sign = 1;
+
+ if (__f < 0)
+ {
+ __f = -__f;
+ __sign = -1;
+ }
+
+ while (__f > __log_base)
+ {
+ ++__result;
+ __f /= 10.0;
+ }
+ return __sign * __result;
+ }
+
+ inline FILE*
+ __open_output_file(const char* __extension)
+ {
+ // The path is made of _S_trace_file_name + "." + extension.
+ std::size_t __root_len
+ = __builtin_strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+ std::size_t __ext_len = __builtin_strlen(__extension);
+ char* __file_name = new char[__root_len + 1 + __ext_len + 1];
+ __builtin_memcpy(__file_name,
+ _GLIBCXX_PROFILE_DATA(_S_trace_file_name),
+ __root_len);
+ *(__file_name + __root_len) = '.';
+ __builtin_memcpy(__file_name + __root_len + 1,
+ __extension, __ext_len + 1);
+
+ FILE* __out_file = std::fopen(__file_name, "w");
+ if (!__out_file)
+ {
+ std::fprintf(stderr, "Could not open trace file '%s'.\n",
+ __file_name);
+ std::abort();
+ }
+
+ delete[] __file_name;
+ return __out_file;
+ }
+
+ struct __warn
+ {
+ FILE* __file;
+
+ __warn(FILE* __f)
+ { __file = __f; }
+
+ void
+ operator()(const __warning_data& __info)
+ {
+ std::fprintf(__file, __info.__warning_id);
+ std::fprintf(__file, ": improvement = %d",
+ __log_magnitude(__info.__magnitude));
+ std::fprintf(__file, ": call stack = ");
+ __gnu_profile::__write(__file, __info.__context);
+ std::fprintf(__file, ": advice = %s\n",
+ __info.__warning_message.c_str());
+ }
+ };
+
+ /** @brief Final report method, registered with @b atexit.
+ *
+ * This can also be called directly by user code, including signal handlers.
+ * It is protected against deadlocks by the reentrance guard in profiler.h.
+ * However, when called from a signal handler that triggers while within
+ * __gnu_profile (under the guarded zone), no output will be produced.
+ */
+ inline void
+ __report(void)
+ {
+ _GLIBCXX_PROFILE_DATA(__global_lock).lock();
+
+ __warning_vector_t __warnings, __top_warnings;
+
+ FILE* __raw_file = __open_output_file("raw");
+ __trace_vector_size_report(__raw_file, __warnings);
+ __trace_hashtable_size_report(__raw_file, __warnings);
+ __trace_hash_func_report(__raw_file, __warnings);
+ __trace_vector_to_list_report(__raw_file, __warnings);
+ __trace_list_to_slist_report(__raw_file, __warnings);
+ __trace_list_to_vector_report(__raw_file, __warnings);
+ __trace_map_to_unordered_map_report(__raw_file, __warnings);
+ std::fclose(__raw_file);
+
+ // Sort data by magnitude, keeping just top N.
+ std::size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
+ __warnings.size());
+ __top_n(__warnings, __top_warnings, __cutoff);
+
+ FILE* __warn_file = __open_output_file("txt");
+ __for_each(__top_warnings.begin(), __top_warnings.end(),
+ __warn(__warn_file));
+ std::fclose(__warn_file);
+
+ _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
+ }
+
+ inline void
+ __set_trace_path()
+ {
+ char* __env_trace_file_name = std::getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+
+ if (__env_trace_file_name)
+ _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
+
+ // Make sure early that we can create the trace file.
+ std::fclose(__open_output_file("txt"));
+ }
+
+ inline void
+ __set_max_warn_count()
+ {
+ char* __env_max_warn_count_str
+ = std::getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+
+ if (__env_max_warn_count_str)
+ _GLIBCXX_PROFILE_DATA(_S_max_warn_count)
+ = static_cast<std::size_t>(std::atoi(__env_max_warn_count_str));
+ }
+
+ inline void
+ __read_cost_factors()
+ {
+ std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+ __conf_file_name += ".conf";
+
+ std::ifstream __conf_file(__conf_file_name.c_str());
+
+ if (__conf_file.is_open())
+ {
+ std::string __line;
+
+ while (std::getline(__conf_file, __line))
+ {
+ std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
+
+ if (__line.length() <= 0 || __line[__i] == '#')
+ // Skip empty lines or comments.
+ continue;
+ }
+
+ // Trim.
+ __line.erase(__remove(__line.begin(), __line.end(), ' '),
+ __line.end());
+ std::string::size_type __pos = __line.find("=");
+ std::string __factor_name = __line.substr(0, __pos);
+ std::string::size_type __end = __line.find_first_of(";\n");
+ std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
+
+ _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value;
+ }
+ }
+
+ struct __cost_factor_writer
+ {
+ FILE* __file;
+
+ __cost_factor_writer(FILE* __f)
+ : __file(__f) { }
+
+ void
+ operator() (const __cost_factor* __factor)
+ { std::fprintf(__file, "%s = %f\n", __factor->__env_var,
+ __factor->__value); }
+ };
+
+ inline void
+ __write_cost_factors()
+ {
+ FILE* __file = __open_output_file("conf.out");
+ __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+ __cost_factor_writer(__file));
+ std::fclose(__file);
+ }
+
+ struct __cost_factor_setter
+ {
+ void
+ operator()(__cost_factor* __factor)
+ {
+ // Look it up in the process environment first.
+ const char* __env_value = std::getenv(__factor->__env_var);
+
+ if (!__env_value)
+ {
+ // Look it up in the config file.
+ __env_t::iterator __it
+ = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var);
+ if (__it != _GLIBCXX_PROFILE_DATA(__env).end())
+ __env_value = (*__it).second.c_str();
+ }
+
+ if (__env_value)
+ __factor->__value = std::atof(__env_value);
+ }
+ };
+
+ inline void
+ __set_cost_factors()
+ {
+ _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->
+ push_back(&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
+ __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+ __cost_factor_setter());
+ }
+
+ inline void
+ __profcxx_init_unconditional()
+ {
+ _GLIBCXX_PROFILE_DATA(__global_lock).lock();
+
+ if (__is_invalid())
+ {
+ __set_max_warn_count();
+
+ if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0)
+ __turn_off();
+ else
+ {
+ __set_max_stack_trace_depth();
+ __set_max_mem();
+ __set_trace_path();
+ __read_cost_factors();
+ __set_cost_factors();
+ __write_cost_factors();
+
+ __trace_vector_size_init();
+ __trace_hashtable_size_init();
+ __trace_hash_func_init();
+ __trace_vector_to_list_init();
+ __trace_list_to_slist_init();
+ __trace_list_to_vector_init();
+ __trace_map_to_unordered_map_init();
+
+ std::atexit(__report);
+
+ __turn_on();
+ }
+ }
+
+ _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
+ }
+
+ /** @brief This function must be called by each instrumentation point.
+ *
+ * The common path is inlined fully.
+ */
+ inline bool
+ __profcxx_init()
+ {
+ if (__is_invalid())
+ __profcxx_init_unconditional();
+
+ return __is_on();
+ }
+
+} // namespace __gnu_profile
+
+#endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_vector_size.h b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
new file mode 100644
index 000000000..604984577
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_vector_size.h
+ * @brief Collection of vector size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H
+#define _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_container_size.h"
+
+namespace __gnu_profile
+{
+ /** @brief Hashtable size instrumentation trace producer. */
+ class __trace_vector_size
+ : public __trace_container_size
+ {
+ public:
+ __trace_vector_size()
+ : __trace_container_size()
+ { __id = "vector-size"; }
+ };
+
+ inline void
+ __trace_vector_size_init()
+ { _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); }
+
+ inline void
+ __trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_vector_size))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_vector_size)->__collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_vector_size)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_vector_size_construct(const void* __obj, std::size_t __num)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_size)->__insert(__obj, __get_stack(),
+ __num);
+ }
+
+ inline void
+ __trace_vector_size_destruct(const void* __obj, std::size_t __num,
+ std::size_t __inum)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_size)->__destruct(__obj, __num, __inum);
+ }
+
+ inline void
+ __trace_vector_size_resize(const void* __obj, std::size_t __from,
+ std::size_t __to)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_size)->__resize(__obj, __from, __to);
+ }
+
+} // namespace __gnu_profile
+
+#endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H */
diff --git a/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
new file mode 100644
index 000000000..7387ab614
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
@@ -0,0 +1,347 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+/** @file profile/impl/profiler_vector_to_list.h
+ * @brief diagnostics for vector to list.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H
+#define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __gnu_profile
+{
+ /** @brief A vector-to-list instrumentation line in the object table. */
+ class __vector2list_info
+ : public __object_info_base
+ {
+ public:
+ __vector2list_info()
+ : _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0),
+ _M_vector_cost(0), _M_valid(true) { }
+
+ __vector2list_info(__stack_t __stack)
+ : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0),
+ _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_valid(true) { }
+
+ virtual ~__vector2list_info() { }
+
+ __vector2list_info(const __vector2list_info& __o)
+ : __object_info_base(__o), _M_shift_count(__o._M_shift_count),
+ _M_iterate(__o._M_iterate), _M_resize(__o._M_resize),
+ _M_list_cost(__o._M_list_cost), _M_vector_cost(__o._M_vector_cost),
+ _M_valid(__o._M_valid) { }
+
+ void
+ __merge(const __vector2list_info& __o)
+ {
+ _M_shift_count += __o._M_shift_count;
+ _M_iterate += __o._M_iterate;
+ _M_vector_cost += __o._M_vector_cost;
+ _M_list_cost += __o._M_list_cost;
+ _M_valid &= __o._M_valid;
+ _M_resize += __o._M_resize;
+ }
+
+ void
+ __write(FILE* __f) const
+ {
+ std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count,
+ _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+ }
+
+ float
+ __magnitude() const
+ { return _M_vector_cost - _M_list_cost; }
+
+ std::string
+ __advice() const
+ { return "change std::vector to std::list"; }
+
+ std::size_t
+ __shift_count()
+ { return _M_shift_count; }
+
+ std::size_t
+ __iterate()
+ { return _M_iterate; }
+
+ float
+ __list_cost()
+ { return _M_list_cost; }
+
+ std::size_t
+ __resize()
+ { return _M_resize; }
+
+ void
+ __set_list_cost(float __lc)
+ { _M_list_cost = __lc; }
+
+ void
+ __set_vector_cost(float __vc)
+ { _M_vector_cost = __vc; }
+
+ bool
+ __is_valid()
+ { return _M_valid; }
+
+ void
+ __set_invalid()
+ { _M_valid = false; }
+
+ void
+ __opr_insert(std::size_t __pos, std::size_t __num)
+ { _M_shift_count += __num - __pos; }
+
+ void
+ __opr_iterate(std::size_t __num)
+ { _M_iterate += __num; }
+
+ void
+ __resize(std::size_t __from, std::size_t)
+ { _M_resize += __from; }
+
+ void
+ __opr_find(std::size_t __size)
+ {
+ // Use average case complexity.
+ _M_iterate += 3.0 / 4.0 * __size;
+ }
+
+ private:
+ std::size_t _M_shift_count;
+ std::size_t _M_iterate;
+ std::size_t _M_resize;
+ float _M_list_cost;
+ float _M_vector_cost;
+ bool _M_valid;
+ };
+
+
+ /** @brief A vector-to-list instrumentation line in the stack table. */
+ class __vector2list_stack_info
+ : public __vector2list_info
+ {
+ public:
+ __vector2list_stack_info(const __vector2list_info& __o)
+ : __vector2list_info(__o) { }
+ };
+
+
+ /** @brief Vector-to-list instrumentation producer. */
+ class __trace_vector_to_list
+ : public __trace_base<__vector2list_info, __vector2list_stack_info>
+ {
+ public:
+ __trace_vector_to_list()
+ : __trace_base<__vector2list_info, __vector2list_stack_info>()
+ { __id = "vector-to-list"; }
+
+ ~__trace_vector_to_list() { }
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void
+ __insert(__object_t __obj, __stack_t __stack)
+ { __add_object(__obj, __vector2list_info(__stack)); }
+
+ // Call at destruction/clean to set container final size.
+ void
+ __destruct(const void* __obj)
+ {
+ if (!__is_on())
+ return;
+
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (!__res)
+ return;
+
+ float __vc = __vector_cost(__res->__shift_count(), __res->__iterate(),
+ __res->__resize());
+ float __lc = __list_cost(__res->__shift_count(), __res->__iterate(),
+ __res->__resize());
+ __res->__set_vector_cost(__vc);
+ __res->__set_list_cost(__lc);
+
+ __retire_object(__obj);
+ }
+
+ // Find the node in the live map.
+ // XXX Undefined?!?
+ __vector2list_info* __find(const void* __obj);
+
+ // Collect cost of operations.
+ void
+ __opr_insert(const void* __obj, std::size_t __pos, std::size_t __num)
+ {
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_insert(__pos, __num);
+ }
+
+ void
+ __opr_iterate(const void* __obj, std::size_t __num)
+ {
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_iterate(__num);
+ }
+
+ void
+ __invalid_operator(const void* __obj)
+ {
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+ }
+
+ void
+ __resize(const void* __obj, std::size_t __from, std::size_t __to)
+ {
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+ }
+
+ float
+ __vector_cost(std::size_t __shift, std::size_t __iterate,
+ std::size_t __resize)
+ {
+ return (__shift
+ * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value
+ + __iterate
+ * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value
+ + __resize
+ * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value);
+ }
+
+ float
+ __list_cost(std::size_t __shift, std::size_t __iterate,
+ std::size_t __resize)
+ {
+ return (__shift
+ * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value
+ + __iterate
+ * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value
+ + __resize
+ * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value);
+ }
+
+ void
+ __opr_find(const void* __obj, std::size_t __size)
+ {
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_find(__size);
+ }
+ };
+
+
+ inline void
+ __trace_vector_to_list_init()
+ { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); }
+
+ inline void
+ __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings)
+ {
+ if (_GLIBCXX_PROFILE_DATA(_S_vector_to_list))
+ {
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->
+ __collect_warnings(__warnings);
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__write(__f);
+ }
+ }
+
+ inline void
+ __trace_vector_to_list_construct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__insert(__obj, __get_stack());
+ }
+
+ inline void
+ __trace_vector_to_list_destruct(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj);
+ }
+
+ inline void
+ __trace_vector_to_list_insert(const void* __obj, std::size_t __pos,
+ std::size_t __num)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_insert(__obj, __pos,
+ __num);
+ }
+
+ inline void
+ __trace_vector_to_list_iterate(const void* __obj, std::size_t __num = 1)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_iterate(__obj, __num);
+ }
+
+ inline void
+ __trace_vector_to_list_invalid_operator(const void* __obj)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__invalid_operator(__obj);
+ }
+
+ inline void
+ __trace_vector_to_list_resize(const void* __obj, std::size_t __from,
+ std::size_t __to)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__resize(__obj, __from, __to);
+ }
+
+ inline void
+ __trace_vector_to_list_find(const void* __obj, std::size_t __size)
+ {
+ if (!__profcxx_init())
+ return;
+
+ _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__opr_find(__obj, __size);
+ }
+
+} // namespace __gnu_profile
+#endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */