From: Dodji Seketeli Date: Mon, 8 Jul 2019 14:53:52 +0000 (+0200) Subject: [xml-writter] Avoid using RTTI when dynamically hashing types X-Git-Tag: upstream/1.7~73 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=65318dacfb948c594032addf1872ff9debc0c413;p=platform%2Fupstream%2Flibabigail.git [xml-writter] Avoid using RTTI when dynamically hashing types When we dynamically hash types in the abixml writter, we use hash_type_or_decl. This function uses runtime type identification to determine if the (type) artifact is a decl or a type, and based on that, choose how to compute its hash value. Profiling shows that using the RTTI in hash_type_or_decl at this point is a hotspot. Because we know that the type ABI is a *type*, we obviously can avoid using RTTI there. The patch thus implements a hash_type function, and uses that in the xml writter. Emitting the abixml output is faster with this patch. * include/abg-fwd.h (hash_type): Declare new function. * src/abg-ir.cc (hash_type): Define new function. * src/abg-writer.cc (type_hasher::operator()): Use the new hash_type rather than the old hash_type_or_decl. Signed-off-by: Dodji Seketeli --- diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 8e45a25e..0ea8b2b9 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -1263,6 +1263,9 @@ type_has_sub_type_changes(type_base_sptr t_v1, void keep_type_alive(type_base_sptr t); +size_t +hash_type(const type_base *t); + size_t hash_type_or_decl(const type_or_decl_base *); diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 106258be..19b80826 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -21697,6 +21697,58 @@ hash_type_or_decl(const type_or_decl_base *tod) return result; } +/// Hash an ABI artifact that is either a type. +/// +/// This function intends to provides the fastest possible hashing for +/// types while being completely correct. +/// +/// Note that if the type artifact has a canonical type, the hash +/// value is going to be the pointer value of the canonical type. +/// Otherwise, this function computes a hash value for the type by +/// recursively walking the type members. This last code path is +/// possibly *very* slow and should only be used when only handful of +/// types are going to be hashed. +/// +/// @param t the type or decl to hash. +/// +/// @return the resulting hash value. +size_t +hash_type(const type_base *t) +{ + size_t result = 0; + + // If the type has a canonical type, then use the pointer value + // as a hash. This is the fastest we can get. + if (type_base* ct = t->get_naked_canonical_type()) + result = reinterpret_cast(ct); + else if (const class_decl* cl = is_class_type(t)) + { + if (cl->get_is_declaration_only() + && cl->get_naked_definition_of_declaration()) + // The is a declaration-only class, so it has no canonical + // type; but then it's class definition has one. Let's + // use that one. + return hash_type(cl->get_naked_definition_of_declaration()); + else + { + // The class really has no canonical type, let's use the + // slow path of hashing the class recursively. Well + // it's not that slow as the hash value is quickly going + // to result to zero anyway. + type_base::dynamic_hash hash; + result = hash(t); + } + } + else + { + // Let's use the slow path of hashing the class recursively. + type_base::dynamic_hash hash; + result = hash(t); + } + + return result; +} + /// Hash an ABI artifact that is either a type of a decl. /// /// @param tod the ABI artifact to hash. diff --git a/src/abg-writer.cc b/src/abg-writer.cc index 2c9085be..0aaa03d4 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -134,7 +134,7 @@ struct type_hasher { size_t operator()(const type_base* t) const - {return hash_type_or_decl(t);} + {return hash_type(t);} }; // end struct type_hasher /// A convenience typedef for a map that associates a pointer to type