The Git repository of the Libabigail Project
Go to file
Dodji Seketeli 400ac7a412 Implement fast comparison of Linux Kernel types when applicable
During type canonicalization there are observations that can speed-up
type comparison significantly without impacting correctness too much.

Typically, when two types are of the same name and kind, are found in
the same corpus and are defined in the same translation unit, they
ought to be the same type, even in C.  So there is no need in this
case to actually perform the structural comparison of the two types
which does have a quadratic performance at best.

Using this optimization made the loading of the
drivers/gpu/drm/i915/i915.ko module go from a quasi inifite time (many
hours on my system) to less than two minutes.  I am confining this
optimization to the Linux kernel case only for now, but I believe it
could benefit all C programs.  I am waiting for more testing before
applying it more broadly.

Also, while looking at this, I noticed that when loading several
corpora into a given corpus group (i.e, loading several linux kernel
binaries to represent a single conceptual kernel), we sometimes fail
to recognize that a type defined in a header file that is included in
several corpora is actually the same type, and should be re-used,
rather than being re-defined in each corpus.  This later adds stress
(time and space) on the system as we need to canonicalize and
de-duplicate these type later on.

This is because the "per-corpus" type maps that we use to lookup a
type by name and location when we see it (so that we know it's defined
in a different corpus of our current group) should really be
per-corpus-group type maps!  That is a type can be defined in the
corpus representing a .ko binary, and that type would be seen again in
another .ko binary later.  Until now, we were wrongly considering that
types were to be first defined in the corpus of the vmlinux binary,
and then could be re-used later.

I have thus fixed the code so that whenever we add a type to its
scope, the relevant per-corpus type maps are updated, as well as the
per-corpus-group ones, so that we can later lookup types in those
per-corpus-group type maps to know if a type is already defined in any
corpus of the group.

	* include/abg-corpus.h (corpus::origin): Add a new
	LINUX_KERNEL_BINARY_ORIGIN enumerator.
	(corpus::{s,g}et_group): Declare new member
	functions.
	(class corpus): Make the corpus_group class friend of this one.
	(corpus_group::get_main_corpus): Declare new member function.
	* src/abg-corpus-priv.h (corpus::priv::group): Define new data
	member.
	(corpus::priv::priv): Initialize the new corpus::priv::group data
	member.
	* src/abg-corpus.cc (corpus::{g,s}et_group): Define new member
	functions.
	(corpus_group::get_main_corpus): Likewise.
	(corpus_group::add_corpus): Use the new corpus::set_group() here
	to to make the corpus be aware of the group it belongs to.
	* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Set the
	current corpus origin to the corpus::LINUX_KERNEL_BINARY_ORIGIN if
	we are looking at a Linux Kernel binary.
	(read_context::main_corpus_from_current_group): Use the
	corpus_group::get_main_corpus method.
	(should_reuse_type_from_corpus_group): Return the corpus group,
	rather than the main corpus.
	(read_debug_info_into_corpus): Add the current corpus to the
	current corpus group before the debug info reading is done.  That
	way, the corpus group will be accessible from the current corpus
	during the construction of the internal representation.
	(read_and_add_corpus_to_group_from_elf): Add the corpus to the
	group only if it wasn't added to it before.
	* include/abg-ir.h (operator{==,!=}): Declare new deep equality
	and inequality operators for class_or_union_sptr and
	union_decl_sptr.
	* src/abg-ir.cc (types_defined_same_linux_kernel_corpus_public):
	Define a new static function.
	(type_base::get_canonical_type_for): Use the new
	types_defined_same_linux_kernel_corpus_public here to speed up
	type comparison.
	(equals): In the overload of class_or_union, use the new
	types_defined_same_linux_kernel_corpus_public as well, to speed up
	type comparison.
	(operator{==,!=}): Define new deep equality and inequality
	operators for class_or_union_sptr and union_decl_sptr.
	(maybe_update_types_lookup_map): In the overload function for
	type_decl_sptr, class_decl_sptr, union_decl_sptr,
	enum_type_decl_sptr, typedef_decl_sptr, qualified_type_def_sptr,
	reference_type_def_sptr, array_type_def_sptr,
	array_type_def::subrange_sptr, and function_type_sptr, update the
	type lookup maps of the containing corpus group as well, not just
	the ones of the current corpus.
	* src/abg-reader.cc (build_enum_type_decl): Forgot to set the
	"is-anonymous" flag.  Oops, fix this.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-17 19:35:38 +02:00
autoconf-archive Do not ignore valgrind checks returning an error 2017-02-27 10:01:15 +01:00
bash-completion Add --self-compare option in fedabipkgdiff 2017-05-31 16:21:14 +05:30
doc Update website mainpage for 1.6 release 2019-03-29 17:31:33 +01:00
include Implement fast comparison of Linux Kernel types when applicable 2019-07-17 19:35:38 +02:00
m4 Delete ltsugar.m4 and pkg.m4 files from m4/ 2015-01-06 09:54:45 +01:00
scripts Clean up scripts/* 2017-04-14 04:14:12 -04:00
src Implement fast comparison of Linux Kernel types when applicable 2019-07-17 19:35:38 +02:00
tests Implement fast comparison of Linux Kernel types when applicable 2019-07-17 19:35:38 +02:00
tools Add compatibility layer for C++11 mode 2019-07-09 18:05:28 +02:00
.clang-format .clang-format: Add more options for match existing coding style 2019-05-22 14:34:31 +02:00
.gitignore .gitignore: Add libabigail-?.* *.orig files 2019-05-22 14:34:23 +02:00
abigail.m4 For usage from within GCC set header path to $includedir/libabigail 2013-08-14 16:10:15 +02:00
AUTHORS Initial AUTHORS and README 2013-02-28 13:25:20 +01:00
ChangeLog Update ChangeLog 2019-03-27 18:39:08 +01:00
COMMIT-LOG-GUIDELINES Update the COMMIT-LOG-GUIDELINES file 2016-05-22 23:20:12 +02:00
COMPILING Some documentation fixes 2018-12-07 11:21:50 +01:00
configure.ac Add --enable-{asan,ubsan} configure options 2019-04-18 15:46:34 +02:00
CONTRIBUTING Control symbols exported from libabigail.so 2016-07-27 12:51:02 +02:00
COPYING Use a better wording for the COPYING file 2015-04-22 09:53:18 +02:00
COPYING-GPLV3 Update licence texts 2015-04-20 13:51:21 +02:00
COPYING-LGPLV2 Initial import of gen-changelog.py 2014-11-18 23:18:06 +01:00
COPYING-LGPLV3 LGPLv3 License the library 2013-07-23 23:13:55 +02:00
default.abignore Add default suppression specification for the libvirt project 2018-10-11 10:59:54 +02:00
gen-changelog.py [gen-changelog] Make subject line always come first 2014-11-18 23:18:06 +01:00
install-sh Add missing autoconfiscation files into version control 2013-03-01 00:47:49 +01:00
libabigail.pc.in Make libxml2 a private dependency wrt pkconfig 2013-08-22 17:41:29 +02:00
ltmain.sh Add missing autoconfiscation files into version control 2013-03-01 00:47:49 +01:00
Makefile.am Make the "upload-release" target be usable in parallel 2018-03-06 18:08:22 +01:00
NEWS Update NEWS file for 1.6 2019-03-27 18:36:53 +01:00
README Fix wording in README 2015-09-05 10:30:00 +02:00
release-text-template.txt Update the release text template after 1.0 2017-11-22 15:55:43 +01:00
update-copyright.sh Update copyright for 2019 2019-01-07 14:54:47 +01:00
VISIBILITY Control symbols exported from libabigail.so 2016-07-27 12:51:02 +02:00

This is the Application Binary Interface Generic Analysis and
Instrumentation Library.

It aims at constructing, manipulating, serializing and de-serializing
ABI-relevant artifacts.

The set of artifacts that we are intersted is made of quantities like
types, variable, fonctions and declarations of a given library or
program.  For a given library or program this set of quantities is
called an ABI corpus.

This library aims at (among other things) providing a way to compare
two ABI Corpora (apparently the plural of corpus is copora, heh,
that's cool), provide detailed information about their differences,
and help build tools to infer interesting conclusions about these
differences.

You are welcome to contribute to this project after reading the files
CONTRIBUTING and COMMIT-LOG-GUIDELINES files in the source tree.

Communicating with the maintainers of this project -- including
sending patches to be include to the source code -- happens via email
at libabigail@sourceware.org.