]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwP.h: Remove abbrev_lock
authorAaron Merey <amerey@redhat.com>
Thu, 3 Jul 2025 18:20:03 +0000 (14:20 -0400)
committerAaron Merey <amerey@redhat.com>
Thu, 3 Jul 2025 18:24:54 +0000 (14:24 -0400)
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 <amerey@redhat.com>
libdw/dwarf_begin_elf.c
libdw/dwarf_decl_file.c
libdw/dwarf_end.c
libdw/dwarf_getscopevar.c
libdw/libdwP.h
libdw/libdw_findcu.c

index 63e2805d3439627c2f60d7229384eb761c5b806d..2a0f5f97625108637aeb6db7a2f6364189e73f84 100644 (file)
@@ -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);
index 1b91a4e9f03e99898962f46ee16937cb5d42728f..03040e12080814d3fdd12b05ab9dd07ba012450f 100644 (file)
@@ -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)
index 979b11689edac09c466f1604333d7abab797a70e..b2d36f95dd823226ded264fd79acd1d875970ac8 100644 (file)
@@ -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);
index 7b1416f3a24d75e286eab0b9955897e6749cfa9e..306ccae0136c7d8ea2f386b49d83daac8c603a9a 100644 (file)
@@ -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.  */
index b77db1423fe0bb68e4634b9f3b1be6ebe50f0e81..d0496a428c724a0bd675d8939872dfcf249a6630 100644 (file)
@@ -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)
 {
index 592673439c488dbb20ad13b7203827017180ef8a..cb1c451d07e85411be3aa8f876abe65abef98c40 100644 (file)
@@ -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);