summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/profile
diff options
context:
space:
mode:
authorSilvius Rus <rus@google.com>2010-01-10 08:25:23 +0000
committerSilvius Rus <rus@gcc.gnu.org>2010-01-10 08:25:23 +0000
commita1360f5702b28237af3c00a517492a8faf78f494 (patch)
tree2ae0e898916516734c5d6bcf4385bc03d46207e9 /libstdc++-v3/include/profile
parent9b2adcdbc12edf30eb4bedcff79f8f9050c7f29a (diff)
downloadgcc-a1360f5702b28237af3c00a517492a8faf78f494.tar.gz
libstdc++ profile mode bug fixes and minor updates
From-SVN: r155786
Diffstat (limited to 'libstdc++-v3/include/profile')
-rw-r--r--libstdc++-v3/include/profile/hashtable.h1151
-rw-r--r--libstdc++-v3/include/profile/impl/profiler.h238
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_container_size.h358
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hash_func.h241
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_hashtable_size.h81
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_list_to_slist.h182
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_list_to_vector.h313
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h434
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_node.h190
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_state.h90
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_trace.h1021
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_size.h80
-rw-r--r--libstdc++-v3/include/profile/impl/profiler_vector_to_list.h503
-rw-r--r--libstdc++-v3/include/profile/iterator_tracker.h273
-rw-r--r--libstdc++-v3/include/profile/list199
-rw-r--r--libstdc++-v3/include/profile/vector139
16 files changed, 2713 insertions, 2780 deletions
diff --git a/libstdc++-v3/include/profile/hashtable.h b/libstdc++-v3/include/profile/hashtable.h
deleted file mode 100644
index 20891877121..00000000000
--- a/libstdc++-v3/include/profile/hashtable.h
+++ /dev/null
@@ -1,1151 +0,0 @@
-// Hashtable implementation used by containers -*- C++ -*-
-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
-// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// 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.
-
-/*
- * Copyright (c) 1996,1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-
-/** @file profile/hashtable.h copied from backward/hashtable.h
- * This file is a GNU extension to the Standard C++ Library (possibly
- * containing extensions from the HP/SGI STL subset).
- */
-
-#ifndef _HASHTABLE_H
-#define _HASHTABLE_H 1
-
-// Hashtable class, used to implement the hashed associative containers
-// hash_set, hash_map, hash_multiset, and hash_multimap.
-// Skip instrumentation on vector.
-#include <vector>
-#include <iterator>
-#include <algorithm>
-#include <bits/stl_function.h>
-#include <backward/hash_fun.h>
-#include <profile/base.h>
-
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
-
- using std::size_t;
- using std::ptrdiff_t;
- using std::forward_iterator_tag;
- using std::input_iterator_tag;
- using std::_Construct;
- using std::_Destroy;
- using std::distance;
- using std::_GLIBCXX_STD_D::vector;
- using std::pair;
- using std::__iterator_category;
-
- template<class _Val>
- struct _Hashtable_node
- {
- _Hashtable_node* _M_next;
- _Val _M_val;
- };
-
- template<class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc = std::allocator<_Val> >
- class hashtable;
-
- template<class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_iterator;
-
- template<class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_const_iterator;
-
- template<class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_iterator
- {
- typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
- typedef forward_iterator_tag iterator_category;
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef _Val& reference;
- typedef _Val* pointer;
-
- _Node* _M_cur;
- _Hashtable* _M_ht;
-
- _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
- : _M_cur(__n), _M_ht(__tab) { }
-
- _Hashtable_iterator() { }
-
- reference
- operator*() const
- { return _M_cur->_M_val; }
-
- pointer
- operator->() const
- { return &(operator*()); }
-
- iterator&
- operator++();
-
- iterator
- operator++(int);
-
- bool
- operator==(const iterator& __it) const
- { return _M_cur == __it._M_cur; }
-
- bool
- operator!=(const iterator& __it) const
- { return _M_cur != __it._M_cur; }
- };
-
- template<class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_const_iterator
- {
- typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
- _ExtractKey,_EqualKey,_Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
-
- typedef forward_iterator_tag iterator_category;
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef const _Val& reference;
- typedef const _Val* pointer;
-
- const _Node* _M_cur;
- const _Hashtable* _M_ht;
-
- _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
- : _M_cur(__n), _M_ht(__tab) { }
-
- _Hashtable_const_iterator() { }
-
- _Hashtable_const_iterator(const iterator& __it)
- : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
-
- reference
- operator*() const
- { return _M_cur->_M_val; }
-
- pointer
- operator->() const
- { return &(operator*()); }
-
- const_iterator&
- operator++();
-
- const_iterator
- operator++(int);
-
- bool
- operator==(const const_iterator& __it) const
- { return _M_cur == __it._M_cur; }
-
- bool
- operator!=(const const_iterator& __it) const
- { return _M_cur != __it._M_cur; }
- };
-
- // Note: assumes long is at least 32 bits.
- enum { _S_num_primes = 28 };
-
- static const unsigned long __stl_prime_list[_S_num_primes] =
- {
- 53ul, 97ul, 193ul, 389ul, 769ul,
- 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
- 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
- 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
- 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
- 1610612741ul, 3221225473ul, 4294967291ul
- };
-
- inline unsigned long
- __stl_next_prime(unsigned long __n)
- {
- const unsigned long* __first = __stl_prime_list;
- const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
- const unsigned long* pos = std::lower_bound(__first, __last, __n);
- return pos == __last ? *(__last - 1) : *pos;
- }
-
- // Forward declaration of operator==.
- template<class _Val, class _Key, class _HF, class _Ex,
- class _Eq, class _All>
- class hashtable;
-
- template<class _Val, class _Key, class _HF, class _Ex,
- class _Eq, class _All>
- bool
- operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
-
- // Hashtables handle allocators a bit differently than other
- // containers do. If we're using standard-conforming allocators, then
- // a hashtable unconditionally has a member variable to hold its
- // allocator, even if it so happens that all instances of the
- // allocator type are identical. This is because, for hashtables,
- // this extra storage is negligible. Additionally, a base class
- // wouldn't serve any other purposes; it wouldn't, for example,
- // simplify the exception-handling code.
- template<class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- class hashtable
- {
- public:
- typedef _Key key_type;
- typedef _Val value_type;
- typedef _HashFcn hasher;
- typedef _EqualKey key_equal;
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef value_type& reference;
- typedef const value_type& const_reference;
-
- hasher
- hash_funct() const
- { return _M_hash; }
-
- key_equal
- key_eq() const
- { return _M_equals; }
-
- private:
- typedef _Hashtable_node<_Val> _Node;
-
- public:
- typedef typename _Alloc::template rebind<value_type>::other allocator_type;
- allocator_type
- get_allocator() const
- { return _M_node_allocator; }
-
- private:
- typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
- typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
- typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
-
- _Node_Alloc _M_node_allocator;
-
- _Node*
- _M_get_node()
- { return _M_node_allocator.allocate(1); }
-
- void
- _M_put_node(_Node* __p)
- { _M_node_allocator.deallocate(__p, 1); }
-
- private:
- hasher _M_hash;
- key_equal _M_equals;
- _ExtractKey _M_get_key;
- _Vector_type _M_buckets;
- size_type _M_num_elements;
-
- public:
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>
- const_iterator;
-
- friend struct
- _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
-
- friend struct
- _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>;
-
- public:
- hashtable(size_type __n, const _HashFcn& __hf,
- const _EqualKey& __eql, const _ExtractKey& __ext,
- const allocator_type& __a = allocator_type())
- : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
- _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
- { _M_initialize_buckets(__n); }
-
- hashtable(size_type __n, const _HashFcn& __hf,
- const _EqualKey& __eql,
- const allocator_type& __a = allocator_type())
- : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
- _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
- { _M_initialize_buckets(__n); }
-
- hashtable(const hashtable& __ht)
- : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
- _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
- _M_buckets(__ht.get_allocator()), _M_num_elements(0)
- { _M_copy_from(__ht); }
-
- hashtable&
- operator= (const hashtable& __ht)
- {
- if (&__ht != this)
- {
- clear();
- _M_hash = __ht._M_hash;
- _M_equals = __ht._M_equals;
- _M_get_key = __ht._M_get_key;
- _M_copy_from(__ht);
- }
- return *this;
- }
-
- ~hashtable()
- { clear(); }
-
- size_type
- size() const
- { return _M_num_elements; }
-
- size_type
- max_size() const
- { return size_type(-1); }
-
- bool
- empty() const
- { return size() == 0; }
-
- void
- swap(hashtable& __ht)
- {
- std::swap(_M_hash, __ht._M_hash);
- std::swap(_M_equals, __ht._M_equals);
- std::swap(_M_get_key, __ht._M_get_key);
- _M_buckets.swap(__ht._M_buckets);
- std::swap(_M_num_elements, __ht._M_num_elements);
- }
-
- iterator
- begin()
- {
- for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
- if (_M_buckets[__n])
- return iterator(_M_buckets[__n], this);
- return end();
- }
-
- iterator
- end()
- { return iterator(0, this); }
-
- const_iterator
- begin() const
- {
- for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
- if (_M_buckets[__n])
- return const_iterator(_M_buckets[__n], this);
- return end();
- }
-
- const_iterator
- end() const
- { return const_iterator(0, this); }
-
- template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
- class _Al>
- friend bool
- operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
- const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
-
- public:
- size_type
- bucket_count() const
- { return _M_buckets.size(); }
-
- size_type
- max_bucket_count() const
- { return __stl_prime_list[(int)_S_num_primes - 1]; }
-
- size_type
- elems_in_bucket(size_type __bucket) const
- {
- size_type __result = 0;
- for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
- __result += 1;
- return __result;
- }
-
- pair<iterator, bool>
- insert_unique(const value_type& __obj)
- {
- resize(_M_num_elements + 1);
- return insert_unique_noresize(__obj);
- }
-
- iterator
- insert_equal(const value_type& __obj)
- {
- resize(_M_num_elements + 1);
- return insert_equal_noresize(__obj);
- }
-
- pair<iterator, bool>
- insert_unique_noresize(const value_type& __obj);
-
- iterator
- insert_equal_noresize(const value_type& __obj);
-
- template<class _InputIterator>
- void
- insert_unique(_InputIterator __f, _InputIterator __l)
- { insert_unique(__f, __l, __iterator_category(__f)); }
-
- template<class _InputIterator>
- void
- insert_equal(_InputIterator __f, _InputIterator __l)
- { insert_equal(__f, __l, __iterator_category(__f)); }
-
- template<class _InputIterator>
- void
- insert_unique(_InputIterator __f, _InputIterator __l,
- input_iterator_tag)
- {
- for ( ; __f != __l; ++__f)
- insert_unique(*__f);
- }
-
- template<class _InputIterator>
- void
- insert_equal(_InputIterator __f, _InputIterator __l,
- input_iterator_tag)
- {
- for ( ; __f != __l; ++__f)
- insert_equal(*__f);
- }
-
- template<class _ForwardIterator>
- void
- insert_unique(_ForwardIterator __f, _ForwardIterator __l,
- forward_iterator_tag)
- {
- size_type __n = distance(__f, __l);
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_unique_noresize(*__f);
- }
-
- template<class _ForwardIterator>
- void
- insert_equal(_ForwardIterator __f, _ForwardIterator __l,
- forward_iterator_tag)
- {
- size_type __n = distance(__f, __l);
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_equal_noresize(*__f);
- }
-
- reference
- find_or_insert(const value_type& __obj);
-
- iterator
- find(const key_type& __key)
- {
- size_type __n = _M_bkt_num_key(__key);
- _Node* __first;
- for (__first = _M_buckets[__n];
- __first && !_M_equals(_M_get_key(__first->_M_val), __key);
- __first = __first->_M_next)
- { }
- return iterator(__first, this);
- }
-
- const_iterator
- find(const key_type& __key) const
- {
- size_type __n = _M_bkt_num_key(__key);
- const _Node* __first;
- for (__first = _M_buckets[__n];
- __first && !_M_equals(_M_get_key(__first->_M_val), __key);
- __first = __first->_M_next)
- { }
- return const_iterator(__first, this);
- }
-
- size_type
- count(const key_type& __key) const
- {
- const size_type __n = _M_bkt_num_key(__key);
- size_type __result = 0;
-
- for (const _Node* __cur = _M_buckets[__n]; __cur;
- __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), __key))
- ++__result;
- return __result;
- }
-
- pair<iterator, iterator>
- equal_range(const key_type& __key);
-
- pair<const_iterator, const_iterator>
- equal_range(const key_type& __key) const;
-
- size_type
- erase(const key_type& __key);
-
- void
- erase(const iterator& __it);
-
- void
- erase(iterator __first, iterator __last);
-
- void
- erase(const const_iterator& __it);
-
- void
- erase(const_iterator __first, const_iterator __last);
-
- void
- resize(size_type __num_elements_hint);
-
- void
- clear();
-
- private:
- size_type
- _M_next_size(size_type __n) const
- { return __stl_next_prime(__n); }
-
- void
- _M_initialize_buckets(size_type __n)
- {
- const size_type __n_buckets = _M_next_size(__n);
- _M_buckets.reserve(__n_buckets);
- _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
- _M_num_elements = 0;
- __profcxx_hashtable_construct(this, __n_buckets);
- __profcxx_hashtable_construct2(this);
- }
-
- size_type
- _M_bkt_num_key(const key_type& __key) const
- { return _M_bkt_num_key(__key, _M_buckets.size()); }
-
- size_type
- _M_bkt_num(const value_type& __obj) const
- { return _M_bkt_num_key(_M_get_key(__obj)); }
-
- size_type
- _M_bkt_num_key(const key_type& __key, size_t __n) const
- { return _M_hash(__key) % __n; }
-
- size_type
- _M_bkt_num(const value_type& __obj, size_t __n) const
- { return _M_bkt_num_key(_M_get_key(__obj), __n); }
-
- _Node*
- _M_new_node(const value_type& __obj)
- {
- _Node* __n = _M_get_node();
- __n->_M_next = 0;
- try
- {
- this->get_allocator().construct(&__n->_M_val, __obj);
- return __n;
- }
- catch(...)
- {
- _M_put_node(__n);
- __throw_exception_again;
- }
- }
-
- void
- _M_delete_node(_Node* __n)
- {
- this->get_allocator().destroy(&__n->_M_val);
- _M_put_node(__n);
- }
-
- void
- _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
-
- void
- _M_erase_bucket(const size_type __n, _Node* __last);
-
- void
- _M_copy_from(const hashtable& __ht);
- };
-
- template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
- _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
- _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
- operator++()
- {
- const _Node* __old = _M_cur;
- _M_cur = _M_cur->_M_next;
- if (!_M_cur)
- {
- size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
- while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
- _M_cur = _M_ht->_M_buckets[__bucket];
- }
- return *this;
- }
-
- template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
- inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
- _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
- operator++(int)
- {
- iterator __tmp = *this;
- ++*this;
- return __tmp;
- }
-
- template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
- _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
- _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
- operator++()
- {
- const _Node* __old = _M_cur;
- _M_cur = _M_cur->_M_next;
- if (!_M_cur)
- {
- size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
- while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
- _M_cur = _M_ht->_M_buckets[__bucket];
- }
- return *this;
- }
-
- template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
- inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
- _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
- operator++(int)
- {
- const_iterator __tmp = *this;
- ++*this;
- return __tmp;
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- bool
- operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
- {
- typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
-
- if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
- return false;
-
- for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
- {
- _Node* __cur1 = __ht1._M_buckets[__n];
- _Node* __cur2 = __ht2._M_buckets[__n];
- // Check same length of lists
- for (; __cur1 && __cur2;
- __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
- { }
- if (__cur1 || __cur2)
- return false;
- // Now check one's elements are in the other
- for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
- __cur1 = __cur1->_M_next)
- {
- bool _found__cur1 = false;
- for (__cur2 = __ht2._M_buckets[__n];
- __cur2; __cur2 = __cur2->_M_next)
- {
- if (__cur1->_M_val == __cur2->_M_val)
- {
- _found__cur1 = true;
- break;
- }
- }
- if (!_found__cur1)
- return false;
- }
- }
- return true;
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- inline bool
- operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
- { return !(__ht1 == __ht2); }
-
- template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
- class _All>
- inline void
- swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
- hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
- { __ht1.swap(__ht2); }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- insert_unique_noresize(const value_type& __obj)
- {
- const size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- return pair<iterator, bool>(iterator(__cur, this), false);
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return pair<iterator, bool>(iterator(__tmp, this), true);
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- insert_equal_noresize(const value_type& __obj)
- {
- const size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- {
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __cur->_M_next;
- __cur->_M_next = __tmp;
- ++_M_num_elements;
- return iterator(__tmp, this);
- }
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return iterator(__tmp, this);
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- find_or_insert(const value_type& __obj)
- {
- resize(_M_num_elements + 1);
-
- size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- return __cur->_M_val;
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return __tmp->_M_val;
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- equal_range(const key_type& __key)
- {
- typedef pair<iterator, iterator> _Pii;
- const size_type __n = _M_bkt_num_key(__key);
-
- for (_Node* __first = _M_buckets[__n]; __first;
- __first = __first->_M_next)
- if (_M_equals(_M_get_key(__first->_M_val), __key))
- {
- for (_Node* __cur = __first->_M_next; __cur;
- __cur = __cur->_M_next)
- if (!_M_equals(_M_get_key(__cur->_M_val), __key))
- return _Pii(iterator(__first, this), iterator(__cur, this));
- for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
- if (_M_buckets[__m])
- return _Pii(iterator(__first, this),
- iterator(_M_buckets[__m], this));
- return _Pii(iterator(__first, this), end());
- }
- return _Pii(end(), end());
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- equal_range(const key_type& __key) const
- {
- typedef pair<const_iterator, const_iterator> _Pii;
- const size_type __n = _M_bkt_num_key(__key);
-
- for (const _Node* __first = _M_buckets[__n]; __first;
- __first = __first->_M_next)
- {
- if (_M_equals(_M_get_key(__first->_M_val), __key))
- {
- for (const _Node* __cur = __first->_M_next; __cur;
- __cur = __cur->_M_next)
- if (!_M_equals(_M_get_key(__cur->_M_val), __key))
- return _Pii(const_iterator(__first, this),
- const_iterator(__cur, this));
- for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
- if (_M_buckets[__m])
- return _Pii(const_iterator(__first, this),
- const_iterator(_M_buckets[__m], this));
- return _Pii(const_iterator(__first, this), end());
- }
- }
- return _Pii(end(), end());
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- erase(const key_type& __key)
- {
- const size_type __n = _M_bkt_num_key(__key);
- _Node* __first = _M_buckets[__n];
- size_type __erased = 0;
-
- if (__first)
- {
- _Node* __cur = __first;
- _Node* __next = __cur->_M_next;
- while (__next)
- {
- if (_M_equals(_M_get_key(__next->_M_val), __key))
- {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- __next = __cur->_M_next;
- ++__erased;
- --_M_num_elements;
- }
- else
- {
- __cur = __next;
- __next = __cur->_M_next;
- }
- }
- if (_M_equals(_M_get_key(__first->_M_val), __key))
- {
- _M_buckets[__n] = __first->_M_next;
- _M_delete_node(__first);
- ++__erased;
- --_M_num_elements;
- }
- }
- return __erased;
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- erase(const iterator& __it)
- {
- _Node* __p = __it._M_cur;
- if (__p)
- {
- const size_type __n = _M_bkt_num(__p->_M_val);
- _Node* __cur = _M_buckets[__n];
-
- if (__cur == __p)
- {
- _M_buckets[__n] = __cur->_M_next;
- _M_delete_node(__cur);
- --_M_num_elements;
- }
- else
- {
- _Node* __next = __cur->_M_next;
- while (__next)
- {
- if (__next == __p)
- {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- --_M_num_elements;
- break;
- }
- else
- {
- __cur = __next;
- __next = __cur->_M_next;
- }
- }
- }
- }
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- erase(iterator __first, iterator __last)
- {
- size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
- : _M_buckets.size();
-
- size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
- : _M_buckets.size();
-
- if (__first._M_cur == __last._M_cur)
- return;
- else if (__f_bucket == __l_bucket)
- _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
- else
- {
- _M_erase_bucket(__f_bucket, __first._M_cur, 0);
- for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
- _M_erase_bucket(__n, 0);
- if (__l_bucket != _M_buckets.size())
- _M_erase_bucket(__l_bucket, __last._M_cur);
- }
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- inline void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- erase(const_iterator __first, const_iterator __last)
- {
- erase(iterator(const_cast<_Node*>(__first._M_cur),
- const_cast<hashtable*>(__first._M_ht)),
- iterator(const_cast<_Node*>(__last._M_cur),
- const_cast<hashtable*>(__last._M_ht)));
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- inline void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- erase(const const_iterator& __it)
- { erase(iterator(const_cast<_Node*>(__it._M_cur),
- const_cast<hashtable*>(__it._M_ht))); }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- resize(size_type __num_elements_hint)
- {
- const size_type __old_n = _M_buckets.size();
- if (__num_elements_hint > __old_n)
- {
- const size_type __n = _M_next_size(__num_elements_hint);
- if (__n > __old_n)
- {
- _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
- try
- {
- for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
- {
- _Node* __first = _M_buckets[__bucket];
- while (__first)
- {
- size_type __new_bucket = _M_bkt_num(__first->_M_val,
- __n);
- _M_buckets[__bucket] = __first->_M_next;
- __first->_M_next = __tmp[__new_bucket];
- __tmp[__new_bucket] = __first;
- __first = _M_buckets[__bucket];
- }
- }
- _M_buckets.swap(__tmp);
- }
- catch(...)
- {
- for (size_type __bucket = 0; __bucket < __tmp.size();
- ++__bucket)
- {
- while (__tmp[__bucket])
- {
- _Node* __next = __tmp[__bucket]->_M_next;
- _M_delete_node(__tmp[__bucket]);
- __tmp[__bucket] = __next;
- }
- }
- __throw_exception_again;
- }
- __profcxx_hashtable_resize(this, __num_elements_hint, __n);
- }
- }
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
- {
- _Node* __cur = _M_buckets[__n];
- if (__cur == __first)
- _M_erase_bucket(__n, __last);
- else
- {
- _Node* __next;
- for (__next = __cur->_M_next;
- __next != __first;
- __cur = __next, __next = __cur->_M_next)
- ;
- while (__next != __last)
- {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- __next = __cur->_M_next;
- --_M_num_elements;
- }
- }
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- _M_erase_bucket(const size_type __n, _Node* __last)
- {
- _Node* __cur = _M_buckets[__n];
- while (__cur != __last)
- {
- _Node* __next = __cur->_M_next;
- _M_delete_node(__cur);
- __cur = __next;
- _M_buckets[__n] = __cur;
- --_M_num_elements;
- }
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- clear()
- {
- size_type __hops=0, __lc = 0, __chain = 0;
- if (_M_num_elements != 0)
- __profcxx_hashtable_destruct(this, _M_buckets.size(), _M_num_elements);
-
- for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
- {
- _Node* __cur = _M_buckets[__i];
- while (__cur != 0)
- {
- _Node* __next = __cur->_M_next;
- _M_delete_node(__cur);
- __cur = __next;
-
- // Compute the longest chain count.
- __chain++;
- }
- _M_buckets[__i] = 0;
-
- // Collect number of hops.
- if (__chain > 1) {
- __lc = __lc > __chain ? __lc : __chain;
- __hops += (__chain-1) * __chain / 2;
- }
- __chain = 0;
- }
- if (_M_num_elements) {
- __profcxx_hashtable_destruct2(this, __lc, _M_num_elements, __hops);
- }
- _M_num_elements = 0;
- }
-
- template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
- void
- hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
- _M_copy_from(const hashtable& __ht)
- {
- _M_buckets.clear();
- _M_buckets.reserve(__ht._M_buckets.size());
- _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
- try
- {
- for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
- const _Node* __cur = __ht._M_buckets[__i];
- if (__cur)
- {
- _Node* __local_copy = _M_new_node(__cur->_M_val);
- _M_buckets[__i] = __local_copy;
-
- for (_Node* __next = __cur->_M_next;
- __next;
- __cur = __next, __next = __cur->_M_next)
- {
- __local_copy->_M_next = _M_new_node(__next->_M_val);
- __local_copy = __local_copy->_M_next;
- }
- }
- }
- _M_num_elements = __ht._M_num_elements;
- }
- catch(...)
- {
- clear();
- __throw_exception_again;
- }
- }
-
-_GLIBCXX_END_NAMESPACE
-
-#endif
diff --git a/libstdc++-v3/include/profile/impl/profiler.h b/libstdc++-v3/include/profile/impl/profiler.h
index c9db6cde4c3..81d8dbad462 100644
--- a/libstdc++-v3/include/profile/impl/profiler.h
+++ b/libstdc++-v3/include/profile/impl/profiler.h
@@ -43,6 +43,20 @@
#include <stddef.h>
#endif
+// Mechanism to define data with inline linkage.
+#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 std::__cxxprof_guard
+ * @brief Mechanism to protect all __gnu_profile operations against
+ * multithreaded and exception reentrance.
+ */
namespace __gnu_profile
{
/** @brief Reentrance guard.
@@ -53,80 +67,127 @@ namespace __gnu_profile
struct __reentrance_guard
{
static bool
- _S_set_in()
+ __get_in()
{
- if (_S_get_in())
+ if (__inside() == true)
return false;
else
{
- _S_get_in() = true;
+ __inside() = true;
return true;
}
}
static bool&
- _S_get_in()
+ __inside()
{
static __thread bool _S_inside(false);
return _S_inside;
}
__reentrance_guard() { }
- ~__reentrance_guard() { _S_get_in() = false; }
+ ~__reentrance_guard() { __inside() = false; }
};
#define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...) \
{ \
- if (__gnu_profile::__reentrance_guard::_S_get_in()) \
+ if (__gnu_profile::__reentrance_guard::__get_in()) \
{ \
__gnu_profile::__reentrance_guard __get_out; \
__x; \
} \
}
+}
+
+/**
+ * @namespace std::__gnu_profile
+ * @brief Implementation of profile extension.
+ */
+namespace __gnu_profile
+{
+// 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*, 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_vector_to_list_find(const void*, 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*, size_t, size_t);
+void __trace_list_to_vector_iterate(const void*, size_t);
+void __trace_list_to_vector_invalid_operator(const void*);
+void __trace_list_to_vector_resize(const void*, size_t, 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*, size_t, size_t);
+void __trace_list_to_set_iterate(const void*, size_t);
+void __trace_list_to_set_invalid_operator(const void*);
+void __trace_list_to_set_find(const void*, size_t);
- // Forward declarations of implementation functions.
- // Don't use any __gnu_profile:: 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*);
+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 __gnu_profile
-// Master switch turns on all diagnostics.
+// 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
@@ -152,10 +213,8 @@ namespace __gnu_profile
#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)))
+#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))
@@ -166,16 +225,14 @@ namespace __gnu_profile
_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...)
+#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)))
+#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))
@@ -186,14 +243,13 @@ namespace __gnu_profile
_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
+#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))
+#if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
#define __profcxx_hashtable_construct2(__x...) \
_GLIBCXX_PROFILE_REENTRANCE_GUARD( \
__gnu_profile::__trace_hash_func_construct(__x))
@@ -201,13 +257,12 @@ namespace __gnu_profile
_GLIBCXX_PROFILE_REENTRANCE_GUARD( \
__gnu_profile::__trace_hash_func_destruct(__x))
#else
-#define __profcxx_hashtable_destruct2(__x...)
-#define __profcxx_hashtable_construct2(__x...)
+#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))
+#if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
#define __profcxx_vector_construct2(__x...) \
_GLIBCXX_PROFILE_REENTRANCE_GUARD( \
__gnu_profile::__trace_vector_to_list_construct(__x))
@@ -226,6 +281,9 @@ namespace __gnu_profile
#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...)
@@ -233,11 +291,57 @@ namespace __gnu_profile
#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) \
- && !defined(_NO_GLIBCXX_PROFILE_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))
@@ -261,7 +365,7 @@ namespace __gnu_profile
__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...)
@@ -271,7 +375,7 @@ namespace __gnu_profile
#endif
// Run multithreaded unless instructed not to do so.
-#ifndef _GLIBCXX_PROFILE_NOTHREADS
+#ifndef _GLIBCXX_PROFILE_NO_THREADS
#define _GLIBCXX_PROFILE_THREADS
#endif
@@ -280,11 +384,11 @@ namespace __gnu_profile
#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"
+#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"
+ "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
#endif
#ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
#define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
@@ -294,14 +398,14 @@ namespace __gnu_profile
#endif
#ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
#define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
- "GLIBCXX_PROFILE_MAX_STACK_DEPTH"
+ "_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"
+ "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
#endif
// Instrumentation hook implementations.
@@ -310,5 +414,7 @@ namespace __gnu_profile
#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_container_size.h b/libstdc++-v3/include/profile/impl/profiler_container_size.h
index 71f5556fa93..bfbab85199b 100644
--- a/libstdc++-v3/include/profile/impl/profiler_container_size.h
+++ b/libstdc++-v3/include/profile/impl/profiler_container_size.h
@@ -47,214 +47,196 @@
#include <string.h>
#endif
+#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();
- __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;
- }
+/** @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
+{
+ std::stringstream __message;
+ if (_M_init < _M_item_max)
+ __message << "change initial container size from " << _M_init
+ << " to " << _M_item_max;
- 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);
- }
+ return strdup(__message.str().c_str());
+}
- 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 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 __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(__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::__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)
+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;
- }
+{
+ _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));
+}
- /** @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_base<__container_size_info, __container_size_stack_info>() { };
-
- ~__trace_container_size() { }
-
- // 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 __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;
+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);
+ __object_t __obj_handle = static_cast<__object_t>(__obj);
- __container_size_info* __object_info = __get_object_info(__obj_handle);
- if (!__object_info)
- return;
+ __container_size_info* __object_info = __get_object_info(__obj_handle);
+ if (!__object_info)
+ return;
- __object_info->__destruct(__num, __inum);
- __retire_object(__obj_handle);
- }
+ __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;
+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;
+ __container_size_info* __object_info = __get_object_info(__obj);
+ if (!__object_info)
+ return;
+
+ __object_info->__resize(__from, __to);
+}
- __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
index 86859e5601a..95fad192590 100644
--- a/libstdc++-v3/include/profile/impl/profiler_hash_func.h
+++ b/libstdc++-v3/include/profile/impl/profiler_hash_func.h
@@ -52,143 +52,134 @@
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);
-
- __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;
- }
+/** @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 strdup("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::__destruct(size_t __chain, size_t __accesses, size_t __hops)
- {
- _M_longest_chain = __max(_M_longest_chain, __chain);
- _M_accesses += __accesses;
- _M_hops += __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";
+}
- /** @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);
- }
+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);
+}
- // Initialization and report.
- inline void
- __trace_hash_func_init()
- { __tables<0>::_S_hash_func = new __trace_hash_func(); }
+inline void __trace_hash_func::__destruct(const void* __obj, size_t __chain,
+ size_t __accesses, size_t __hops)
+{
+ if (!__is_on()) return;
- 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);
- }
- }
+ // 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);
+}
- // Implementations of instrumentation hooks.
- inline void
- __trace_hash_func_construct(const void* __obj)
- {
- if (!__profcxx_init())
- return;
+inline void __trace_hash_func_init()
+{
+ _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func();
+}
- __tables<0>::_S_hash_func->__insert(__obj, __get_stack());
+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_destruct(const void* __obj, size_t __chain,
- size_t __accesses, size_t __hops)
- {
- if (!__profcxx_init())
- return;
+inline void __trace_hash_func_construct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
- __tables<0>::_S_hash_func->__destruct(__obj, __chain, __accesses, __hops);
- }
+ _GLIBCXX_PROFILE_DATA(_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;
+
+ _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
index da89c071138..8248f47e75d 100644
--- a/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
+++ b/libstdc++-v3/include/profile/impl/profiler_hashtable_size.h
@@ -54,57 +54,54 @@
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"; }
- };
-
- // 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)
+
+/** @brief Hashtable size instrumentation trace producer. */
+class __trace_hashtable_size : public __trace_container_size
+{
+ public:
+ __trace_hashtable_size() : __trace_container_size()
{
- if (__tables<0>::_S_hashtable_size)
- {
- __tables<0>::_S_hashtable_size->__collect_warnings(__warnings);
- __tables<0>::_S_hashtable_size->__write(__f);
- }
+ __id = "hashtable-size";
}
+};
- // Implementations of instrumentation hooks.
- inline void
- __trace_hashtable_size_construct(const void* __obj, size_t __num)
- {
- if (!__profcxx_init())
- return;
+inline void __trace_hashtable_size_init()
+{
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size();
+}
- __tables<0>::_S_hashtable_size->__insert(__obj, __get_stack(), __num);
+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_destruct(const void* __obj, size_t __num,
- size_t __inum)
- {
- if (!__profcxx_init())
- return;
+inline void __trace_hashtable_size_construct(const void* __obj, 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, size_t __num,
+ size_t __inum)
+{
+ if (!__profcxx_init()) return;
- __tables<0>::_S_hashtable_size->__destruct(__obj, __num, __inum);
- }
+ _GLIBCXX_PROFILE_DATA(_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;
+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);
- }
+ _GLIBCXX_PROFILE_DATA(_S_hashtable_size)->__resize(__obj, __from, __to);
+}
} // namespace __gnu_profile
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 00000000000..073bdf27587
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h
@@ -0,0 +1,182 @@
+// -*- 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_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
+
+#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 __gnu_profile
+{
+
+class __list2slist_info: public __object_info_base
+{
+ public:
+ __list2slist_info() : _M_rewind(false), _M_operations(0) {}
+ __list2slist_info(__stack_t __stack)
+ : _M_rewind(false), _M_operations(0),__object_info_base(__stack) {}
+ 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& __o) {};
+ void __write(FILE* __f) const;
+ const char* __advice() const
+ { return strdup("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;
+ 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);
+ void __record_operation(const void* __obj);
+ void __insert(const __object_t __obj, __stack_t __stack)
+ { __add_object(__obj, __list2slist_info(__stack)); }
+ void __destruct(const void* __obj);
+};
+
+inline void __list2slist_info::__write(FILE* __f) const
+{
+ fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid");
+}
+
+inline void __trace_list_to_slist::__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::__opr_rewind(const void* __obj)
+{
+ __list2slist_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_rewind();
+}
+
+inline void __trace_list_to_slist::__record_operation(const void* __obj)
+{
+ __list2slist_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__record_operation();
+}
+
+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 00000000000..d3a3713954c
--- /dev/null
+++ b/libstdc++-v3/include/profile/impl/profiler_list_to_vector.h
@@ -0,0 +1,313 @@
+// -*- 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_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
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+#include <string>
+#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);
+ void __merge(const __list2vector_info& __o);
+ void __write(FILE* __f) const;
+ float __magnitude() const { return _M_list_cost - _M_vector_cost; }
+ const char* __advice() const;
+ 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 __shift, size_t __size);
+ 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;
+ size_t _M_max_size;
+};
+
+inline __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_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 = __o._M_max_size;
+}
+
+inline const char* __list2vector_info::__advice() const {
+ std::stringstream __sstream;
+ __sstream
+ << "change std::list to std::vector and its initial size from 0 to "
+ << _M_max_size;
+ return strdup(__sstream.str().c_str());
+}
+
+inline void __list2vector_info::__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 = __max( _M_max_size, __o._M_max_size);
+}
+
+inline void __list2vector_info::__opr_insert(size_t __shift, size_t __size)
+{
+ _M_shift_count += __shift;
+ _M_max_size = __max(_M_max_size, __size);
+}
+
+inline void __list2vector_info::__resize(size_t __from, size_t __to)
+{
+ _M_resize += __from;
+}
+
+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_list_to_vector() {}
+
+ // 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.
+ __list2vector_info* __find(const void* __obj);
+
+ // Collect cost of operations.
+ void __opr_insert(const void* __obj, size_t __shift, size_t __size);
+ 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);
+ float __list_cost(size_t __shift, size_t __iterate);
+};
+
+inline __trace_list_to_vector::__trace_list_to_vector()
+ : __trace_base<__list2vector_info, __list2vector_stack_info>()
+{
+ __id = "list-to-vector";
+}
+
+inline void __trace_list_to_vector::__insert(__object_t __obj,
+ __stack_t __stack)
+{
+ __add_object(__obj, __list2vector_info(__stack));
+}
+
+inline void __list2vector_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);
+}
+
+inline float __trace_list_to_vector::__vector_cost(size_t __shift,
+ 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;
+}
+
+inline float __trace_list_to_vector::__list_cost(size_t __shift,
+ 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::__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);
+}
+
+inline void __trace_list_to_vector::__opr_insert(const void* __obj,
+ size_t __shift, size_t __size)
+{
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__opr_insert(__shift, __size);
+}
+
+inline void __trace_list_to_vector::__opr_iterate(const void* __obj,
+ size_t __num)
+{
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res) {
+ __res->__opr_iterate(__num);
+ }
+}
+
+inline void __trace_list_to_vector::__invalid_operator(const void* __obj)
+{
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+}
+
+inline void __trace_list_to_vector::__resize(const void* __obj, size_t __from,
+ size_t __to)
+{
+ __list2vector_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+}
+
+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,
+ size_t __shift, 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, 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,
+ size_t __from, 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
index 6c90e7a0377..e715e4cd467 100644
--- a/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
+++ b/libstdc++-v3/include/profile/impl/profiler_map_to_unordered_map.h
@@ -52,275 +52,241 @@
namespace __gnu_profile
{
- // Cost model.
- // 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
- // XXX: this must be taken from the machine model instead.
- 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)
+
+inline int __log2(size_t __size)
+{
+ for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; -- __bit_count)
{
- int __bit_count = sizeof(size_t) - 1;
- for (; __bit_count >= 0; --__bit_count)
- {
- if ((2 << __bit_count) & __size)
- return __bit_count;
- }
- return 0;
+ 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)); }
+inline float __map_insert_cost(size_t __size)
+{
+ return (_GLIBCXX_PROFILE_DATA(__map_insert_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_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 __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 const char*
- __map2umap_info::__advice() const
- { return "change std::map to std::unordered_map"; }
-
- 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 float __map_erase_cost(size_t __size)
+{
+ return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
+ * static_cast<float>(__log2(__size)));
+}
- 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 float __map_find_cost(size_t __size)
+{
+ return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
+ * static_cast<float>(__log2(__size)));
+}
- 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;
- }
+/** @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 strdup("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
+ * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
+}
- 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_erase(size_t __size, 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);
+}
- 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_find(size_t __size)
+{
+ _M_find += 1;
+ _M_map_cost += __map_find_cost(__size);
+ _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
+}
- inline void
- __map2umap_info:: __record_invalidate()
- {
- _M_valid = false;
- }
+inline void __map2umap_info:: __record_iterate(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);
+}
+
+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");
- }
+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 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();
- };
+/** @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 __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_init()
+{
+ _GLIBCXX_PROFILE_DATA(_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);
- }
+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);
}
+}
- // Implementations of instrumentation hooks.
- inline void
- __trace_map_to_unordered_map_construct(const void* __obj)
- {
- if (!__profcxx_init())
- return;
+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()));
- }
+ _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;
+inline void __trace_map_to_unordered_map_destruct(const void* __obj)
+{
+ if (!__profcxx_init()) return;
- __tables<0>::_S_map2umap->__retire_object(__obj);
- }
+ _GLIBCXX_PROFILE_DATA(_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;
+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);
+ __map2umap_info* __info =
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
- if (__info)
- __info->__record_insert(__size, __count);
- }
+ 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;
+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);
+ __map2umap_info* __info =
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
- if (__info)
- __info->__record_erase(__size, __count);
- }
+ 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;
+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);
+ __map2umap_info* __info =
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
- if (__info)
- __info->__record_find(__size);
- }
+ if (__info) __info->__record_find(__size);
+}
- inline void
- __trace_map_to_unordered_map_iterate(const void* __obj, size_t __count)
- {
- if (!__profcxx_init())
- return;
+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);
+ __map2umap_info* __info =
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
- if (__info)
- __info->__record_iterate(__count);
- }
+ if (__info) __info->__record_iterate(__count);
+}
- inline void
- __trace_map_to_unordered_map_invalidate(const void* __obj)
- {
- if (!__profcxx_init())
- return;
+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);
+ __map2umap_info* __info =
+ _GLIBCXX_PROFILE_DATA(_S_map2umap)->__get_object_info(__obj);
- if (__info)
- __info->__record_invalidate();
- }
+ 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
index 66101a7ef71..77654a8f813 100644
--- a/libstdc++-v3/include/profile/impl/profiler_node.h
+++ b/libstdc++-v3/include/profile/impl/profiler_node.h
@@ -47,122 +47,126 @@
#include <string.h>
#endif
#include <vector>
-#if defined HAVE_EXECINFO_H
+#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_PR::vector<__instruction_address_t> __stack_npt;
- typedef __stack_npt* __stack_t;
+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();
+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
+inline __stack_t __get_stack()
+{
+#if defined _GLIBCXX_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 __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);
}
+}
- inline void __write(FILE* __f, const __stack_t __stack)
+/** @brief Hash function for summary trace using call stack as index. */
+class __stack_hash
+{
+ public:
+ size_t operator()(const __stack_t __s) const
{
- if (!__stack)
- return;
+ if (!__s) {
+ return 0;
+ }
+ uintptr_t __index = 0;
__stack_npt::const_iterator __it;
- for (__it = __stack->begin(); __it != __stack->end(); ++__it)
- fprintf(__f, "%p ", *__it);
+ for (__it = __s->begin(); __it != __s->end(); ++__it) {
+ __index += reinterpret_cast<uintptr_t>(*__it);
+ }
+ return __index;
}
- /** @brief Hash function for summary trace using call stack as index. */
- class __stack_hash
+ bool operator() (const __stack_t __stack1, const __stack_t __stack2) const
{
- 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;
- }
+ if (!__stack1 && !__stack2) return true;
+ if (!__stack1 || !__stack2) return false;
+ if (__stack1->size() != __stack2->size()) return false;
- 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;
+ }
+};
- 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;
+}
- /** @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;
+}
- 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;
+};
- /** @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
index 347b5e248b0..540c3e4bf0c 100644
--- a/libstdc++-v3/include/profile/impl/profiler_state.h
+++ b/libstdc++-v3/include/profile/impl/profiler_state.h
@@ -37,72 +37,34 @@
#ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H
#define _GLIBCXX_PROFILE_PROFILER_STATE_H 1
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-#include <cstdio>
-#else
-#include <stdio.h>
-#endif
-
namespace __gnu_profile
{
- /** @brief Profiling mode on/off state. */
- template<int _Unused=0>
- class __state
- {
- private:
- enum __state_type { __ON, __OFF, __INVALID };
-
- __state_type _M_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; }
- };
-
- 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();
- }
+
+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
index 173b647421b..75126774d5b 100644
--- a/libstdc++-v3/include/profile/impl/profiler_trace.h
+++ b/libstdc++-v3/include/profile/impl/profiler_trace.h
@@ -54,9 +54,17 @@
#endif
#include <algorithm>
+#include <fstream>
+#include <string>
#include <utility>
-#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+#if (defined _GLIBCXX_PROFILE_THREADS) && !(defined _GLIBCXX_HAVE_TLS)
+#error You do not seem to have TLS support, which is required by the profile \
+ mode. If your program is not multithreaded, recompile with \
+ -D_GLIBCXX_PROFILE_NO_THREADS
+#endif
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined _GLIBCXX_HAVE_TLS
#include <pthread.h>
#endif
@@ -65,528 +73,611 @@
namespace __gnu_profile
{
-#if defined _GLIBCXX_PROFILE_THREADS && defined HAVE_TLS
+
+#if defined _GLIBCXX_PROFILE_THREADS && defined _GLIBCXX_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); }
- };
+typedef pthread_mutex_t __mutex_t;
+/** @brief Pthread mutex wrapper. */
+_GLIBCXX_PROFILE_DEFINE_DATA(__mutex_t, __global_lock,
+ PTHREAD_MUTEX_INITIALIZER);
+inline void __lock(__mutex_t& __m) { pthread_mutex_lock(&__m); }
+inline void __unlock(__mutex_t& __m) { pthread_mutex_unlock(&__m); }
#else
+typedef int __mutex_t;
+/** @brief Mock mutex interface. */
#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) { }
- };
+_GLIBCXX_PROFILE_DEFINE_DATA(__mutex_t, __global_lock, 0);
+inline void __lock(__mutex_t& __m) {}
+inline 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)
+{
+}
- /** @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()));
- }
- }
+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)
+{
+}
- 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;
- __stack_table_lock = _GLIBCXX_IMPL_MUTEX_INITIALIZER;
- __object_table_lock = __stack_table_lock;
- }
+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;
+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&);
+
+// Utility functions.
+inline size_t __max(size_t __a, size_t __b)
+{
+ return __a >= __b ? __a : __b;
+}
- template<typename __object_info, typename __stack_info>
- void
- __trace_base<__object_info, __stack_info>::__add_object(__object_t __object, __object_info __info)
+inline size_t __min(size_t __a, size_t __b)
+{
+ return __a <= __b ? __a : __b;
+}
+
+struct __cost_factor
+{
+ const char* __env_var;
+ float __value;
+};
+
+typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
+
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, NULL);
+_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, NULL);
+
+_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, NULL);
+
+_GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
+ _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
+ _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
+_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
+ _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
+
+inline size_t __stack_max_depth()
+{
+ return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
+}
+
+inline 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:
+ __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 )
{
- typedef typename __object_table_t::value_type value_type;
- if (__max_mem() == 0
- || __object_table.size() * sizeof(__object_info) <= __max_mem())
- {
- __lock_object_table();
- __object_table.insert(value_type(__object, __info));
- __unlock_object_table();
- }
+ __warnings.push_back(__warning_data((*__i).second.__magnitude(),
+ (*__i).first,
+ __id,
+ (*__i).second.__advice()));
}
+}
- 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);
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__lock_object_table()
+{
+ __lock(this->__object_table_lock);
+}
- 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>::__lock_stack_table()
+{
+ __lock(this->__stack_table_lock);
+}
- 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);
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_object_table()
+{
+ __unlock(this->__object_table_lock);
+}
- 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();
+template <typename __object_info, typename __stack_info>
+void __trace_base<__object_info, __stack_info>::__unlock_stack_table()
+{
+ __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>
- 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, "|");
- __gnu_profile::__write(__f, __it->first);
- fprintf(__f, "|");
- __it->second.__write(__f);
- }
- }
+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;
}
+}
- 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;
+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();
+}
- 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);
+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, "|");
+ __gnu_profile::__write(__f, __it->first);
+ fprintf(__f, "|");
+ __it->second.__write(__f);
+ }
}
+}
- 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 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'.\n", __env_var);
+ abort();
+ } else {
+ return static_cast<size_t>(__converted_value);
+ }
+ } else {
+ return __default_value;
}
+}
- 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 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;
+}
- struct __warn
+struct __warn
+{
+ FILE* __file;
+ __warn(FILE* __f) { __file = __f; }
+ void operator() (const __warning_data& __info)
{
- 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 = ");
- __gnu_profile::__write(__file, __info.__context);
- fprintf(__file, ": advice = %s\n", __info.__warning_message);
- }
- };
+ fprintf(__file, __info.__warning_id);
+ fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude));
+ fprintf(__file, ": call stack = ");
+ __gnu_profile::__write(__file, __info.__context);
+ fprintf(__file, ": advice = %s\n", __info.__warning_message);
+ free(
+ const_cast<void*>(
+ reinterpret_cast<const void*>(__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();
- }
+inline FILE* __open_output_file(const char* extension)
+{
+ // The path is made of _S_trace_file_name + "." + extension.
+ size_t root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
+ size_t ext_len = strlen(extension);
+ char* file_name = new char[root_len + 1 + ext_len + 1];
+ memcpy(file_name, _GLIBCXX_PROFILE_DATA(_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'.\n", 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
+ * __gnu_profile (under the guarded zone), no output will be produced.
+ */
+inline void __report(void)
+{
+ __lock(_GLIBCXX_PROFILE_DATA(__global_lock));
- /** @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
- * __gnu_profile (under the guarded zone), no output will be produced.
- */
- inline void
- __report(void)
- {
- __mutex<0>::__lock(__mutex<0>::__global_lock);
+ __warning_vector_t __warnings;
- __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_list_to_slist_report(__raw_file, __warnings);
+ __trace_list_to_vector_report(__raw_file, __warnings);
+ __trace_map_to_unordered_map_report(__raw_file, __warnings);
+ fclose(__raw_file);
- 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(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
+ __warnings.size());
- // Sort data by magnitude.
+ std::sort(__warnings.begin(), __warnings.end(),
+ std::greater<__warning_vector_t::value_type>());
+ __warnings.resize(__cutoff);
- // XXX: instead of sorting, should collect only top N for better
- // performance.
- size_t __cutoff = __min(__settings<0>::_S_max_warn_count,
- __warnings.size());
+ FILE* __warn_file = __open_output_file("txt");
+ std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
+ fclose(__warn_file);
- std::sort(__warnings.begin(), __warnings.end(),
- std::greater<__warning_vector_t::value_type>());
- __warnings.resize(__cutoff);
+ __unlock(_GLIBCXX_PROFILE_DATA(__global_lock));
+}
- FILE* __warn_file = __open_output_file("txt");
- std::for_each(__warnings.begin(), __warnings.end(), __warn(__warn_file));
- fclose(__warn_file);
+inline void __set_trace_path()
+{
+ char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
- __mutex<0>::__unlock(__mutex<0>::__global_lock);
+ if (__env_trace_file_name) {
+ _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
}
- inline void
- __set_trace_path()
- {
- char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
+ // Make sure early that we can create the trace file.
+ fclose(__open_output_file("txt"));
+}
- if (__env_trace_file_name)
- __settings<0>::_S_trace_file_name = __env_trace_file_name;
+inline void __set_max_warn_count()
+{
+ char* __env_max_warn_count_str = getenv(
+ _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
- // Make sure early that we can create the trace file.
- fclose(__open_output_file("txt"));
+ if (__env_max_warn_count_str) {
+ _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast<size_t>(
+ atoi(__env_max_warn_count_str));
}
+}
- inline void
- __set_max_warn_count()
- {
- char* __env_max_warn_count_str = getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
+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 (getline(__conf_file, __line)) {
+ std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
- if (__env_max_warn_count_str)
- {
- int i = atoi(__env_max_warn_count_str);
- __settings<0>::_S_max_warn_count = static_cast<size_t>(i);
+ if (__line.length() <= 0 || __line[__i] == '#') {
+ // Skip empty lines or comments.
+ continue;
+ }
+
+ // Trim.
+ __line.erase(std::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);
+
+ setenv(__factor_name.c_str(), __factor_value.c_str(), 0);
}
+ }
+}
+
+struct __cost_factor_writer
+{
+ FILE* __file;
+ __cost_factor_writer(FILE* __f) : __file(__f) {}
+ void operator() (const __cost_factor* __factor)
+ {
+ fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value);
}
+};
- inline void
- __profcxx_init_unconditional()
+inline void __write_cost_factors()
+{
+ FILE* __file = __open_output_file("conf.out");
+ std::for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+ __cost_factor_writer(__file));
+ fclose(__file);
+}
+
+struct __cost_factor_setter
+{
+ void operator() (__cost_factor* __factor)
{
- __mutex<0>::__lock(__mutex<0>::__global_lock);
+ char* __env_cost_factor;
+ if (__env_cost_factor = getenv(__factor->__env_var))
+ __factor->__value = atof(__env_cost_factor);
+ }
+};
+
+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));
+ std::for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
+ _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
+ __cost_factor_setter());
+}
+
+inline void __profcxx_init_unconditional()
+{
+ __lock(_GLIBCXX_PROFILE_DATA(__global_lock));
+
+ if (__is_invalid()) {
__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();
- }
- }
+ 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();
+
+ 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();
+ __unlock(_GLIBCXX_PROFILE_DATA(__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 __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
index 151e5d4bfb7..8d630e4d90b 100644
--- a/libstdc++-v3/include/profile/impl/profiler_vector_size.h
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_size.h
@@ -54,49 +54,51 @@
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"; }
- };
-
- // 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);
- }
+/** @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_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_init()
+{
+ _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size();
+}
- 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);
+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, 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, size_t __num,
+ 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, size_t __from,
+ 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
index 45076f8eb79..d4113da8b4e 100644
--- a/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
+++ b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h
@@ -28,8 +28,8 @@
// 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.
+/** @file profile/impl/profiler_vector_to_list.h
+ * @brief diagnostics for vector to list.
*/
// Written by Lixia Liu and Silvius Rus.
@@ -52,258 +52,285 @@
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);
-
- 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;
- }
+/** @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 strdup("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);
+ void __resize(size_t __from, size_t __to);
+ void __opr_find(size_t __size);
+
+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::__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);
- }
+inline void __vector2list_info::__resize(size_t __from, size_t __to)
+{
+ _M_resize += __from;
+}
- // Cost model.
- // 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
- // XXX: get this from the cost model database instead.
- 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 __vector2list_info::__opr_iterate(size_t __num)
+{
+ _M_iterate += __num;
+}
- 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 __vector2list_info::__opr_find(size_t __size)
+{
+ // Use average case complexity.
+ _M_iterate += 3.0 / 4.0 * __size;
+}
+
+/** @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);
+ void __opr_find(const void* __obj, size_t __size);
+};
+
+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::__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::__insert(__object_t __obj,
+ __stack_t __stack)
+{
+ __add_object(__obj, __vector2list_info(__stack));
+}
- 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 __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);
+}
- 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);
- }
+inline float __trace_vector_to_list::__vector_cost(size_t __shift,
+ size_t __iterate,
+ 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
+ );
+}
+
+inline float __trace_vector_to_list::__list_cost(size_t __shift,
+ size_t __iterate,
+ 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);
+}
+inline void __trace_vector_to_list::__destruct(const void* __obj)
+{
+ if (!__is_on())
+ return;
- // Initialization and report.
- inline void
- __trace_vector_to_list_init()
- { __tables<0>::_S_vector_to_list = new __trace_vector_to_list(); }
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (!__res)
+ return;
- 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);
- }
- }
+ 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);
- // 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());
- }
+ __retire_object(__obj);
+}
- 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::__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_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::__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_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)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__set_invalid();
+}
- 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)
+{
+ __vector2list_info* __res = __get_object_info(__obj);
+ if (__res)
+ __res->__resize(__from, __to);
+}
+
+inline void __trace_vector_to_list::__opr_find(const void* __obj,
+ 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_resize(const void* __obj, size_t __from, size_t __to)
- {
- if (!__profcxx_init()) return;
- __tables<0>::_S_vector_to_list->__resize(__obj, __from, __to);
+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,
+ size_t __pos, 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, 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,
+ size_t __from, 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, 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 */
diff --git a/libstdc++-v3/include/profile/iterator_tracker.h b/libstdc++-v3/include/profile/iterator_tracker.h
new file mode 100644
index 00000000000..8e077481f34
--- /dev/null
+++ b/libstdc++-v3/include/profile/iterator_tracker.h
@@ -0,0 +1,273 @@
+#ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER
+#define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1
+
+#include <ext/type_traits.h>
+
+namespace std
+{
+namespace __profile
+{
+
+template<typename _Iterator, typename _Sequence>
+class __iterator_tracker
+{
+ typedef __iterator_tracker _Self;
+ // The underlying iterator
+ _Iterator _M_current;
+ // The underlying data structure
+ const _Sequence* _M_ds;
+ typedef std::iterator_traits<_Iterator> _Traits;
+
+ public:
+ typedef _Iterator _Base_iterator;
+ typedef typename _Traits::iterator_category iterator_category;
+ typedef typename _Traits::value_type value_type;
+ typedef typename _Traits::difference_type difference_type;
+ typedef typename _Traits::reference reference;
+ typedef typename _Traits::pointer pointer;
+
+ __iterator_tracker() : _M_current(), _M_ds(0) { }
+ __iterator_tracker(const _Iterator& __i, const _Sequence* seq)
+ : _M_current(__i), _M_ds(seq) { }
+ __iterator_tracker(const __iterator_tracker& __x)
+ : _M_current(__x._M_current), _M_ds(__x._M_ds) { }
+ template<typename _MutableIterator>
+ __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x)
+ : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { }
+
+ _Iterator
+ base() const { return _M_current; }
+ /**
+ * @brief Conversion to underlying non-debug iterator to allow
+ * better interaction with non-profile containers.
+ */
+ operator _Iterator() const { return _M_current; }
+
+ pointer
+ operator->() const { return &*_M_current; }
+
+ __iterator_tracker&
+ operator++()
+ {
+ _M_ds->_M_profile_iterate();
+ ++_M_current;
+ return *this;
+ }
+
+ __iterator_tracker&
+ operator++(int)
+ {
+ _M_ds->_M_profile_iterate();
+ __iterator_tracker __tmp(*this);
+ ++_M_current;
+ return __tmp;
+ }
+
+ __iterator_tracker&
+ operator--()
+ {
+ _M_ds->_M_profile_iterate(1);
+ --_M_current;
+ return *this;
+ }
+
+ __iterator_tracker&
+ operator--(int)
+ {
+ _M_ds->_M_profile_iterate(1);
+ __iterator_tracker __tmp(*this);
+ --_M_current;
+ return __tmp;
+ }
+
+ __iterator_tracker&
+ operator=(const __iterator_tracker& __x)
+ {
+ _M_current = __x._M_current;
+ return *this;
+ }
+
+ reference
+ operator*() const
+ {
+ return *_M_current;
+ }
+
+ // ------ Random access iterator requirements ------
+ reference
+ operator[](const difference_type& __n) const
+ {
+ return _M_current[__n];
+ }
+
+ __iterator_tracker&
+ operator+=(const difference_type& __n)
+ {
+ _M_current += __n;
+ return *this;
+ }
+
+ __iterator_tracker
+ operator+(const difference_type& __n) const
+ {
+ __iterator_tracker __tmp(*this);
+ __tmp += __n;
+ return __tmp;
+ }
+
+ __iterator_tracker&
+ operator-=(const difference_type& __n)
+ {
+ _M_current += -__n;
+ return *this;
+ }
+
+ __iterator_tracker
+ operator-(const difference_type& __n) const
+ {
+ __iterator_tracker __tmp(*this);
+ __tmp -= __n;
+ return __tmp;
+ }
+
+ void
+ _M_find()
+ {
+ _M_ds->_M_profile_find();
+ }
+
+ const _Sequence*
+ _M_get_sequence() const
+ {
+ return static_cast<const _Sequence*>(_M_ds);
+ }
+};
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() == __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() == __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() != __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() != __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() < __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() < __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() <= __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() <= __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() > __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() > __rhs.base();
+}
+
+template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+inline bool
+operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() >= __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline bool
+operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() >= __rhs.base();
+}
+
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// According to the resolution of DR179 not only the various comparison
+// operators but also operator- must accept mixed iterator/const_iterator
+// parameters.
+ template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+ inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type
+ operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs,
+ const __iterator_tracker<_IteratorR, _Sequence>& __rhs)
+{
+ return __lhs.base() - __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type
+operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs,
+ const __iterator_tracker<_Iterator, _Sequence>& __rhs)
+{
+ return __lhs.base() - __rhs.base();
+}
+
+template<typename _Iterator, typename _Sequence>
+inline __iterator_tracker<_Iterator, _Sequence>
+operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type
+ __n,
+ const __iterator_tracker<_Iterator, _Sequence>& __i)
+{
+ return __i + __n;
+}
+
+} // namespace __profile
+} // namespace std
+#endif
diff --git a/libstdc++-v3/include/profile/list b/libstdc++-v3/include/profile/list
index 09510a04205..01edd2919f6 100644
--- a/libstdc++-v3/include/profile/list
+++ b/libstdc++-v3/include/profile/list
@@ -30,13 +30,15 @@
#define _GLIBCXX_PROFILE_LIST 1
#include <list>
+#include <profile/base.h>
+#include <profile/iterator_tracker.h>
namespace std
{
namespace __profile
{
- /// Class std::list wrapper with performance instrumentation.
- template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+ /** @brief List wrapper with performance instrumentation. */
+template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class list
: public _GLIBCXX_STD_D::list<_Tp, _Allocator>
{
@@ -46,8 +48,10 @@ namespace __profile
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
+ typedef __iterator_tracker<typename _Base::iterator, list>
+ iterator;
+ typedef __iterator_tracker<typename _Base::const_iterator, list>
+ const_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
@@ -61,35 +65,60 @@ namespace __profile
// 23.2.2.1 construct/copy/destroy:
explicit list(const _Allocator& __a = _Allocator())
- : _Base(__a) { }
+ : _Base(__a)
+ {
+ __profcxx_list_construct(this); // list2slist
+ __profcxx_list_construct2(this); // list2vector
+ }
explicit list(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator())
- : _Base(__n, __value, __a) { }
+ : _Base(__n, __value, __a)
+ {
+ __profcxx_list_construct(this);
+ __profcxx_list_construct2(this);
+ }
template<class _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
- { }
+ {
+ __profcxx_list_construct(this);
+ __profcxx_list_construct2(this);
+ }
list(const list& __x)
- : _Base(__x) { }
+ : _Base(__x)
+ {
+ __profcxx_list_construct(this);
+ __profcxx_list_construct2(this);
+ }
list(const _Base& __x)
- : _Base(__x) { }
+ : _Base(__x)
+ {
+ __profcxx_list_construct(this);
+ __profcxx_list_construct2(this);
+ }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
list(list&& __x)
: _Base(std::forward<list>(__x))
- { }
+ {
+ __profcxx_list_construct(this);
+ __profcxx_list_construct2(this);
+ }
list(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
- ~list() { }
+ ~list() {
+ __profcxx_list_destruct(this);
+ __profcxx_list_destruct2(this);
+ }
list&
operator=(const list& __x)
@@ -118,7 +147,7 @@ namespace __profile
void
assign(initializer_list<value_type> __l)
- { _Base::assign(__l); }
+ { _Base::assign(__l); }
#endif
template<class _InputIterator>
@@ -128,34 +157,46 @@ namespace __profile
void
assign(size_type __n, const _Tp& __t)
- { _Base::assign(__n, __t); }
+ { _Base::assign(__n, __t); }
using _Base::get_allocator;
// iterators:
iterator
begin()
- { return iterator(_Base::begin()); }
+ { return iterator(_Base::begin(), this); }
const_iterator
begin() const
- { return const_iterator(_Base::begin()); }
+ { return const_iterator(_Base::begin(), this); }
iterator
end()
- { return iterator(_Base::end()); }
+ {
+ __profcxx_list_rewind(this);
+ return iterator(_Base::end(), this);
+ }
const_iterator
end() const
- { return const_iterator(_Base::end()); }
+ {
+ __profcxx_list_rewind(this);
+ return const_iterator(_Base::end(), this);
+ }
reverse_iterator
rbegin()
- { return reverse_iterator(end()); }
+ {
+ __profcxx_list_rewind(this);
+ return reverse_iterator(end());
+ }
const_reverse_iterator
rbegin() const
- { return const_reverse_iterator(end()); }
+ {
+ __profcxx_list_rewind(this);
+ return const_reverse_iterator(end());
+ }
reverse_iterator
rend()
@@ -168,11 +209,11 @@ namespace __profile
#ifdef __GXX_EXPERIMENTAL_CXX0X__
const_iterator
cbegin() const
- { return const_iterator(_Base::begin()); }
+ { return const_iterator(_Base::begin(), this); }
const_iterator
cend() const
- { return const_iterator(_Base::end()); }
+ { return const_iterator(_Base::end(), this); }
const_reverse_iterator
crbegin() const
@@ -203,14 +244,26 @@ namespace __profile
reference
back()
- { return _Base::back(); }
+ {
+ __profcxx_list_rewind(this);
+ return _Base::back();
+ }
const_reference
back() const
- { return _Base::back(); }
+ {
+ __profcxx_list_rewind(this);
+ return _Base::back();
+ }
// 23.2.2.3 modifiers:
- using _Base::push_front;
+ void
+ push_front(const value_type& __x)
+ {
+ __profcxx_list_invalid_operator(this);
+ __profcxx_list_operation(this);
+ _Base::push_front(__x);
+ }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
using _Base::emplace_front;
@@ -219,7 +272,7 @@ namespace __profile
void
pop_front()
{
- iterator __victim = begin();
+ __profcxx_list_operation(this);
_Base::pop_front();
}
@@ -235,6 +288,7 @@ namespace __profile
iterator __victim = end();
--__victim;
_Base::pop_back();
+ __profcxx_list_rewind(this);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -242,54 +296,70 @@ namespace __profile
iterator
emplace(iterator __position, _Args&&... __args)
{
- return iterator(_Base::emplace(__position,
- std::forward<_Args>(__args)...));
+ return iterator(_Base::emplace(__position.base(),
+ std::forward<_Args>(__args)...));
}
#endif
iterator
insert(iterator __position, const _Tp& __x)
- { return iterator(_Base::insert(__position, __x)); }
+ {
+ _M_profile_insert(this, __position, size());
+ return iterator(_Base::insert(__position.base(), __x), this);
+ }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
insert(iterator __position, _Tp&& __x)
- { return emplace(__position, std::move(__x)); }
+ {
+ _M_profile_insert(this, __position, size());
+ return iterator(_Base::emplace(__position.base(), std::move(__x)),
+ this);
+ }
void
- insert(iterator __p, initializer_list<value_type> __l)
- { _Base::insert(__p, __l); }
+ insert(iterator __position, initializer_list<value_type> __l)
+ {
+ _M_profile_insert(this, __position, size());
+ _Base::insert(__position.base(), __l);
+ }
#endif
void
insert(iterator __position, size_type __n, const _Tp& __x)
- { _Base::insert(__position, __n, __x); }
+ {
+ _M_profile_insert(this, __position, size());
+ _Base::insert(__position.base(), __n, __x);
+ }
template<class _InputIterator>
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
- { _Base::insert(__position, __first, __last); }
+ {
+ _M_profile_insert(this, __position, size());
+ _Base::insert(__position.base(), __first, __last);
+ }
iterator
erase(iterator __position)
- { return iterator(_Base::erase(__position)); }
+ { return iterator(_Base::erase(__position.base()), this); }
iterator
erase(iterator __position, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
- return iterator(_Base::erase(__position, __last));
+ return iterator(_Base::erase(__position.base(), __last.base()), this);
}
void
swap(list& __x)
- { _Base::swap(__x); }
+ { _Base::swap(__x); }
void
clear()
- { _Base::clear(); }
+ { _Base::clear(); }
// 23.2.2.4 list operations:
void
@@ -306,6 +376,12 @@ namespace __profile
{ this->splice(__position, std::move(__x)); }
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ splice(iterator __position, list& __x, iterator __i)
+ { this->splice(__position, std::move(__x), __i); }
+#endif
+
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
splice(iterator __position, list&& __x, iterator __i)
@@ -317,16 +393,10 @@ namespace __profile
// after implementing the relevant bits of N1599.
// _GLIBCXX_RESOLVE_LIB_DEFECTS
- _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
- __i);
+ _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
+ __i.base());
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- void
- splice(iterator __position, list& __x, iterator __i)
- { this->splice(__position, std::move(__x), __i); }
-#endif
-
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
splice(iterator __position, list&& __x, iterator __first,
@@ -339,8 +409,8 @@ namespace __profile
// We used to perform the splice_alloc check: not anymore, redundant
// after implementing the relevant bits of N1599.
- _Base::splice(__position, _GLIBCXX_MOVE(__x._M_base()),
- __first, __last);
+ _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
+ __first.base(), __last.base());
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -352,7 +422,7 @@ namespace __profile
void
remove(const _Tp& __value)
{
- for (iterator __x = begin(); __x != _Base::end(); )
+ for (iterator __x = begin(); __x != end(); )
{
if (*__x == __value)
__x = erase(__x);
@@ -365,8 +435,9 @@ namespace __profile
void
remove_if(_Predicate __pred)
{
- for (iterator __x = begin(); __x != _Base::end(); )
+ for (iterator __x = begin(); __x != end(); )
{
+ __profcxx_list_operation(this);
if (__pred(*__x))
__x = erase(__x);
else
@@ -384,6 +455,7 @@ namespace __profile
iterator __next = __first;
while (++__next != __last)
{
+ __profcxx_list_operation(this);
if (*__first == *__next)
erase(__next);
else
@@ -403,6 +475,7 @@ namespace __profile
iterator __next = __first;
while (++__next != __last)
{
+ __profcxx_list_operation(this);
if (__binary_pred(*__first, *__next))
erase(__next);
else
@@ -421,7 +494,7 @@ namespace __profile
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
- _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
+ { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -429,7 +502,7 @@ namespace __profile
merge(list& __x)
{ this->merge(std::move(__x)); }
#endif
-
+
template<class _Compare>
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -441,7 +514,7 @@ namespace __profile
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 300. list::merge() specification incomplete
if (this != &__x)
- _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
+ { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -466,6 +539,28 @@ namespace __profile
const _Base&
_M_base() const { return *this; }
+ inline void _M_profile_find() const
+ { }
+
+ inline void _M_profile_iterate(int __rewind = 0) const
+ {
+ __profcxx_list_operation(this);
+ __profcxx_list_iterate(this);
+ if (__rewind)
+ __profcxx_list_rewind(this);
+ }
+
+ private:
+ size_type _M_profile_insert(void* obj, iterator __pos, size_type __size)
+ {
+ size_type __shift = 0;
+ typename _Base::iterator __it = __pos.base();
+ for ( ; __it!=_Base::end(); __it++)
+ __shift++;
+ __profcxx_list_rewind(this);
+ __profcxx_list_operation(this);
+ __profcxx_list_insert(this, __shift, __size);
+ }
};
template<typename _Tp, typename _Alloc>
diff --git a/libstdc++-v3/include/profile/vector b/libstdc++-v3/include/profile/vector
index e4e680f8699..ba4d5e70cd5 100644
--- a/libstdc++-v3/include/profile/vector
+++ b/libstdc++-v3/include/profile/vector
@@ -37,12 +37,12 @@
#include <vector>
#include <utility>
#include <profile/base.h>
+#include <profile/iterator_tracker.h>
namespace std
{
namespace __profile
{
- /// Class std::vector wrapper with performance instrumentation.
template<typename _Tp,
typename _Allocator = std::allocator<_Tp> >
class vector
@@ -54,17 +54,21 @@ namespace __profile
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
+ typedef __iterator_tracker<typename _Base::iterator, vector>
+ iterator;
+ typedef __iterator_tracker<typename _Base::const_iterator, vector>
+ const_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
- typedef _Tp value_type;
- typedef _Allocator allocator_type;
+ typedef _Tp value_type;
+ typedef _Allocator allocator_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
-
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
_Base&
_M_base() { return *this; }
@@ -158,6 +162,58 @@ namespace __profile
using _Base::assign;
using _Base::get_allocator;
+
+ // iterators:
+ iterator
+ begin()
+ { return iterator(_Base::begin(), this); }
+
+ const_iterator
+ begin() const
+ { return const_iterator(_Base::begin(), this); }
+
+ iterator
+ end()
+ { return iterator(_Base::end(), this); }
+
+ const_iterator
+ end() const
+ { return const_iterator(_Base::end(), this); }
+
+ reverse_iterator
+ rbegin()
+ { return reverse_iterator(end()); }
+
+ const_reverse_iterator
+ rbegin() const
+ { return const_reverse_iterator(end()); }
+
+ reverse_iterator
+ rend()
+ { return reverse_iterator(begin()); }
+
+ const_reverse_iterator
+ rend() const
+ { return const_reverse_iterator(begin()); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const_iterator
+ cbegin() const
+ { return const_iterator(_Base::begin(), this); }
+
+ const_iterator
+ cend() const
+ { return const_iterator(_Base::end(), this); }
+
+ const_reverse_iterator
+ crbegin() const
+ { return const_reverse_iterator(end()); }
+
+ const_reverse_iterator
+ crend() const
+ { return const_reverse_iterator(begin()); }
+#endif
+
// 23.2.4.2 capacity:
using _Base::size;
using _Base::max_size;
@@ -243,22 +299,24 @@ namespace __profile
iterator
insert(iterator __position, const _Tp& __x)
{
- __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+ this->size());
size_type __old_size = this->capacity();
- typename _Base::iterator __res = _Base::insert(__position,__x);
+ typename _Base::iterator __res = _Base::insert(__position.base(), __x);
_M_profile_resize(this, __old_size, this->capacity());
- return __res;
+ return iterator(__res, this);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
iterator
insert(iterator __position, _Tp&& __x)
{
- __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+ this->size());
size_type __old_size = this->capacity();
- typename _Base::iterator __res = _Base::insert(__position,__x);
+ typename _Base::iterator __res = _Base::insert(__position.base(), __x);
_M_profile_resize(this, __old_size, this->capacity());
- return __res;
+ return iterator(__res, this);
}
void
@@ -266,20 +324,27 @@ namespace __profile
{ this->insert(__position, __l.begin(), __l.end()); }
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
+ swap(vector&& __x)
+ {
+ _Base::swap(__x);
+ }
+#endif
+ void
swap(vector& __x)
{
_Base::swap(__x);
}
-
void
insert(iterator __position, size_type __n, const _Tp& __x)
{
- __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ __profcxx_vector_insert(this, __position.base() - _Base::begin(),
+ this->size());
size_type __old_size = this->capacity();
- _Base::insert(__position, __n, __x);
+ _Base::insert(__position, __n, __x);
_M_profile_resize(this, __old_size, this->capacity());
}
@@ -288,12 +353,31 @@ namespace __profile
insert(iterator __position,
_InputIterator __first, _InputIterator __last)
{
- __profcxx_vector_insert(this, __position-_Base::begin(), this->size());
+ __profcxx_vector_insert(this, __position.base()-_Base::begin(),
+ this->size());
size_type __old_size = this->capacity();
_Base::insert(__position, __first, __last);
_M_profile_resize(this, __old_size, this->capacity());
}
+
+ iterator
+ erase(iterator __position)
+ {
+ typename _Base::iterator __res = _Base::erase(__position.base());
+ return iterator(__res, this);
+ }
+
+ iterator
+ erase(iterator __first, iterator __last)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 151. can't currently clear() empty container
+ typename _Base::iterator __res = _Base::erase(__first.base(),
+ __last.base());
+ return iterator(__res, this);
+ }
+
void
clear()
{
@@ -302,17 +386,14 @@ namespace __profile
_Base::clear();
}
- // iterators:
- iterator
- begin()
+ inline void _M_profile_find() const
{
- return _Base::begin();
+ __profcxx_vector_find(this, size());
}
- const_iterator
- begin() const
+ inline void _M_profile_iterate(int __rewind = 0) const
{
- return _Base::begin();
+ __profcxx_vector_iterate(this);
}
private:
@@ -367,6 +448,18 @@ namespace __profile
swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __profile
using _GLIBCXX_STD_D::_S_word_bit;
} // namespace std