summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Merey <[email protected]>2025-07-03 14:20:03 -0400
committerAaron Merey <[email protected]>2025-07-03 14:24:54 -0400
commit56d9896abcb8a9a648192d570635f519c4a63021 (patch)
treedf94c397429e3226b5c65297c9ed820fa45a13f4
parent7159dc3fb43fda5134461d861566ae311478231b (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.c3
-rw-r--r--libdw/dwarf_decl_file.c3
-rw-r--r--libdw/dwarf_end.c1
-rw-r--r--libdw/dwarf_getscopevar.c3
-rw-r--r--libdw/libdwP.h65
-rw-r--r--libdw/libdw_findcu.c1
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);