summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/include/profile/impl
diff options
context:
space:
mode:
authorrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-03 02:17:41 +0000
committerrus <rus@138bc75d-0d04-0410-961f-82ee72b054a4>2009-10-03 02:17:41 +0000
commitc55dc904bf82da75f1a76a6523c4e8ff16352b4f (patch)
tree4ee10967bd743d512cc41a7b4610019f4ca6adfb /libstdc++-v3/include/profile/impl
parentfb5d6a4fa9aec18d9dda9b4d568d0e2be87a34ef (diff)
downloadppe42-gcc-c55dc904bf82da75f1a76a6523c4e8ff16352b4f.tar.gz
ppe42-gcc-c55dc904bf82da75f1a76a6523c4e8ff16352b4f.zip
merge branch profile-stdlib
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152431 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/profile/impl')
-rw-r--r--libstdc++-v3/include/profile/impl/profiler.h326
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_container_size.h250
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hash_func.h192
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hashtable_size.h115
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h305
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_node.h172
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_state.h107
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_trace.h564
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_size.h112
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_to_list.h318
10 files changed, 2461 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 00000000000..f86920344fc
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler.h
@@ -0,0 +1,326 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler.h
+ * @brief Interface of the profiling runtime library.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_H__
+#define PROFCXX_PROFILER_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+/**
+ * @namespace std::__cxxprof_guard
+ * @brief Mechanism to protect all __cxxprof_impl operations against
+ * multithreaded and exception reentrance.
+ */
+namespace __cxxprof_guard
+{
+
+/** @brief Reentrance guard.
+ *
+ * Mechanism to protect all __cxxprof_impl operations against recursion,
+ * multithreaded and exception reentrance.
+ */
+template <int _Unused=0>
+class __reentrance_guard
+{
+ public:
+ static __thread bool __inside_cxxprof_impl;
+ static bool __get_in();
+ __reentrance_guard() {}
+ ~__reentrance_guard() { __inside_cxxprof_impl = false; }
+};
+
+template <int _Unused>
+__thread bool __reentrance_guard<_Unused>::__inside_cxxprof_impl = false;
+
+template <int _Unused>
+bool __reentrance_guard<_Unused>::__get_in()
+{
+ if (__inside_cxxprof_impl) {
+ return false;
+ } else {
+ __inside_cxxprof_impl = true;
+ return true;
+ }
+}
+
+} // namespace __cxxprof_guard
+
+#define _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__x...) \
+ { \
+ if (__cxxprof_guard::__reentrance_guard<0>::__get_in()) \
+ { \
+ __cxxprof_guard::__reentrance_guard<0> __auto_get_out; \
+ __x; \
+ } \
+ }
+
+/**
+ * @namespace std::__cxxprof_impl
+ * @brief Implementation of profile extension.
+ */
+namespace __cxxprof_impl
+{
+// Forward declarations of implementation functions.
+// Don't use any __cxxprof_impl:: in user code.
+// Instead, use the __profcxx... macros, which offer guarded access.
+void __turn_on();
+void __turn_off();
+bool __is_invalid();
+bool __is_on();
+bool __is_off();
+void __report(void);
+void __trace_hashtable_size_resize(const void*, size_t, size_t);
+void __trace_hashtable_size_destruct(const void*, size_t, size_t);
+void __trace_hashtable_size_construct(const void*, size_t);
+void __trace_vector_size_resize(const void*, size_t, size_t);
+void __trace_vector_size_destruct(const void*, size_t, size_t);
+void __trace_vector_size_construct(const void*, size_t);
+void __trace_hash_func_destruct(const void*, size_t, size_t, 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*, size_t, size_t);
+void __trace_vector_to_list_iterate(const void*, size_t);
+void __trace_vector_to_list_invalid_operator(const void*);
+void __trace_vector_to_list_resize(const void*, size_t, 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*, size_t, size_t);
+void __trace_map_to_unordered_map_erase(const void*, size_t, size_t);
+void __trace_map_to_unordered_map_iterate(const void*, size_t);
+void __trace_map_to_unordered_map_find(const void*, size_t);
+void __trace_map_to_unordered_map_destruct(const void*);
+} // namespace __cxxprof_impl
+
+// Master switch turns on all diagnostics.
+#ifdef _GLIBCXX_PROFILE
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
+#define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
+#define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
+#define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
+#define _GLIBCXX_PROFILE_INEFFICIENT_HASH
+#define _GLIBCXX_PROFILE_VECTOR_TO_LIST
+#define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
+#endif
+
+// Expose global management routines to user code.
+#ifdef _GLIBCXX_PROFILE
+#define __profcxx_report() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__report())
+#define __profcxx_turn_on() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_on())
+#define __profcxx_turn_off() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__turn_off())
+#define __profcxx_is_invalid() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_invalid())
+#define __profcxx_is_on() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__is_on())
+#define __profcxx__is_off() \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD(__cxxprof_impl::__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(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL)) \
+ || (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE) \
+ && !defined(_NO_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE)))
+#define __profcxx_hashtable_resize(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hashtable_size_resize(__x))
+#define __profcxx_hashtable_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hashtable_size_destruct(__x))
+#define __profcxx_hashtable_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__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(_NO_GLIBCXX_PROFILE_VECTOR_TOO_SMALL)) \
+ || (defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE) \
+ && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)))
+#define __profcxx_vector_resize(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_size_resize(__x))
+#define __profcxx_vector_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_size_destruct(__x))
+#define __profcxx_vector_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__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) \
+ && !defined(_NO_GLIBCXX_PROFILE_INEFFICIENT_HASH))
+#define __profcxx_hashtable_construct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_hash_func_construct(__x))
+#define __profcxx_hashtable_destruct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__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) \
+ && !defined(_NO_GLIBCXX_PROFILE_VECTOR_TO_LIST))
+#define __profcxx_vector_construct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_construct(__x))
+#define __profcxx_vector_destruct2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_destruct(__x))
+#define __profcxx_vector_insert(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_insert(__x))
+#define __profcxx_vector_iterate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_iterate(__x))
+#define __profcxx_vector_invalid_operator(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_invalid_operator(__x))
+#define __profcxx_vector_resize2(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_vector_to_list_resize(__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...)
+#endif
+
+// Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
+#if (defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) \
+ && !defined(_NO_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP))
+#define __profcxx_map_to_unordered_map_construct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_construct(__x))
+#define __profcxx_map_to_unordered_map_destruct(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_destruct(__x))
+#define __profcxx_map_to_unordered_map_insert(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_insert(__x))
+#define __profcxx_map_to_unordered_map_erase(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_erase(__x))
+#define __profcxx_map_to_unordered_map_iterate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_iterate(__x))
+#define __profcxx_map_to_unordered_map_invalidate(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__trace_map_to_unordered_map_invalidate(__x))
+#define __profcxx_map_to_unordered_map_find(__x...) \
+ _GLIBCXX_PROFILE_IMPL_REENTRANCE_GUARD( \
+ __cxxprof_impl::__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
+
+// Run multithreaded unless instructed not to do so.
+#ifndef _GLIBCXX_PROFILE_NOTHREADS
+#define _GLIBCXX_PROFILE_THREADS
+#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 2 << 27
+#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"
+
+#endif // PROFCXX_PROFILER_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 00000000000..330afc5ba79
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_container_size.h
@@ -0,0 +1,250 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_trace.h
+ * @brief Diagnostics for container sizes.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_CONTAINER_SIZE_H__
+#define PROFCXX_PROFILER_CONTAINER_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @brief A container size instrumentation line in the object table. */
+class __container_size_info: public __object_info_base
+{
+ public:
+ __container_size_info();
+ __container_size_info(const __container_size_info& __o);
+ __container_size_info(__stack_t __stack, size_t __num);
+ virtual ~__container_size_info() {}
+
+ void __write(FILE* f) const;
+ float __magnitude() const { return static_cast<float>(_M_cost); }
+ const char* __advice() const;
+
+ void __merge(const __container_size_info& __o);
+ // Call if a container is destructed or cleaned.
+ void __destruct(size_t __num, size_t __inum);
+ // Estimate the cost of resize/rehash.
+ float __resize_cost(size_t __from, size_t __to) { return __from; }
+ // Call if container is resized.
+ void __resize(size_t __from, size_t __to);
+
+ private:
+ size_t _M_init;
+ size_t _M_max; // range of # buckets
+ size_t _M_min;
+ size_t _M_total;
+ size_t _M_item_min; // range of # items
+ size_t _M_item_max;
+ size_t _M_item_total;
+ size_t _M_count;
+ size_t _M_resize;
+ size_t _M_cost;
+};
+
+inline const char* __container_size_info::__advice() const
+{
+ const size_t __max_chars_size_t_printed = 20;
+ const char* __message_pattern =
+ "change initial container size from %d to %d";
+ size_t __message_size = (strlen(__message_pattern)
+ + 2 * __max_chars_size_t_printed
+ - 2 * 2);
+ char* __message = new char[__message_size + 1];
+
+ if (_M_init < _M_item_max)
+ snprintf(__message, __message_size, __message_pattern, _M_init,
+ _M_item_max);
+ else
+ snprintf(__message, __message_size, __message_pattern, _M_init,
+ _M_item_max);
+
+ return __message;
+}
+
+inline void __container_size_info::__destruct(size_t __num, size_t __inum)
+{
+ _M_max = __max(_M_max, __num);
+ _M_item_max = __max(_M_item_max, __inum);
+ if (_M_min == 0) {
+ _M_min = __num;
+ _M_item_min = __inum;
+ } else {
+ _M_min = __min(_M_min, __num);
+ _M_item_min = __min(_M_item_min, __inum);
+ }
+ _M_total += __num;
+ _M_item_total += __inum;
+ _M_count += 1;
+}
+
+inline void __container_size_info::__resize(size_t __from, size_t __to)
+{
+ _M_cost += this->__resize_cost(__from, __to);
+ _M_resize += 1;
+ _M_max = __max(_M_max, __to);
+}
+
+inline __container_size_info::__container_size_info(__stack_t __stack,
+ size_t __num)
+ : __object_info_base(__stack), _M_init(0), _M_max(0), _M_item_max(0),
+ _M_min(0), _M_item_min(0), _M_total(0), _M_item_total(0), _M_cost(0),
+ _M_count(0), _M_resize(0)
+{
+ _M_init = _M_max = __num;
+ _M_item_min = _M_item_max = _M_item_total = _M_total = 0;
+ _M_min = 0;
+ _M_count = 0;
+ _M_resize = 0;
+}
+
+inline void __container_size_info::__merge(const __container_size_info& __o)
+{
+ _M_init = __max(_M_init, __o._M_init);
+ _M_max = __max(_M_max, __o._M_max);
+ _M_item_max = __max(_M_item_max, __o._M_item_max);
+ _M_min = __min(_M_min, __o._M_min);
+ _M_item_min = __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;
+}
+
+inline __container_size_info::__container_size_info()
+ : _M_init(0), _M_max(0), _M_item_max(0), _M_min(0), _M_item_min(0),
+ _M_total(0), _M_item_total(0), _M_cost(0), _M_count(0), _M_resize(0)
+{
+}
+
+inline __container_size_info::__container_size_info(
+ const __container_size_info& __o)
+ : __object_info_base(__o)
+{
+ _M_init = __o._M_init;
+ _M_max = __o._M_max;
+ _M_item_max = __o._M_item_max;
+ _M_min = __o._M_min;
+ _M_item_min = __o._M_item_min;
+ _M_total = __o._M_total;
+ _M_item_total = __o._M_item_total;
+ _M_cost = __o._M_cost;
+ _M_count = __o._M_count;
+ _M_resize = __o._M_resize;
+}
+
+/** @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, size_t __num);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj, size_t __num, size_t __inum);
+ void __construct(const void* __obj, size_t __inum);
+ // Call at resize to set resize/cost information.
+ void __resize(const void* __obj, int __from, int __to);
+};
+
+inline void __trace_container_size::__insert(const __object_t __obj,
+ __stack_t __stack, size_t __num)
+{
+ __add_object(__obj, __container_size_info(__stack, __num));
+}
+
+inline void __container_size_info::__write(FILE* __f) const
+{
+ 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);
+}
+
+inline void __trace_container_size::__destruct(const void* __obj,
+ size_t __num, 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);
+}
+
+inline void __trace_container_size::__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 __cxxprof_impl
+#endif /* PROFCXX_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 00000000000..cf639545163
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
@@ -0,0 +1,192 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_HASH_FUNC_H__
+#define PROFCXX_PROFILER_HASH_FUNC_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @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);
+ __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);
+ void __destruct(size_t __chain, size_t __accesses, size_t __hops);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return static_cast<float>(_M_hops); }
+ const char* __advice() const { return "change hash function"; }
+
+private:
+ size_t _M_longest_chain;
+ size_t _M_accesses;
+ size_t _M_hops;
+};
+
+inline __hashfunc_info::__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;
+}
+
+inline void __hashfunc_info::__merge(const __hashfunc_info& __o)
+{
+ _M_longest_chain = __max(_M_longest_chain, __o._M_longest_chain);
+ _M_accesses += __o._M_accesses;
+ _M_hops += __o._M_hops;
+}
+
+inline void __hashfunc_info::__destruct(size_t __chain, size_t __accesses,
+ size_t __hops)
+{
+ _M_longest_chain = __max(_M_longest_chain, __chain);
+ _M_accesses += __accesses;
+ _M_hops += __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_hash_func() {}
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void __insert(__object_t __obj, __stack_t __stack);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops);
+};
+
+inline __trace_hash_func::__trace_hash_func()
+ : __trace_base<__hashfunc_info, __hashfunc_stack_info>()
+{
+ __id = "hash-distr";
+}
+
+inline void __trace_hash_func::__insert(__object_t __obj, __stack_t __stack)
+{
+ __add_object(__obj, __hashfunc_info(__stack));
+}
+
+inline void __hashfunc_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain);
+}
+
+inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain,
+ size_t __accesses, 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);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hash_func_init()
+{
+ __tables<0>::_S_hash_func = new __trace_hash_func();
+}
+
+inline void __trace_hash_func_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_hash_func) {
+ __tables<0>::_S_hash_func->__collect_warnings(__warnings);
+ __tables<0>::_S_hash_func->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hash_func_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hash_func->__insert(__obj, __get_stack());
+}
+
+inline void __trace_hash_func_destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_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 00000000000..2192879325e
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_hashtable_size.cc
+ * @brief Collection of hashtable size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_HASHTABLE_SIZE_H__
+#define PROFCXX_PROFILER_HASHTABLE_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#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 __cxxprof_impl
+{
+
+/** @brief Hashtable size instrumentation trace producer. */
+class __trace_hashtable_size : public __trace_container_size
+{
+ public:
+ __trace_hashtable_size() : __trace_container_size()
+ {
+ __id = "hashtable-size";
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hashtable_size_init()
+{
+ __tables<0>::_S_hashtable_size = new __trace_hashtable_size();
+}
+
+inline void __trace_hashtable_size_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_hashtable_size) {
+ __tables<0>::_S_hashtable_size->__collect_warnings(__warnings);
+ __tables<0>::_S_hashtable_size->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_hashtable_size_construct(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__insert(__obj, __get_stack(), __num);
+}
+
+inline void __trace_hashtable_size_destruct(const void* __obj, size_t __num,
+ size_t __inum)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__destruct(__obj, __num, __inum);
+}
+
+inline void __trace_hashtable_size_resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_hashtable_size->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_PROFILER_HASHTABLE_SIZE_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 00000000000..cdb88a86bcb
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
@@ -0,0 +1,305 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_map_to_unordered_map.h
+ * @brief Diagnostics for map to unordered_map.
+ */
+
+// Written by Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__
+#define PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+// Cost model. XXX: this must be taken from the machine model instead.
+// Map operations:
+// - insert: 1.5 * log(size)
+// - erase: 1.5 * log(size)
+// - find: log(size)
+// - iterate: 2.3
+// Unordered map operations:
+// - insert: 12
+// - erase: 12
+// - find: 10
+// - iterate: 1.7
+
+const float __map_insert_cost_factor = 1.5;
+const float __map_erase_cost_factor = 1.5;
+const float __map_find_cost_factor = 1;
+const float __map_iterate_cost = 2.3;
+
+const float __umap_insert_cost = 12.0;
+const float __umap_erase_cost = 12.0;
+const float __umap_find_cost = 10.0;
+const float __umap_iterate_cost = 1.7;
+
+inline int __log2(size_t __size)
+{
+ for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; --__bit_count) {
+ if ((2 << __bit_count) & __size) {
+ return __bit_count;
+ }
+ }
+ return 0;
+}
+
+inline float __map_insert_cost(size_t __size)
+{
+ return __map_insert_cost_factor * static_cast<float>(__log2(__size));
+}
+
+inline float __map_erase_cost(size_t __size)
+{
+ return __map_erase_cost_factor * static_cast<float>(__log2(__size));
+}
+
+inline float __map_find_cost(size_t __size)
+{
+ return __map_find_cost_factor * 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_map_cost(0.0), _M_umap_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_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
+ virtual ~__map2umap_info() {}
+ __map2umap_info(const __map2umap_info& o);
+ void __merge(const __map2umap_info& o);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return _M_map_cost - _M_umap_cost; }
+ const char* __advice() const;
+
+ void __record_insert(size_t __size, size_t __count);
+ void __record_erase(size_t __size, size_t __count);
+ void __record_find(size_t __size);
+ void __record_iterate(size_t __count);
+ void __record_invalidate();
+
+ private:
+ size_t _M_insert;
+ size_t _M_erase;
+ size_t _M_find;
+ size_t _M_iterate;
+ float _M_umap_cost;
+ float _M_map_cost;
+ bool _M_valid;
+};
+
+inline const char* __map2umap_info::__advice() const
+{
+ return "change std::map to std::unordered_map";
+}
+
+inline __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_map_cost(__o._M_map_cost),
+ _M_umap_cost(__o._M_umap_cost),
+ _M_valid(__o._M_valid)
+{}
+
+inline void __map2umap_info::__merge(const __map2umap_info& __o)
+{
+ _M_insert += __o._M_insert;
+ _M_erase += __o._M_erase;
+ _M_find += __o._M_find;
+ _M_map_cost += __o._M_map_cost;
+ _M_umap_cost += __o._M_umap_cost;
+ _M_valid &= __o._M_valid;
+}
+
+inline void __map2umap_info:: __record_insert(size_t __size, size_t __count)
+{
+ _M_insert += __count;
+ _M_map_cost += __count * __map_insert_cost(__size);
+ _M_umap_cost += __count * __umap_insert_cost;
+}
+
+inline void __map2umap_info:: __record_erase(size_t __size, size_t __count)
+{
+ _M_erase += __count;
+ _M_map_cost += __count * __map_erase_cost(__size);
+ _M_umap_cost += __count * __umap_erase_cost;
+}
+
+inline void __map2umap_info:: __record_find(size_t __size)
+{
+ _M_find += 1;
+ _M_map_cost += __map_find_cost(__size);
+ _M_umap_cost += __umap_find_cost;
+}
+
+inline void __map2umap_info:: __record_iterate(size_t __count)
+{
+ _M_iterate += __count;
+ _M_map_cost += __count * __map_iterate_cost;
+ _M_umap_cost += __count * __umap_iterate_cost;
+}
+
+inline void __map2umap_info:: __record_invalidate()
+{
+ _M_valid = false;
+}
+
+inline void __map2umap_info::__write(FILE* __f) const
+{
+ 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");
+}
+
+/** @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();
+};
+
+inline __trace_map2umap::__trace_map2umap()
+ : __trace_base<__map2umap_info, __map2umap_stack_info>()
+{
+ __id = "map-to-unordered-map";
+}
+
+inline void __trace_map_to_unordered_map_init()
+{
+ __tables<0>::_S_map2umap = new __trace_map2umap();
+}
+
+inline void __trace_map_to_unordered_map_report(
+ FILE* __f, __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_map2umap) {
+ __tables<0>::_S_map2umap->__collect_warnings(__warnings);
+ __tables<0>::_S_map2umap->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_map_to_unordered_map_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_map2umap->__add_object(__obj,
+ __map2umap_info(__get_stack()));
+}
+
+inline void __trace_map_to_unordered_map_destruct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_map2umap->__retire_object(__obj);
+}
+
+inline void __trace_map_to_unordered_map_insert(const void* __obj,
+ size_t __size, size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_insert(__size, __count);
+}
+
+inline void __trace_map_to_unordered_map_erase(const void* __obj,
+ size_t __size, size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_erase(__size, __count);
+}
+
+inline void __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_find(__size);
+}
+
+inline void __trace_map_to_unordered_map_iterate(const void* __obj,
+ size_t __count)
+{
+ if (!__profcxx_init()) return;
+
+ __map2umap_info* __info = __tables<0>::_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 = __tables<0>::_S_map2umap->__get_object_info(__obj);
+
+ if (__info) __info->__record_invalidate();
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_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 00000000000..cd2b9ab2016
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_node.h
@@ -0,0 +1,172 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_node.h
+ * @brief Data structures to represent a single profiling event.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_NODE_H__
+#define PROFCXX_PROFILER_NODE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdint>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include <vector>
+#if defined HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+namespace __cxxprof_impl
+{
+typedef const void* __object_t;
+typedef void* __instruction_address_t;
+typedef std::_GLIBCXX_STD_PR::vector<__instruction_address_t> __stack_npt;
+typedef __stack_npt* __stack_t;
+
+size_t __stack_max_depth();
+
+inline __stack_t __get_stack()
+{
+#if defined HAVE_EXECINFO_H
+ size_t __max_depth = __stack_max_depth();
+ if (__max_depth == 0)
+ return NULL;
+ __stack_npt __buffer(__max_depth);
+ int __depth = backtrace(&__buffer[0], __max_depth);
+ __stack_t __stack = new __stack_npt(__depth);
+ memcpy(&(*__stack)[0], &__buffer[0], __depth * sizeof(__object_t));
+ return __stack;
+#else
+ return NULL;
+#endif
+}
+
+inline __size(const __stack_t& __stack)
+{
+ if (!__stack) {
+ return 0;
+ } else {
+ return __stack->size();
+ }
+}
+
+inline void __write(FILE* __f, const __stack_t __stack)
+{
+ if (!__stack) {
+ return;
+ }
+
+ __stack_npt::const_iterator __it;
+ for (__it = __stack->begin(); __it != __stack->end(); ++__it) {
+ fprintf(__f, "%p ", *__it);
+ }
+}
+
+/** @brief Hash function for summary trace using call stack as index. */
+class __stack_hash
+{
+ public:
+ size_t operator()(const __stack_t __s) const
+ {
+ if (!__s) {
+ return 0;
+ }
+
+ uintptr_t __index = 0;
+ __stack_npt::const_iterator __it;
+ for (__it = __s->begin(); __it != __s->end(); ++__it) {
+ __index += reinterpret_cast<uintptr_t>(*__it);
+ }
+ return __index;
+ }
+
+ bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
+ {
+ if (!__stack1 && !__stack2) return true;
+ if (!__stack1 || !__stack2) return false;
+ if (__stack1->size() != __stack2->size()) return false;
+
+ size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type);
+ return 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);
+ __object_info_base(const __object_info_base& o);
+ 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;
+};
+
+inline __object_info_base::__object_info_base(__stack_t __stack)
+{
+ _M_stack = __stack;
+ _M_valid = true;
+}
+
+inline __object_info_base::__object_info_base(const __object_info_base& __o)
+{
+ _M_stack = __o._M_stack;
+ _M_valid = __o._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 __cxxprof_impl
+#endif /* PROFCXX_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 00000000000..64c10db616c
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_state.h
@@ -0,0 +1,107 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_state.cc
+ * @brief Global profiler state.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_STATE_H__
+#define PROFCXX_PROFILER_STATE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+
+namespace __cxxprof_impl
+{
+
+/** @brief Profiling mode on/off state. */
+template <int _Unused=0>
+class __state
+{
+ public:
+
+ static __state<_Unused>* _S_diag_state;
+
+ __state() : _M_state(__INVALID) {}
+ ~__state() {}
+
+ bool __is_on() { return _M_state == __ON; }
+ bool __is_off() { return _M_state == __OFF; }
+ bool __is_invalid() { return _M_state == __INVALID; }
+ void __turn_on() { _M_state = __ON; }
+ void __turn_off() { _M_state = __OFF; }
+
+ private:
+ enum __state_type { __ON, __OFF, __INVALID };
+ __state_type _M_state;
+};
+
+template <int _Unused>
+__state<_Unused>* __state<_Unused>::_S_diag_state = NULL;
+
+inline bool __is_on()
+{
+ return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_on();
+}
+
+inline bool __is_off()
+{
+ return __state<0>::_S_diag_state && __state<0>::_S_diag_state->__is_off();
+}
+
+inline bool __is_invalid()
+{
+ return (!__state<0>::_S_diag_state
+ || __state<0>::_S_diag_state->__is_invalid());
+}
+
+inline void __turn_on()
+{
+ if (!__state<0>::_S_diag_state) {
+ __state<0>::_S_diag_state = new __state<0>();
+ }
+ __state<0>::_S_diag_state->__turn_on();
+}
+
+inline void __turn_off()
+{
+ if (!__state<0>::_S_diag_state) {
+ __state<0>::_S_diag_state = new __state<0>();
+ }
+ __state<0>::_S_diag_state->__turn_off();
+}
+
+} // end namespace __cxxprof_impl
+#endif /* PROFCXX_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 00000000000..37bcb6436e5
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_trace.h
@@ -0,0 +1,564 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_TRACE_H__
+#define PROFCXX_PROFILER_TRACE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cerrno>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_PR::unordered_map
+#include <unordered_map>
+#else
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tr1/unordered_map>
+#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
+#endif
+
+#include <algorithm>
+#include <utility>
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#include <pthread.h>
+#endif
+
+#include "profile/impl/profiler_state.h"
+#include "profile/impl/profiler_node.h"
+
+namespace __cxxprof_impl
+{
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#define _GLIBCXX_IMPL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+typedef pthread_mutex_t __mutex_t;
+/** @brief Pthread mutex wrapper. */
+template <int _Unused=0>
+class __mutex {
+ public:
+ static __mutex_t __global_lock;
+ static void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
+ static void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
+};
+#else
+#define _GLIBCXX_IMPL_MUTEX_INITIALIZER 0
+typedef int __mutex_t;
+/** @brief Mock mutex interface. */
+template <int _Unused=0>
+class __mutex {
+ public:
+ static __mutex_t __global_lock;
+ static void __lock(__mutex_t& __m) {}
+ static void __unlock(__mutex_t& __m) {}
+};
+#endif
+
+template <int _Unused>
+__mutex_t __mutex<_Unused>::__global_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+
+/** @brief Representation of a warning. */
+struct __warning_data
+{
+ float __magnitude;
+ __stack_t __context;
+ const char* __warning_id;
+ const char* __warning_message;
+ __warning_data();
+ __warning_data(float __m, __stack_t __c, const char* __id,
+ const char* __msg);
+ bool operator>(const struct __warning_data& other) const;
+};
+
+inline __warning_data::__warning_data()
+ : __magnitude(0.0), __context(NULL), __warning_id(NULL),
+ __warning_message(NULL)
+{
+}
+
+inline __warning_data::__warning_data(float __m, __stack_t __c,
+ const char* __id, const char* __msg)
+ : __magnitude(__m), __context(__c), __warning_id(__id),
+ __warning_message(__msg)
+{
+}
+
+inline bool __warning_data::operator>(const struct __warning_data& other) const
+{
+ return __magnitude > other.__magnitude;
+}
+
+typedef std::_GLIBCXX_STD_PR::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;
+void __trace_vector_size_init();
+void __trace_hashtable_size_init();
+void __trace_hash_func_init();
+void __trace_vector_to_list_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_map_to_unordered_map_report(FILE*, __warning_vector_t&);
+
+// Utility functions.
+inline size_t __max(size_t __a, size_t __b)
+{
+ return __a >= __b ? __a : __b;
+}
+
+inline size_t __min(size_t __a, size_t __b)
+{
+ return __a <= __b ? __a : __b;
+}
+
+/** @brief Storage for diagnostic table entries. Has only static fields. */
+template <int _Unused=0>
+class __tables
+{
+ public:
+ static __trace_hash_func* _S_hash_func;
+ static __trace_hashtable_size* _S_hashtable_size;
+ static __trace_map2umap* _S_map2umap;
+ static __trace_vector_size* _S_vector_size;
+ static __trace_vector_to_list* _S_vector_to_list;
+};
+
+template <int _Unused>
+__trace_hash_func* __tables<_Unused>::_S_hash_func = NULL;
+template <int _Unused>
+__trace_hashtable_size* __tables<_Unused>::_S_hashtable_size = NULL;
+template <int _Unused>
+__trace_map2umap* __tables<_Unused>::_S_map2umap = NULL;
+template <int _Unused>
+__trace_vector_size* __tables<_Unused>::_S_vector_size = NULL;
+template <int _Unused>
+__trace_vector_to_list* __tables<_Unused>::_S_vector_to_list = NULL;
+
+/** @brief Storage for user defined parameters. Has only static fields. */
+template <int _Unused=0>
+class __settings {
+ public:
+ static const char* _S_trace_file_name;
+ static size_t _S_max_warn_count;
+ static size_t _S_max_stack_depth;
+ static size_t _S_max_mem;
+};
+
+template <int _Unused>
+const char* __settings<_Unused>::_S_trace_file_name =
+ _GLIBCXX_PROFILE_TRACE_PATH_ROOT;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_warn_count =
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_stack_depth =
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH;
+template <int _Unused>
+size_t __settings<_Unused>::_S_max_mem =
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC;
+
+inline size_t __stack_max_depth()
+{
+ return __settings<0>::_S_max_stack_depth;
+}
+
+inline size_t __max_mem()
+{
+ return __settings<0>::_S_max_mem;
+}
+
+/** @brief Base class for all trace producers. */
+template <typename __object_info, typename __stack_info>
+class __trace_base
+{
+ public:
+ __trace_base();
+ 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);
+
+ void __lock_object_table();
+ void __lock_stack_table();
+ void __unlock_object_table();
+ void __unlock_stack_table();
+
+ private:
+ __mutex_t __object_table_lock;
+ __mutex_t __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;
+ 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)
+{
+ typename __stack_table_t::iterator __i = __stack_table.begin();
+ for ( ; __i != __stack_table.end(); ++__i )
+ {
+ warnings.push_back(__warning_data((*__i).second.__magnitude(),
+ (*__i).first,
+ __id,
+ (*__i).second.__advice()));
+ }
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_object_table()
+{
+ __mutex<0>::__lock(this->__object_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_stack_table()
+{
+ __mutex<0>::__lock(this->__stack_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_object_table()
+{
+ __mutex<0>::__unlock(this->__object_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_stack_table()
+{
+ __mutex<0>::__unlock(this->__stack_table_lock);
+}
+
+template <typename __object_info, typename __stack_info>
+__trace_base<__object_info, __stack_info>::__trace_base()
+{
+ // Do not pick the initial size too large, as we don't know which diagnostics
+ // are more active.
+ __object_table.rehash(10000);
+ __stack_table.rehash(10000);
+ __stack_table_byte_size = 0;
+ __id = NULL;
+ __object_table_lock = __stack_table_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
+}
+
+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()) {
+ __lock_object_table();
+ __object_table.insert(
+ typename __object_table_t::value_type(__object, __info));
+ __unlock_object_table();
+ }
+}
+
+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.
+ __lock_object_table();
+ typename __object_table_t::iterator __object_it =
+ __object_table.find(__object);
+ if (__object_it == __object_table.end()){
+ __unlock_object_table();
+ return NULL;
+ } else {
+ __unlock_object_table();
+ return &__object_it->second;
+ }
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__retire_object(
+ __object_t __object)
+{
+ __lock_object_table();
+ __lock_stack_table();
+ 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);
+ }
+ __unlock_stack_table();
+ __unlock_object_table();
+}
+
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__write(FILE* __f)
+{
+ typename __stack_table_t::iterator __it;
+
+ for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) {
+ if (__it->second.__is_valid()) {
+ fprintf(__f, __id);
+ fprintf(__f, "|");
+ __cxxprof_impl::__write(__f, __it->first);
+ fprintf(__f, "|");
+ __it->second.__write(__f);
+ }
+ }
+}
+
+inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
+{
+ char* __env_value = getenv(__env_var);
+ if (__env_value) {
+ long int __converted_value = strtol(__env_value, NULL, 10);
+ if (errno || __converted_value < 0) {
+ fprintf(stderr, "Bad value for environment variable '%s'.", __env_var);
+ abort();
+ } else {
+ return static_cast<size_t>(__converted_value);
+ }
+ } else {
+ return __default_value;
+ }
+}
+
+inline void __set_max_stack_trace_depth()
+{
+ __settings<0>::_S_max_stack_depth = __env_to_size_t(
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
+ __settings<0>::_S_max_stack_depth);
+}
+
+inline void __set_max_mem()
+{
+ __settings<0>::_S_max_mem = __env_to_size_t(
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, __settings<0>::_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;
+}
+
+struct __warn
+{
+ FILE* __file;
+ __warn(FILE* __f) { __file = __f; }
+ void operator() (const __warning_data& __info)
+ {
+ fprintf(__file, __info.__warning_id);
+ fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude));
+ fprintf(__file, ": call stack = ");
+ __cxxprof_impl::__write(__file, __info.__context);
+ fprintf(__file, ": advice = %s\n", __info.__warning_message);
+ }
+};
+
+inline FILE* __open_output_file(const char* extension)
+{
+ // The path is made of _S_trace_file_name + "." + extension.
+ size_t root_len = strlen(__settings<0>::_S_trace_file_name);
+ size_t ext_len = strlen(extension);
+ char* file_name = new char[root_len + 1 + ext_len + 1];
+ char* p = file_name;
+ memcpy(file_name, __settings<0>::_S_trace_file_name, root_len);
+ *(file_name + root_len) = '.';
+ memcpy(file_name + root_len + 1, extension, ext_len + 1);
+ FILE* out_file = fopen(file_name, "w");
+ if (out_file) {
+ return out_file;
+ } else {
+ fprintf(stderr, "Could not open trace file '%s'.", file_name);
+ abort();
+ }
+}
+
+/** @brief Final report method, registered with "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
+ * __cxxprof_impl (under the guarded zone), no output will be produced.
+ */
+inline void __report(void)
+{
+ __mutex<0>::__lock(__mutex<0>::__global_lock);
+
+ __warning_vector_t __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_map_to_unordered_map_report(__raw_file, __warnings);
+ fclose(__raw_file);
+
+ // Sort data by magnitude.
+ // XXX: instead of sorting, should collect only top N for better performance.
+ size_t __cutoff = __min(__settings<0>::_S_max_warn_count,
+ __warnings.size());
+
+ std::sort(__warnings.begin(), __warnings.end(),
+ std::greater<__warning_vector_t::value_type>());
+ __warnings.resize(__cutoff);
+
+ FILE* __warn_file = __open_output_file("txt");
+ std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
+ fclose(__warn_file);
+
+ __mutex<0>::__unlock(__mutex<0>::__global_lock);
+}
+
+inline void __set_trace_path()
+{
+ char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+
+ if (__env_trace_file_name) {
+ __settings<0>::_S_trace_file_name = __env_trace_file_name;
+ }
+
+ // Make sure early that we can create the trace file.
+ fclose(__open_output_file("txt"));
+}
+
+inline void __set_max_warn_count()
+{
+ char* __env_max_warn_count_str = getenv(
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+
+ if (__env_max_warn_count_str) {
+ __settings<0>::_S_max_warn_count = static_cast<size_t>(
+ atoi(__env_max_warn_count_str));
+ }
+}
+
+inline void __profcxx_init_unconditional()
+{
+ __mutex<0>::__lock(__mutex<0>::__global_lock);
+
+ __set_max_warn_count();
+
+ if (__is_invalid()) {
+
+ if (__settings<0>::_S_max_warn_count == 0) {
+
+ __turn_off();
+
+ } else {
+
+ __set_max_stack_trace_depth();
+ __set_max_mem();
+ __set_trace_path();
+
+ __trace_vector_size_init();
+ __trace_hashtable_size_init();
+ __trace_hash_func_init();
+ __trace_vector_to_list_init();
+ __trace_map_to_unordered_map_init();
+
+ atexit(__report);
+
+ __turn_on();
+
+ }
+ }
+
+ __mutex<0>::__unlock(__mutex<0>::__global_lock);
+}
+
+/** @brief This function must be called by each instrumentation point.
+ *
+ * The common path is inlined fully.
+ */
+inline bool __profcxx_init(void)
+{
+ if (__is_invalid()) {
+ __profcxx_init_unconditional();
+ }
+
+ return __is_on();
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_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 00000000000..dd42959825f
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_vector_size.h
+ * @brief Collection of vector size traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_VECTOR_SIZE_H__
+#define PROFCXX_PROFILER_VECTOR_SIZE_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+#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 __cxxprof_impl
+{
+
+/** @brief Hashtable size instrumentation trace producer. */
+class __trace_vector_size : public __trace_container_size
+{
+ public:
+ __trace_vector_size() : __trace_container_size() { __id = "vector-size"; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_size_init()
+{
+ __tables<0>::_S_vector_size = new __trace_vector_size();
+}
+
+inline void __trace_vector_size_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_vector_size) {
+ __tables<0>::_S_vector_size->__collect_warnings(__warnings);
+ __tables<0>::_S_vector_size->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_size_construct(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__insert(__obj, __get_stack(), __num);
+}
+
+inline void __trace_vector_size_destruct(const void* __obj, size_t __num,
+ size_t __inum)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__destruct(__obj, __num, __inum);
+}
+
+inline void __trace_vector_size_resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_size->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+
+#endif /* PROFCXX_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 00000000000..ec3dfbcfb86
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
@@ -0,0 +1,318 @@
+// -*- C++ -*-
+//
+// Copyright (C) 2009 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 2, 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/** @file profile/impl/profiler_trace.h
+ * @brief Data structures to represent profiling traces.
+ */
+
+// Written by Lixia Liu and Silvius Rus.
+
+#ifndef PROFCXX_PROFILER_VECTOR_TO_LIST_H__
+#define PROFCXX_PROFILER_VECTOR_TO_LIST_H__ 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include "profile/impl/profiler.h"
+#include "profile/impl/profiler_node.h"
+#include "profile/impl/profiler_trace.h"
+
+namespace __cxxprof_impl
+{
+
+/** @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);
+ void __merge(const __vector2list_info& __o);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return _M_vector_cost - _M_list_cost; }
+ const char* __advice() const { return "change std::vector to std::list"; }
+
+ size_t __shift_count() { return _M_shift_count; }
+ size_t __iterate() { return _M_iterate; }
+ float __list_cost() { return _M_list_cost; }
+ 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(size_t __pos, size_t __num);
+ void __opr_iterate(size_t __num) { _M_iterate += __num; }
+ void __resize(size_t __from, size_t __to);
+
+private:
+ size_t _M_shift_count;
+ size_t _M_iterate;
+ size_t _M_resize;
+ float _M_list_cost;
+ float _M_vector_cost;
+ bool _M_valid;
+};
+
+inline __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_vector_cost = __o._M_vector_cost;
+ _M_list_cost = __o._M_list_cost;
+ _M_valid = __o._M_valid;
+ _M_resize = __o._M_resize;
+}
+
+inline void __vector2list_info::__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;
+}
+
+inline void __vector2list_info::__opr_insert(size_t __pos, size_t __num)
+{
+ _M_shift_count += __num - __pos;
+}
+
+inline void __vector2list_info::__resize(size_t __from, size_t __to)
+{
+ _M_resize += __from;
+}
+
+/** @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_vector_to_list() {}
+
+ // Insert a new node at construct with object, callstack and initial size.
+ void __insert(__object_t __obj, __stack_t __stack);
+ // Call at destruction/clean to set container final size.
+ void __destruct(const void* __obj);
+
+ // Find the node in the live map.
+ __vector2list_info* __find(const void* __obj);
+
+ // Collect cost of operations.
+ void __opr_insert(const void* __obj, size_t __pos, size_t __num);
+ void __opr_iterate(const void* __obj, size_t __num);
+ void __invalid_operator(const void* __obj);
+ void __resize(const void* __obj, size_t __from, size_t __to);
+ float __vector_cost(size_t __shift, size_t __iterate, size_t __resize);
+ float __list_cost(size_t __shift, size_t __iterate, size_t __resize);
+};
+
+inline __trace_vector_to_list::__trace_vector_to_list()
+ : __trace_base<__vector2list_info, __vector2list_stack_info>()
+{
+ __id = "vector-to-list";
+}
+
+inline void __trace_vector_to_list::__insert(__object_t __obj,
+ __stack_t __stack)
+{
+ __add_object(__obj, __vector2list_info(__stack));
+}
+
+inline void __vector2list_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n",
+ _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost);
+}
+
+// Cost model. XXX: get this from the cost model database instead.
+// Vector operation cost:
+// - Cost per shift: 1
+// - Cost per access: 1
+// - Cost per resize: 1
+// List operation cost:
+// - Cost per shift: 0
+// - Cost per access: 10
+// - Cost per resize: 0
+
+inline float __trace_vector_to_list::__vector_cost(size_t __shift,
+ size_t __iterate,
+ size_t __resize)
+{
+ return __shift * 1 + __iterate * 1 + __resize * 1;
+}
+
+inline float __trace_vector_to_list::__list_cost(size_t __shift,
+ size_t __iterate,
+ size_t __resize)
+{
+ return __shift * 0 + __iterate * 10 + __resize * 0;
+}
+
+inline void __trace_vector_to_list::__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);
+}
+
+inline void __trace_vector_to_list::__opr_insert(const void* __obj,
+ size_t __pos, size_t __num)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_insert(__pos, __num);
+}
+
+inline void __trace_vector_to_list::__opr_iterate(const void* __obj,
+ size_t __num)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_iterate(__num);
+}
+
+inline void __trace_vector_to_list::__invalid_operator(const void* __obj)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+}
+
+inline void __trace_vector_to_list::__resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Initialization and report.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_to_list_init()
+{
+ __tables<0>::_S_vector_to_list = new __trace_vector_to_list();
+}
+
+inline void __trace_vector_to_list_report(FILE* __f,
+ __warning_vector_t& __warnings)
+{
+ if (__tables<0>::_S_vector_to_list) {
+ __tables<0>::_S_vector_to_list->__collect_warnings(__warnings);
+ __tables<0>::_S_vector_to_list->__write(__f);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Implementations of instrumentation hooks.
+//////////////////////////////////////////////////////////////////////////////
+
+inline void __trace_vector_to_list_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__insert(__obj, __get_stack());
+}
+
+inline void __trace_vector_to_list_destruct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__destruct(__obj);
+}
+
+inline void __trace_vector_to_list_insert(const void* __obj,
+ size_t __pos, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__opr_insert(__obj, __pos, __num);
+}
+
+
+inline void __trace_vector_to_list_iterate(const void* __obj, size_t __num)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__opr_iterate(__obj, __num);
+}
+
+inline void __trace_vector_to_list_invalid_operator(const void* __obj)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__invalid_operator(__obj);
+}
+
+inline void __trace_vector_to_list_resize(const void* __obj,
+ size_t __from, size_t __to)
+{
+ if (!__profcxx_init()) return;
+
+ __tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
+}
+
+} // namespace __cxxprof_impl
+#endif /* PROFCXX_PROFILER_VECTOR_TO_LIST_H__ */
OpenPOWER on IntegriCloud