]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf, string: delete separate movable ref storage again
authorNick Alcock <nick.alcock@oracle.com>
Mon, 13 Jan 2025 12:04:40 +0000 (12:04 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 28 Feb 2025 15:13:23 +0000 (15:13 +0000)
This was added last year to let us maintain a backpointer to the movable
refs dynhash in movable ref atoms without spending space for the
backpointer on the majority of (non-movable) refs and also without
causing an atom which had some refs movable and some refs not movable to
dereference unallocated storage when freed.

The backpointer's only purpose was to let us locate the
ctf_str_movable_refs dynhash during item freeing, when we had nothing
but a pointer to the atom being freed.  Now we have a proper freeing
arg, we don't need the backpointer at all: we can just pass a pointer to
the dict in to the atoms dynhash as a freeing arg for the atom freeing
functions, and throw the whole backpointer and separate movable ref list
complexity away.

libctf/ctf-dedup.c
libctf/ctf-impl.h
libctf/ctf-string.c

index 1e876c8a9e0287333e6a992657409a60d58c90d0..e7fcd223f0545652b3b2bd17b69ca5abd1e50666 100644 (file)
@@ -3156,8 +3156,8 @@ ctf_dedup_emit (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs,
   return outputs;
 }
 
-/* Deduplicate strings.  The child dict ctf_parent_strlen is not updated
-   yet: this must be done after parent serialization.  */
+/* Deduplicate strings.  This must be done after parent serialization.
+   The child dict ctf_parent_strlen is not updated yet.  */
 
 int
 ctf_dedup_strings (ctf_dict_t *fp)
@@ -3185,8 +3185,7 @@ ctf_dedup_strings (ctf_dict_t *fp)
          ctf_str_atom_t *atom = (ctf_str_atom_t *) v;
          uintptr_t count = 0;
 
-         if (ctf_list_empty_p (&atom->csa_refs)
-             && ctf_list_empty_p (&atom->csa_movable_refs))
+         if (ctf_list_empty_p (&atom->csa_refs))
            continue;
 
          if (atom->csa_external_offset
@@ -3222,10 +3221,7 @@ ctf_dedup_strings (ctf_dict_t *fp)
     goto iterr;
 
   /* Deduplicate the strings, adding them to the parent and transplanting
-     their ref lists there.  After transplantation, some of the movable refs
-     in the parent will contain references to a ctf_str_movable_refs hashtab
-     in the child dicts, but that's fine: it only means we can still do things
-     that involve ref movement in children without trouble.  */
+     their ref lists there.  */
 
   while ((err = ctf_dynhash_next (fp->ctf_link_outputs, &i, NULL, &dict)) == 0)
     {
@@ -3238,8 +3234,7 @@ ctf_dedup_strings (ctf_dict_t *fp)
          ctf_str_atom_t *atom = (ctf_str_atom_t *) v;
          ctf_str_atom_t *dedupped_atom;
 
-         if (ctf_list_empty_p (&atom->csa_refs)
-             && ctf_list_empty_p (&atom->csa_movable_refs))
+         if (ctf_list_empty_p (&atom->csa_refs))
              continue;
 
          if (atom->csa_external_offset
@@ -3268,8 +3263,6 @@ ctf_dedup_strings (ctf_dict_t *fp)
          /* Splice all refs into the new atom.  */
 
          ctf_list_splice (&dedupped_atom->csa_refs, &atom->csa_refs);
-         ctf_list_splice (&dedupped_atom->csa_movable_refs,
-                          &atom->csa_movable_refs);
 
          /* This atom is now "external" from the perspective of the child:
             mostly, this means the child will not try to write it to its
index 90b0b95d08c984b923b7a48c38855c2d96d6bd06..84d9d7eb4044b707a607466ebad3b2d5da220e92 100644 (file)
@@ -222,7 +222,6 @@ typedef struct ctf_str_atom
 {
   char *csa_str;               /* Pointer to string (also used as hash key).  */
   ctf_list_t csa_refs;         /* This string's refs.  */
-  ctf_list_t csa_movable_refs; /* This string's movable refs.  */
   uint32_t csa_offset;         /* Offset in this strtab, if any.  */
   uint32_t csa_external_offset;        /* External strtab offset, if any.  */
   unsigned long csa_snapshot_id; /* Snapshot ID at time of creation.  */
@@ -237,15 +236,6 @@ typedef struct ctf_str_atom_ref
   uint32_t *caf_ref;           /* A single ref to this string.  */
 } ctf_str_atom_ref_t;
 
-/* Like a ctf_str_atom_ref_t, but specific to movable refs.  */
-
-typedef struct ctf_str_atom_ref_movable
-{
-  ctf_list_t caf_list;         /* List forward/back pointers.  */
-  uint32_t *caf_ref;           /* A single ref to this string.  */
-  ctf_dynhash_t *caf_movable_refs; /* Backpointer to ctf_str_movable_refs for this dict. */  
-} ctf_str_atom_ref_movable_t;
-
 /* A single linker-provided symbol, during symbol addition, possibly before we
    have been given external strtab refs.  */
 typedef struct ctf_in_flight_dynsym
index 32a6511f8a93fcae0eda81d6fdea9b349766c370..84f0e0d9e4fc70177f96d69f0d579b70134a296b 100644 (file)
@@ -156,37 +156,27 @@ ctf_strptr_validate (ctf_dict_t *fp, uint32_t name)
 
 /* Remove all refs to a given atom.  */
 static void
-ctf_str_purge_atom_refs (ctf_str_atom_t *atom)
+ctf_str_purge_atom_refs (ctf_dict_t *fp, ctf_str_atom_t *atom)
 {
   ctf_str_atom_ref_t *ref, *next;
-  ctf_str_atom_ref_movable_t *movref, *movnext;
 
   for (ref = ctf_list_next (&atom->csa_refs); ref != NULL; ref = next)
     {
       next = ctf_list_next (ref);
       ctf_list_delete (&atom->csa_refs, ref);
+      ctf_dynhash_remove (fp->ctf_str_movable_refs, ref);
       free (ref);
     }
-
-  for (movref = ctf_list_next (&atom->csa_movable_refs);
-       movref != NULL; movref = movnext)
-    {
-      movnext = ctf_list_next (movref);
-      ctf_list_delete (&atom->csa_movable_refs, movref);
-
-      ctf_dynhash_remove (movref->caf_movable_refs, movref);
-
-      free (movref);
-    }
 }
 
 /* Free an atom.  */
 static void
-ctf_str_free_atom (void *a)
+ctf_str_free_atom (void *a, void *fp_)
 {
   ctf_str_atom_t *atom = a;
+  ctf_dict_t *fp = fp_;
 
-  ctf_str_purge_atom_refs (atom);
+  ctf_str_purge_atom_refs (fp, atom);
 
   if (atom->csa_flags & CTF_STR_ATOM_FREEABLE)
     free (atom->csa_str);
@@ -210,8 +200,8 @@ ctf_str_create_atoms (ctf_dict_t *fp)
 {
   size_t i;
 
-  fp->ctf_str_atoms = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
-                                         NULL, ctf_str_free_atom);
+  fp->ctf_str_atoms = ctf_dynhash_create_arg (ctf_hash_string, ctf_hash_eq_string,
+                                             NULL, ctf_str_free_atom, fp);
   if (!fp->ctf_str_atoms)
     return -ENOMEM;
 
@@ -299,38 +289,27 @@ static ctf_str_atom_ref_t *
 aref_create (ctf_dict_t *fp, ctf_str_atom_t *atom, uint32_t *ref, int flags)
 {
   ctf_str_atom_ref_t *aref;
-  size_t s = sizeof (struct ctf_str_atom_ref);
 
-  if (flags & CTF_STR_MOVABLE)
-    s = sizeof (struct ctf_str_atom_ref_movable);
-
-  aref = malloc (s);
+  aref = malloc (sizeof (struct ctf_str_atom_ref));
 
   if (!aref)
     return NULL;
 
   aref->caf_ref = ref;
 
-  /* Movable refs get a backpointer to them in ctf_str_movable_refs, and a
-     pointer to ctf_str_movable_refs itself in the ref, for use when freeing
-     refs: they can be moved later in batches via a call to
-     ctf_str_move_refs.  */
+  /* Movable refs get a backpointer to them in ctf_str_movable_refs: they can be
+     moved later in batches via a call to ctf_str_move_refs.  */
 
   if (flags & CTF_STR_MOVABLE)
     {
-      ctf_str_atom_ref_movable_t *movref = (ctf_str_atom_ref_movable_t *) aref;
-
-      movref->caf_movable_refs = fp->ctf_str_movable_refs;
-
       if (ctf_dynhash_insert (fp->ctf_str_movable_refs, ref, aref) < 0)
        {
          free (aref);
          return NULL;
        }
-      ctf_list_append (&atom->csa_movable_refs, movref);
     }
-  else
-    ctf_list_append (&atom->csa_refs, aref);
+
+  ctf_list_append (&atom->csa_refs, aref);
 
   return aref;
 }
@@ -584,7 +563,7 @@ ctf_str_add_external (ctf_dict_t *fp, const char *str, uint32_t offset)
    refs backpointer for this, because it is done an amortized-constant
    number of times during structure member and enumerand addition, and if we
    did a linear search this would turn such addition into an O(n^2)
-   operation.  Even this is not linear, but it's better than that.  */
+   operation.  */
 int
 ctf_str_move_refs (ctf_dict_t *fp, void *src, size_t len, void *dest)
 {
@@ -595,7 +574,7 @@ ctf_str_move_refs (ctf_dict_t *fp, void *src, size_t len, void *dest)
 
   for (p = (uintptr_t) src; p - (uintptr_t) src < len; p++)
     {
-      ctf_str_atom_ref_movable_t *ref;
+      ctf_str_atom_ref_t *ref;
 
       if ((ref = ctf_dynhash_lookup (fp->ctf_str_movable_refs,
                                     (ctf_str_atom_ref_t *) p)) != NULL)
@@ -620,7 +599,6 @@ void
 ctf_str_remove_ref (ctf_dict_t *fp, const char *str, uint32_t *ref)
 {
   ctf_str_atom_ref_t *aref, *anext;
-  ctf_str_atom_ref_movable_t *amovref, *amovnext;
   ctf_str_atom_t *atom = NULL;
 
   atom = ctf_dynhash_lookup (fp->ctf_str_atoms, str);
@@ -636,18 +614,6 @@ ctf_str_remove_ref (ctf_dict_t *fp, const char *str, uint32_t *ref)
          free (aref);
        }
     }
-
-  for (amovref = ctf_list_next (&atom->csa_movable_refs);
-       amovref != NULL; amovref = amovnext)
-    {
-      amovnext = ctf_list_next (amovref);
-      if (amovref->caf_ref == ref)
-       {
-         ctf_list_delete (&atom->csa_movable_refs, amovref);
-         ctf_dynhash_remove (fp->ctf_str_movable_refs, ref);
-         free (amovref);
-       }
-    }
 }
 
 /* A ctf_dynhash_iter_remove() callback that removes atoms later than a given
@@ -674,18 +640,19 @@ ctf_str_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
 /* An adaptor around ctf_purge_atom_refs.  */
 static void
 ctf_str_purge_one_atom_refs (void *key _libctf_unused_, void *value,
-                            void *arg _libctf_unused_)
+                            void *arg)
 {
   ctf_str_atom_t *atom = (ctf_str_atom_t *) value;
+  ctf_dict_t *fp = (ctf_dict_t *) arg;
 
-  ctf_str_purge_atom_refs (atom);
+  ctf_str_purge_atom_refs (fp, atom);
 }
 
 /* Remove all the recorded refs from the atoms table.  */
 void
 ctf_str_purge_refs (ctf_dict_t *fp)
 {
-  ctf_dynhash_iter (fp->ctf_str_atoms, ctf_str_purge_one_atom_refs, NULL);
+  ctf_dynhash_iter (fp->ctf_str_atoms, ctf_str_purge_one_atom_refs, fp);
 }
 
 /* Update a list of refs to the specified value. */
@@ -693,15 +660,10 @@ static void
 ctf_str_update_refs (ctf_str_atom_t *refs, uint32_t value)
 {
   ctf_str_atom_ref_t *ref;
-  ctf_str_atom_ref_movable_t *movref;
 
   for (ref = ctf_list_next (&refs->csa_refs); ref != NULL;
        ref = ctf_list_next (ref))
     *(ref->caf_ref) = value;
-
-  for (movref = ctf_list_next (&refs->csa_movable_refs);
-       movref != NULL; movref = ctf_list_next (movref))
-    *(movref->caf_ref) = value;
 }
 
 /* Sort the strtab.  */
@@ -817,8 +779,7 @@ ctf_str_write_strtab (ctf_dict_t *fp)
        goto err_strtab;
 
       if (atom->csa_str[0] == 0 || atom->csa_external_offset
-         || (ctf_list_empty_p (&atom->csa_refs)
-             && ctf_list_empty_p (&atom->csa_movable_refs)))
+         || ctf_list_empty_p (&atom->csa_refs))
        continue;
 
       strtab->cts_len += strlen (atom->csa_str) + 1;
@@ -854,8 +815,7 @@ ctf_str_write_strtab (ctf_dict_t *fp)
        goto err_sorttab;
 
       if (atom->csa_str[0] == 0 || atom->csa_external_offset
-         || (ctf_list_empty_p (&atom->csa_refs)
-             && ctf_list_empty_p (&atom->csa_movable_refs)))
+         || ctf_list_empty_p (&atom->csa_refs))
        continue;
 
       sorttab[i++] = atom;
@@ -904,8 +864,7 @@ ctf_str_write_strtab (ctf_dict_t *fp)
       ctf_str_atom_t *atom = (ctf_str_atom_t *) v;
       uint32_t offset;
 
-      if (ctf_list_empty_p (&atom->csa_refs) &&
-         ctf_list_empty_p (&atom->csa_movable_refs))
+      if (ctf_list_empty_p (&atom->csa_refs))
        continue;
 
       if (atom->csa_external_offset)