diff options
author | Aaron Merey <[email protected]> | 2025-07-03 14:20:03 -0400 |
---|---|---|
committer | Aaron Merey <[email protected]> | 2025-07-03 14:24:54 -0400 |
commit | 56d9896abcb8a9a648192d570635f519c4a63021 (patch) | |
tree | df94c397429e3226b5c65297c9ed820fa45a13f4 | |
parent | 7159dc3fb43fda5134461d861566ae311478231b (diff) |
libdwP.h: Remove abbrev_lock
Improve __libdw_dieabbrev performance by removing abbrev_lock. This
lock protects the Dwarf_Die abbrev member due to lazy loading.
Instead, eagerly load abbrev during Dwarf_Die initialization so that
the member is readonly and requires no locking.
Signed-off-by: Aaron Merey <[email protected]>
-rw-r--r-- | libdw/dwarf_begin_elf.c | 3 | ||||
-rw-r--r-- | libdw/dwarf_decl_file.c | 3 | ||||
-rw-r--r-- | libdw/dwarf_end.c | 1 | ||||
-rw-r--r-- | libdw/dwarf_getscopevar.c | 3 | ||||
-rw-r--r-- | libdw/libdwP.h | 65 | ||||
-rw-r--r-- | libdw/libdw_findcu.c | 1 |
6 files changed, 32 insertions, 44 deletions
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index 63e2805d..2a0f5f97 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -359,7 +359,6 @@ valid_p (Dwarf *result) result->fake_loc_cu->version = 4; result->fake_loc_cu->split = NULL; eu_search_tree_init (&result->fake_loc_cu->locs_tree); - rwlock_init (result->fake_loc_cu->abbrev_lock); rwlock_init (result->fake_loc_cu->split_lock); mutex_init (result->fake_loc_cu->src_lock); mutex_init (result->fake_loc_cu->str_off_base_lock); @@ -392,7 +391,6 @@ valid_p (Dwarf *result) result->fake_loclists_cu->version = 5; result->fake_loclists_cu->split = NULL; eu_search_tree_init (&result->fake_loclists_cu->locs_tree); - rwlock_init (result->fake_loclists_cu->abbrev_lock); rwlock_init (result->fake_loclists_cu->split_lock); mutex_init (result->fake_loclists_cu->src_lock); mutex_init (result->fake_loclists_cu->str_off_base_lock); @@ -430,7 +428,6 @@ valid_p (Dwarf *result) result->fake_addr_cu->version = 5; result->fake_addr_cu->split = NULL; eu_search_tree_init (&result->fake_addr_cu->locs_tree); - rwlock_init (result->fake_addr_cu->abbrev_lock); rwlock_init (result->fake_addr_cu->split_lock); mutex_init (result->fake_addr_cu->src_lock); mutex_init (result->fake_addr_cu->str_off_base_lock); diff --git a/libdw/dwarf_decl_file.c b/libdw/dwarf_decl_file.c index 1b91a4e9..03040e12 100644 --- a/libdw/dwarf_decl_file.c +++ b/libdw/dwarf_decl_file.c @@ -50,7 +50,8 @@ dwarf_decl_file (Dwarf_Die *die) Dwarf_Files *files; size_t nfiles; - if (INTUSE(dwarf_getsrcfiles) (&CUDIE (attr_mem.cu), &files, &nfiles) != 0) + Dwarf_Die cudie = CUDIE (attr_mem.cu); + if (INTUSE(dwarf_getsrcfiles) (&cudie, &files, &nfiles) != 0) return NULL; if (idx >= nfiles) diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index 979b1168..b2d36f95 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -63,7 +63,6 @@ cu_free (void *arg) struct Dwarf_CU *p = (struct Dwarf_CU *) arg; eu_search_tree_fini (&p->locs_tree, noop_free); - rwlock_fini (p->abbrev_lock); rwlock_fini (p->split_lock); mutex_fini (p->src_lock); mutex_fini (p->str_off_base_lock); diff --git a/libdw/dwarf_getscopevar.c b/libdw/dwarf_getscopevar.c index 7b1416f3..306ccae0 100644 --- a/libdw/dwarf_getscopevar.c +++ b/libdw/dwarf_getscopevar.c @@ -40,7 +40,8 @@ static int getfiles (Dwarf_Die *die, Dwarf_Files **files) { - return INTUSE(dwarf_getsrcfiles) (&CUDIE (die->cu), files, NULL); + Dwarf_Die cudie = CUDIE (die->cu); + return INTUSE(dwarf_getsrcfiles) (&cudie, files, NULL); } /* Fetch an attribute that should have a constant integer form. */ diff --git a/libdw/libdwP.h b/libdw/libdwP.h index b77db142..d0496a42 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -455,10 +455,6 @@ struct Dwarf_CU Don't access directly, call __libdw_cu_locs_base. */ Dwarf_Off locs_base; - /* Synchronize access to the abbrev member of a Dwarf_Die that - refers to this Dwarf_CU. Covers __libdw_die_abbrev. */ - rwlock_define(, abbrev_lock); - /* Synchronize access to the split member of this Dwarf_CU. Covers __libdw_find_split_unit. */ rwlock_define(, split_lock); @@ -599,23 +595,6 @@ __libdw_first_die_off_from_cu (struct Dwarf_CU *cu) cu->unit_type); } -#define CUDIE(fromcu) \ - ((Dwarf_Die) \ - { \ - .cu = (fromcu), \ - .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ - + __libdw_first_die_off_from_cu (fromcu)) \ - }) - -#define SUBDIE(fromcu) \ - ((Dwarf_Die) \ - { \ - .cu = (fromcu), \ - .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ - + (fromcu)->start + (fromcu)->subdie_offset) \ - }) - - /* Prototype of a single .debug_macro operator. */ typedef struct { @@ -824,12 +803,7 @@ __nonnull_attribute__ (1) __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) { if (unlikely (die->cu == NULL)) - { - die->abbrev = DWARF_END_ABBREV; - return DWARF_END_ABBREV; - } - - rwlock_wrlock (die->cu->abbrev_lock); + return DWARF_END_ABBREV; /* Do we need to get the abbreviation, or need to read after the code? */ if (die->abbrev == NULL || readp != NULL) @@ -839,25 +813,20 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) const unsigned char *addr = die->addr; if (addr >= (const unsigned char *) die->cu->endp) - { - die->abbrev = DWARF_END_ABBREV; - rwlock_unlock (die->cu->abbrev_lock); - return DWARF_END_ABBREV; - } + return DWARF_END_ABBREV; get_uleb128 (code, addr, die->cu->endp); if (readp != NULL) *readp = addr; - /* Find the abbreviation. */ + /* Find the abbreviation. To improve performance, this write is not + protected by a lock. It should only be reachable by a single thread + when initializing the DIE. */ if (die->abbrev == NULL) die->abbrev = __libdw_findabbrev (die->cu, code); } - Dwarf_Abbrev *result = die->abbrev; - rwlock_unlock (die->cu->abbrev_lock); - - return result; + return die->abbrev; } /* Helper functions for form handling. */ @@ -1117,6 +1086,28 @@ cu_sec_idx (struct Dwarf_CU *cu) return cu->sec_idx; } +static inline Dwarf_Die +CUDIE (Dwarf_CU *fromcu) +{ + Dwarf_Die res = {0}; + res.cu = fromcu; + res.addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf + + __libdw_first_die_off_from_cu (fromcu)); + (void) dwarf_tag (&res); /* Set .abbrev */ + return res; +} + +static inline Dwarf_Die +SUBDIE (Dwarf_CU *fromcu) +{ + Dwarf_Die res = {0}; + res.cu = fromcu; + res.addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf + + (fromcu)->start + (fromcu)->subdie_offset); + (void) dwarf_tag (&res); /* Set .abbrev */ + return res; +} + static inline bool is_cudie (Dwarf_Die *cudie) { diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 59267343..cb1c451d 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -177,7 +177,6 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->startp = data->d_buf + newp->start; newp->endp = data->d_buf + newp->end; eu_search_tree_init (&newp->locs_tree); - rwlock_init (newp->abbrev_lock); rwlock_init (newp->split_lock); mutex_init (newp->src_lock); mutex_init (newp->str_off_base_lock); |