mirror of
git://sourceware.org/git/libabigail.git
synced 2025-03-05 22:27:34 +00:00
Implement a poor-man's RTTI for performance
Profiling showed that a number of use of dynamic_cast are a speed bottleneck. This patch implements a poor-man's RTTI that allows us to implement a form of dynamic_cast that is specific to the types of the internal reprenstation that are in the namespace abigail::ir. It speeds up things greatly. Basically, the base type of all ABI artifacts (abigail::ir::type_or_decl_base) now contains three new data members. The first one contains a bitmap that identifies the type of artifact. The second one contains a pointer to the dynamic type sub-object of the current instance of the artifact. The last one contains either a pointer to the type_base sub-object of the current instance of ABI artifact if it's a type, or a pointer to the type_decl sub-object of the current instance. Together these three data members allow the patch to implement the abigail::ir::{is_type(), is_decl(), is_<type_kind>_type} functions that we need to make the code base noticeably faster when using abidw on a big vmlinux binary. * include/abg-fwd.h (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. * include/abg-ir.h (type_or_decl_base::type_or_decl_kind): Define new enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Declare new accessors. (operator{|,|=,&,&=): Declare new operators for the new type_or_decl_base::type_or_decl_kind enum. (global_scope::global_scope): Move the definition of this constructor to ... * src/abg-ir.cc (global_scope::global_scope): ... here. (type_or_decl_base::priv::{kind_, rtti_, type_or_decl_ptr_}): Add new data members. (type_or_decl_base::priv::priv): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::priv::kind): Define new accessors. (operator{|,|=,&,&=): Define new operators for the new type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::type_or_decl_base): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Define new accessors. (decl_base::decl_base, scope_decl::scope_decl) (type_base::type_base, scope_type_decl::scope_type_decl) (class_or_union::class_or_union) : Adjust to set the runtime type identifier of the instances of these types. (global_scope::global_scope, type_decl::type_decl) (qualified_type_def::qualified_type_def) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def array_type_def::subrange_type::subrange_type) (array_type_def::array_type_def, enum_type_decl::enum_type_decl) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter, method_decl::method_decl) (class_decl::class_decl, class_decl::base_spec::base_spec) (union_decl::union_decl, template_decl::template_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Likewise and call runtime_type_instance() here to set the runtime type instance pointers of the current instance. (is_decl, is_type, is_class_type, is_pointer_type): Adjust to use the new poor-man's rtti machinery. (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. (pointer_type_def::operator==, class_decl::operator==): Use the poor-man's rtti machinery to replace dynamic_cast. hash_type_or_decl: Replace dynamic_cast<const type_base> by is_type() and dynamic_cast<const decl_base*> by is_decl(). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
35312fa92a
commit
c940a229c9
@ -408,13 +408,10 @@ bool
|
||||
is_anonymous_type(const type_base_sptr&);
|
||||
|
||||
const type_decl*
|
||||
is_type_decl(const type_base*);
|
||||
is_type_decl(const type_or_decl_base*);
|
||||
|
||||
type_decl_sptr
|
||||
is_type_decl(const type_base_sptr&);
|
||||
|
||||
type_decl_sptr
|
||||
is_type_decl(const decl_base_sptr&);
|
||||
is_type_decl(const type_or_decl_base_sptr&);
|
||||
|
||||
typedef_decl_sptr
|
||||
is_typedef(const type_or_decl_base_sptr);
|
||||
|
106
include/abg-ir.h
106
include/abg-ir.h
@ -1167,13 +1167,66 @@ class type_or_decl_base : public ir_traversable_base
|
||||
|
||||
protected:
|
||||
|
||||
/// This is a bitmap type which instance is meant to contain the
|
||||
/// runtime type of a given ABI artifact. Bits of the identifiers
|
||||
/// of the type of a given artifact as well as the types it inherits
|
||||
/// from are to be set to 1.
|
||||
enum type_or_decl_kind
|
||||
{
|
||||
ABSTRACT_TYPE_OR_DECL,
|
||||
ABSTRACT_DECL_BASE = 1,
|
||||
ABSTRACT_SCOPE_DECL = 1 << 1,
|
||||
GLOBAL_SCOPE_DECL = 1 << 2,
|
||||
NAMESPACE_DECL = 1 << 3,
|
||||
VAR_DECL = 1 << 4,
|
||||
FUNCTION_DECL = 1 << 5,
|
||||
FUNCTION_PARAMETER_DECL = 1 << 6,
|
||||
METHOD_DECL = 1 << 7,
|
||||
TEMPLATE_DECL = 1 << 8,
|
||||
ABSTRACT_TYPE_BASE = 1 << 9,
|
||||
ABSTRACT_SCOPE_TYPE_DECL = 1 << 10,
|
||||
BASIC_TYPE = 1 << 11,
|
||||
QUALIFIED_TYPE = 1 << 12,
|
||||
POINTER_TYPE = 1 << 13,
|
||||
REFERENCE_TYPE = 1 << 14,
|
||||
ARRAY_TYPE = 1 << 15,
|
||||
ENUM_TYPE = 1 << 16,
|
||||
TYPEDEF_TYPE = 1 << 17,
|
||||
CLASS_TYPE = 1 << 18,
|
||||
UNION_TYPE = 1 << 19,
|
||||
FUNCTION_TYPE = 1 << 20,
|
||||
METHOD_TYPE = 1 << 21,
|
||||
}; // end enum type_or_decl_kind
|
||||
|
||||
enum type_or_decl_kind
|
||||
kind() const;
|
||||
|
||||
void
|
||||
kind(enum type_or_decl_kind);
|
||||
|
||||
const void*
|
||||
runtime_type_instance() const;
|
||||
|
||||
void*
|
||||
runtime_type_instance();
|
||||
|
||||
void
|
||||
runtime_type_instance(void*);
|
||||
|
||||
const void*
|
||||
type_or_decl_base_pointer() const;
|
||||
|
||||
void*
|
||||
type_or_decl_base_pointer();
|
||||
|
||||
bool hashing_started() const;
|
||||
|
||||
void hashing_started(bool) const;
|
||||
|
||||
public:
|
||||
|
||||
type_or_decl_base(const environment*);
|
||||
type_or_decl_base(const environment*,
|
||||
enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL);
|
||||
|
||||
type_or_decl_base(const type_or_decl_base&);
|
||||
|
||||
@ -1212,8 +1265,52 @@ public:
|
||||
virtual string
|
||||
get_pretty_representation(bool internal = false,
|
||||
bool qualified_name = true) const = 0;
|
||||
|
||||
friend type_or_decl_base::type_or_decl_kind
|
||||
operator|(type_or_decl_base::type_or_decl_kind,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
friend type_or_decl_base::type_or_decl_kind&
|
||||
operator|=(type_or_decl_base::type_or_decl_kind&,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
friend type_or_decl_base::type_or_decl_kind
|
||||
operator&(type_or_decl_base::type_or_decl_kind,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
friend type_or_decl_base::type_or_decl_kind&
|
||||
operator&=(type_or_decl_base::type_or_decl_kind&,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
friend class_decl*
|
||||
is_class_type(const type_or_decl_base*);
|
||||
|
||||
friend pointer_type_def*
|
||||
is_pointer_type(type_or_decl_base*);
|
||||
|
||||
friend type_base*
|
||||
is_type(const type_or_decl_base*);
|
||||
|
||||
friend decl_base*
|
||||
is_decl(const type_or_decl_base* d);
|
||||
}; // end class type_or_decl_base
|
||||
|
||||
type_or_decl_base::type_or_decl_kind
|
||||
operator|(type_or_decl_base::type_or_decl_kind,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
type_or_decl_base::type_or_decl_kind&
|
||||
operator|=(type_or_decl_base::type_or_decl_kind&,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
type_or_decl_base::type_or_decl_kind
|
||||
operator&(type_or_decl_base::type_or_decl_kind,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
type_or_decl_base::type_or_decl_kind&
|
||||
operator&=(type_or_decl_base::type_or_decl_kind&,
|
||||
type_or_decl_base::type_or_decl_kind);
|
||||
|
||||
bool
|
||||
operator==(const type_or_decl_base&, const type_or_decl_base&);
|
||||
|
||||
@ -1590,12 +1687,7 @@ class global_scope : public scope_decl
|
||||
{
|
||||
translation_unit* translation_unit_;
|
||||
|
||||
global_scope(translation_unit *tu)
|
||||
: type_or_decl_base(tu->get_environment()),
|
||||
decl_base(tu->get_environment(), "", location()),
|
||||
scope_decl(tu->get_environment(), "", location()),
|
||||
translation_unit_(tu)
|
||||
{}
|
||||
global_scope(translation_unit *tu);
|
||||
|
||||
public:
|
||||
|
||||
|
627
src/abg-ir.cc
627
src/abg-ir.cc
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user