This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH 3/5] remove deleted BFDs from the archive cache
- From: Alan Modra <amodra at gmail dot com>
- To: Tom Tromey <tromey at redhat dot com>
- Cc: Binutils Development <binutils at sourceware dot org>
- Date: Sat, 4 Aug 2012 01:39:34 +0930
- Subject: Re: [PATCH 3/5] remove deleted BFDs from the archive cache
- References: <87txwknhzj.fsf@fleche.redhat.com>
On Fri, Aug 03, 2012 at 08:54:40AM -0600, Tom Tromey wrote:
> I could not find a way to look up the member BFD in its parent cache
> directly, hence the iteration.
You've made closing an archive O(n^2) on number of elements. That I
dislike enough to NAK the patch.
Here's something I hacked together to go a little further than your
patch and actually close archive member bfds when the archive is
closed. You'll see I solved the problem of looking up the member BFD
by saving the filepos in arelt_data. What I haven't done is make this
all work with thin archives, but that shouldn't be too hard.
Just a matter of adding a field to struct areltdata instead of
reusing "origin", and solving the fact that my_archive isn't set for
thin archives, I think. Care to run with this?
Index: bfd/archive.c
===================================================================
RCS file: /cvs/src/src/bfd/archive.c,v
retrieving revision 1.87
diff -u -p -r1.87 archive.c
--- bfd/archive.c 13 Jul 2012 14:22:42 -0000 1.87
+++ bfd/archive.c 3 Aug 2012 14:59:07 -0000
@@ -316,7 +316,8 @@ _bfd_look_for_bfd_in_cache (bfd *arch_bf
static hashval_t
hash_file_ptr (const void * p)
{
- return (hashval_t) (((struct ar_cache *) p)->ptr);
+ struct ar_cache *ent = (struct ar_cache *) p;
+ return (hashval_t) ent->ptr;
}
/* Returns non-zero if P1 and P2 are equal. */
@@ -422,8 +423,6 @@ get_extended_arelt_filename (bfd *arch,
}
*originp = origin;
}
- else
- *originp = 0;
return bfd_ardata (arch)->extended_names + table_index;
}
@@ -687,6 +686,7 @@ _bfd_get_elt_at_filepos (bfd *archive, f
{
n_nfd->origin = n_nfd->proxy_origin;
n_nfd->filename = filename;
+ new_areldata->origin = filepos;
}
n_nfd->arelt_data = new_areldata;
@@ -2682,3 +2682,58 @@ coff_write_armap (bfd *arch,
return TRUE;
}
+
+static int
+archive_close_worker (void **slot, void *inf ATTRIBUTE_UNUSED)
+{
+ struct ar_cache *ent = (struct ar_cache *) *slot;
+
+ bfd_close_all_done (ent->arbfd);
+ return 1;
+}
+
+bfd_boolean
+_bfd_archive_close_and_cleanup (bfd *abfd)
+{
+ if (bfd_check_format (abfd, bfd_archive))
+ {
+ bfd *nbfd;
+ bfd *next;
+ htab_t htab;
+
+ /* Close nested archives (if this bfd is a thin archive). */
+ for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
+ {
+ next = nbfd->archive_next;
+ bfd_close (nbfd);
+ }
+
+ htab = bfd_ardata (abfd)->cache;
+ if (htab)
+ {
+ htab_traverse_noresize (htab, archive_close_worker, NULL);
+ htab_delete (htab);
+ bfd_ardata (abfd)->cache = NULL;
+ }
+ }
+ else if (abfd->my_archive != NULL)
+ {
+ htab_t htab = bfd_ardata (abfd->my_archive)->cache;
+
+ if (htab)
+ {
+ struct ar_cache ent;
+ void **slot;
+ struct areltdata *ared = arch_eltdata (abfd);
+
+ ent.ptr = ared->origin;
+ slot = htab_find_slot (htab, &ent, NO_INSERT);
+ if (slot != NULL)
+ {
+ BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
+ htab_clear_slot (htab, slot);
+ }
+ }
+ }
+ return TRUE;
+}
Index: bfd/libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.99
diff -u -p -r1.99 libbfd-in.h
--- bfd/libbfd-in.h 24 Jul 2012 21:06:58 -0000 1.99
+++ bfd/libbfd-in.h 3 Aug 2012 14:59:10 -0000
@@ -232,7 +232,9 @@ int bfd_generic_stat_arch_elt
/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
-#define _bfd_generic_close_and_cleanup bfd_true
+#define _bfd_generic_close_and_cleanup _bfd_archive_close_and_cleanup
+extern bfd_boolean _bfd_archive_close_and_cleanup
+ (bfd *);
#define _bfd_generic_bfd_free_cached_info bfd_true
extern bfd_boolean _bfd_generic_new_section_hook
(bfd *, asection *);
Index: bfd/opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.69
diff -u -p -r1.69 opncls.c
--- bfd/opncls.c 29 May 2012 14:23:33 -0000 1.69
+++ bfd/opncls.c 3 Aug 2012 14:59:11 -0000
@@ -707,8 +707,6 @@ bfd_boolean
bfd_close (bfd *abfd)
{
bfd_boolean ret;
- bfd *nbfd;
- bfd *next;
if (bfd_write_p (abfd))
{
@@ -716,13 +714,6 @@ bfd_close (bfd *abfd)
return FALSE;
}
- /* Close nested archives (if this bfd is a thin archive). */
- for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
- {
- next = nbfd->archive_next;
- bfd_close (nbfd);
- }
-
if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
return FALSE;
--
Alan Modra
Australia Development Lab, IBM