mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-09 18:17:07 +00:00
Recursive type hashing was showing up as the major hot spot of performance profiles. After spending a few days on trying to speed it up, I have officially declared recursive tree node hashing as a slow process and I am giving up. I have thus decided to not use that at type canonicalization time. Rather, I am proposing a new type canonicalization routine where types are first hashed by hashing their pretty representation string. Basically, if T is the total number of types in the system and C the number of classes of equivalences (or the number of canonical types), the number of type comparisons done by a naive type canonicalization routine is N x C. With the worse C being equal to N itself, that worse number of comparisons is N*N. By using a hash table to store the canonical types, keyed by a hash of their pretty representation string, the number of type comparisons can be brought down to N*P, where P is a the greater number of which pretty representation string hash collide. That number P is usually small; my measurements show that N usually goes from 1 to 3. And moreover, computing the hash of the pretty representation string of the function is way faster than using the recursive type hash! As a result, running abidw on the libcilkrts.so library, from GCC goes from 12 minutes to 0.4 seconds! Incidentally, now that we are not trying to speed up the recursive type hashing process, all the complicated business we had around caching the result of the hashing is gone! I was thinking that hash cashing was inherently a bad idea, especially for recursive types -- that refer to themselves directly or indirectly, because in those case, depending on when you cached the hash value, the value of the hashing can be different. The abixml writer's code doesn't use the recursive type hash anymore either; it uses the pointer value of the canonical type as hash. Super fast too! The patch had to fix pieces here and there to comply with the fact that canonical types are now used across the board in a mandatory fashion. * include/abg-ir.h (canonical_types_map_type): Adjust this typedef to make it point to an unordered_map which the key is now a string and the value is a vector of types. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value, cached_hash}): Remove these member functions and type. (struct type_base::cached_hash): Remove. * src/abg-ir.cc (struct type_or_decl_base::priv::hash_): Remove. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::{g,s}et_cached_hash_value): Remove. (type_base::get_canonical_type_for): For declaration-only classes, look at their definition for the canonical_type. Do not use recursive type hashing anymore. Rather, use the pretty representation string, and hash that. (class_decl::base_spec::get_hash): Do away with hash value caching here. (class_decl::operator==): For decl-only classes, look at their definitions for canonical types. (hash_type_or_decl): Adjust comment. Use the canonical type pointer value for type hash. That's the fast path. Otherwise, if not available, fall back to a slow path which is the recursive type hash we were using before. * src/abg-dwarf-reader.cc (maybe_canonicalize_type): Schedule all classes and typedef to classes for late canonicalization. * src/abg-hash.cc (type_base::dynamic_hash::operator()): There is no hash value cashing anymore. (type_base::cached_hash::operator()): Remove. * src/abg-reader.cc (read_context::get_type): Slight style adjustment. (read_translation_unit_from_file) (read_translation_unit_from_buffer): Do not forget to canonicalize types when reading just one translation unit. (build_type_tparameter, build_template_tparameter): Canonicalize the type. * src/abg-writer.cc (struct type_hasher): New hasher type. (type_ptr_map): Use a deep pointer comparison equal operator functor, and canonical types as type hash values. (write_class_decl): Do not write size and alignment on decl-only classes. Do not record decl-only classes as being emitted. Their definition must be emitted before. * tests/test-read-write.cc (main): Do not do abi testing on translation units (as opposed to doing it on abi corpora) as that code is not wet yet. We need to know how to diff namespaces. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
200 lines
13 KiB
Plaintext
200 lines
13 KiB
Plaintext
Functions changes summary: 1 Removed, 19 Changed, 1 Added functions
|
|
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
|
|
|
|
1 Removed function:
|
|
|
|
'method void std::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >::_M_clear()'
|
|
|
|
1 Added function:
|
|
|
|
'method void std::__cxx11::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >::_M_clear()'
|
|
|
|
19 functions with some indirect sub-type change:
|
|
|
|
[C]'method sigc::connection::connection(const sigc::connection&)' has some indirect sub-type changes:
|
|
parameter 1 of type 'const sigc::connection&' has sub-type changes:
|
|
in referenced type 'const sigc::connection':
|
|
in unqualified underlying type 'struct sigc::connection':
|
|
1 data member change:
|
|
type of 'sigc::slot_base* sigc::connection::slot_' changed:
|
|
in pointed to type 'class sigc::slot_base':
|
|
1 data member change:
|
|
type of 'sigc::slot_base::rep_type* sigc::slot_base::rep_' changed:
|
|
in pointed to type 'typedef sigc::slot_base::rep_type':
|
|
underlying type 'struct sigc::internal::slot_rep' changed:
|
|
1 base class change:
|
|
'struct sigc::trackable' changed:
|
|
1 data member change:
|
|
type of 'sigc::internal::trackable_callback_list* sigc::trackable::callback_list_' changed:
|
|
in pointed to type 'struct sigc::internal::trackable_callback_list':
|
|
type size changed from 192 to 256 bits
|
|
2 data member changes:
|
|
type of 'sigc::internal::trackable_callback_list::callback_list sigc::internal::trackable_callback_list::callbacks_' changed:
|
|
underlying type 'class std::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >' changed:
|
|
type name changed from 'std::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >' to 'std::__cxx11::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >'
|
|
type size changed from 128 to 192 bits
|
|
1 base class deletion:
|
|
class std::_List_base<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >
|
|
1 base class insertion:
|
|
class std::__cxx11::_List_base<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >
|
|
|
|
'bool sigc::internal::trackable_callback_list::clearing_' offset changed from 128 to 192 (in bits)
|
|
|
|
|
|
|
|
|
|
|
|
[C]'method sigc::connection::connection(sigc::slot_base&)' has some indirect sub-type changes:
|
|
parameter 1 of type 'sigc::slot_base&' has sub-type changes:
|
|
referenced type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::connection& sigc::connection::operator=(const sigc::connection&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
referenced type 'struct sigc::connection' changed, as reported earlier
|
|
parameter 1 of type 'const sigc::connection&' has sub-type changes:
|
|
in referenced type 'const sigc::connection':
|
|
unqualified underlying type 'struct sigc::connection' changed, as reported earlier
|
|
|
|
[C]'method void sigc::connection::set_slot(sigc::slot_base*)' has some indirect sub-type changes:
|
|
parameter 1 of type 'sigc::slot_base*' has sub-type changes:
|
|
pointed to type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::connect(const sigc::slot_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::erase(sigc::internal::signal_impl::iterator_type)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
|
|
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::insert(sigc::internal::signal_impl::iterator_type, const sigc::slot_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 2 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::signal_base::iterator_type sigc::signal_base::connect(const sigc::slot_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::signal_base::iterator_type sigc::signal_base::erase(sigc::signal_base::iterator_type)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'typedef sigc::signal_base::iterator_type' changed:
|
|
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
|
|
[C]'method sigc::internal::signal_impl* sigc::signal_base::impl()' has some indirect sub-type changes:
|
|
return type changed:
|
|
in pointed to type 'struct sigc::internal::signal_impl':
|
|
type size changed from 192 to 256 bits
|
|
1 data member change:
|
|
type of 'std::list<sigc::slot_base, std::allocator<sigc::slot_base> > sigc::internal::signal_impl::slots_' changed:
|
|
type name changed from 'std::list<sigc::slot_base, std::allocator<sigc::slot_base> >' to 'std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >'
|
|
type size changed from 128 to 192 bits
|
|
1 base class deletion:
|
|
class std::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >
|
|
1 base class insertion:
|
|
class std::__cxx11::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >
|
|
|
|
|
|
[C]'method sigc::signal_base::iterator_type sigc::signal_base::insert(sigc::signal_base::iterator_type, const sigc::slot_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 1 of type 'typedef sigc::signal_base::iterator_type' changed:
|
|
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
|
|
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
|
|
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
|
|
|
|
parameter 2 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::signal_base& sigc::signal_base::operator=(const sigc::signal_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
in referenced type 'struct sigc::signal_base':
|
|
1 base class change:
|
|
'struct sigc::trackable' changed:
|
|
details were reported earlier
|
|
|
|
1 data member change:
|
|
type of 'sigc::internal::signal_impl* sigc::signal_base::impl_' changed:
|
|
pointed to type 'struct sigc::internal::signal_impl' changed, as reported earlier
|
|
|
|
parameter 1 of type 'const sigc::signal_base&' has sub-type changes:
|
|
in referenced type 'const sigc::signal_base':
|
|
unqualified underlying type 'struct sigc::signal_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::signal_base::signal_base(const sigc::signal_base&)' has some indirect sub-type changes:
|
|
parameter 1 of type 'const sigc::signal_base&' has sub-type changes:
|
|
in referenced type 'const sigc::signal_base':
|
|
unqualified underlying type 'struct sigc::signal_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::slot_base& sigc::slot_base::operator=(const sigc::slot_base&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
referenced type 'class sigc::slot_base' changed, as reported earlier
|
|
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::slot_base::slot_base(sigc::slot_base::rep_type*)' has some indirect sub-type changes:
|
|
parameter 1 of type 'sigc::slot_base::rep_type*' has sub-type changes:
|
|
in pointed to type 'typedef sigc::slot_base::rep_type':
|
|
underlying type 'struct sigc::internal::slot_rep' changed, as reported earlier
|
|
|
|
[C]'method sigc::slot_base::slot_base(const sigc::slot_base&)' has some indirect sub-type changes:
|
|
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
|
|
in referenced type 'const sigc::slot_base':
|
|
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
|
|
|
|
[C]'method sigc::internal::trackable_callback_list* sigc::trackable::callback_list()' has some indirect sub-type changes:
|
|
return type changed:
|
|
pointed to type 'struct sigc::internal::trackable_callback_list' changed, as reported earlier
|
|
|
|
[C]'method sigc::trackable& sigc::trackable::operator=(const sigc::trackable&)' has some indirect sub-type changes:
|
|
return type changed:
|
|
referenced type 'struct sigc::trackable' changed, as reported earlier
|
|
parameter 1 of type 'const sigc::trackable&' has sub-type changes:
|
|
in referenced type 'const sigc::trackable':
|
|
unqualified underlying type 'struct sigc::trackable' changed, as reported earlier
|
|
|
|
[C]'method sigc::trackable::trackable(const sigc::trackable&)' has some indirect sub-type changes:
|
|
parameter 1 of type 'const sigc::trackable&' has sub-type changes:
|
|
in referenced type 'const sigc::trackable':
|
|
unqualified underlying type 'struct sigc::trackable' changed, as reported earlier
|
|
|
|
|
|
|