mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-20 00:40:05 +00:00
ba741963b9
Look at this code: struct list; struct payload { int value; list* parent_list; //<-- the hash value of struct list when looking // through this pointer is the non-zero // value as computed on the struct list // type below. }; struct list { payload* p; // <-- While walking the struct list type, the hash // value of the 'struct list' sub-tree node when // looking through this pointer is zero, because we // are still computing the hash value of struct list. // we do it this way to break the otherwise infinite // recursion that might occur here. list* next; // <-- likewise here. list* prev; // <-- likewise here. }; // <-- when we reach this point the hash value of struct list // is computed and is different from zero. Basically, when a type refers to itself in one of its sub-type (like struct list here, where list::p refers to struct list, because its type contains a pointer to struct list), then we need to devise a way to break the infinite recursion we might fall into when computing its hash value. So, when computing the hash value of struct list, when we look at the type of list::prev, which is "list*", we say that the hash value of the type pointed to by the type of list::next (which is struct list itself) is zero. This allows us to break the possibly infinite recursion here. But then, this means that the hash value of "struct list" depends on *when* we request that hash value. If we are computing the hash value of struct list itself, then the temporary value of "struct list" is zero. But then once we are done computing the hash value of "struct list", that value becomes non-zero. Hence, the hash value of a type depends on when that value is computed. But then if we want to cache that hash value and re-use it later, which value should we cache? Definitely not the zero value! So in other words, we can use (and thus cache) the hash value of a given type T only after the hash values of all types which use T have been computed. To satisfy that condition, we decide to use the (cached) hash value of each type only after we've computed all the hash values of all types of the system. So, during type canonicalization, when a type T is canonicalized, this patch stores the hash value of T. But then it's only when all types are canonicalized that the hashing code is allowed to re-use the cached value of types. This fixes the issues of spurious type differences introduced when the same type was read either from DWARF or from abixml. Those differences where introduced by differences in the order of hashing types which sub-types refer to themselves. The patch also updates regression tests accordingly. * src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Before we read debug info and build the IR, set a flag in the environment saying that type canonicalization isn't finished yet. But then, after type canonicalization is done, flip that flag to say that type canonicalization is done. * src/abg-reader.cc (read_corpus_from_input): Likewise. * src/abg-ir.cc (type_base::get_canonical_type_for): Once a type has been canonicalized, cache its hash value. * src/abg-hash.cc (type_base::dynamic_hash::operator()): If type canonicalization has been done and if the type has a cached value, use that one. * tests/data/test-read-dwarf/test2.so.abi: 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> |
||
---|---|---|
.. | ||
data | ||
Makefile.am | ||
print-diff-tree.cc | ||
runtestcanonicalizetypes.sh.in | ||
test-abicompat.cc | ||
test-abidiff.cc | ||
test-alt-dwarf-file.cc | ||
test-core-diff.cc | ||
test-diff2.cc | ||
test-diff-dwarf.cc | ||
test-diff-filter.cc | ||
test-diff-pkg.cc | ||
test-diff-suppr.cc | ||
test-dot.cc | ||
test-ir-walker.cc | ||
test-lookup-syms.cc | ||
test-read-dwarf.cc | ||
test-read-write.cc | ||
test-svg.cc | ||
test-utils.cc | ||
test-utils.h | ||
test-write-read-archive.cc |