aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2009-06-22 19:50:10 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2009-06-22 19:50:10 +0000
commit07e7f39ffd43349e4e64f77c45199d865b6e7cff (patch)
treeca2e0b3b1946f9f533913ccc5fa4118608d59331
parent4463ce244d595312be683e7df686eea59a4a1987 (diff)
downloadgdb-07e7f39ffd43349e4e64f77c45199d865b6e7cff.zip
gdb-07e7f39ffd43349e4e64f77c45199d865b6e7cff.tar.gz
gdb-07e7f39ffd43349e4e64f77c45199d865b6e7cff.tar.bz2
gdb/
PR gdb/9988: * buildsym.c (block_compar): New function. (end_symtab): Replace the bubble sort by a qsort based code.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/buildsym.c55
2 files changed, 39 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2067980..ecb49bb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,10 @@
-2009-05-07 Sami Wagiaalla <swagiaal@redhat.com>
+2009-06-22 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR gdb/9988:
+ * buildsym.c (block_compar): New function.
+ (end_symtab): Replace the bubble sort by a qsort based code.
+
+2009-06-22 Sami Wagiaalla <swagiaal@redhat.com>
* MAINTAINERS (Write After Approval): Add self.
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index e7c48fe..f94c14d 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -899,6 +899,19 @@ watch_main_source_file_lossage (void)
}
}
+/* Helper function for qsort. Parametes are `struct block *' pointers,
+ function sorts them in descending order by their BLOCK_START. */
+
+static int
+block_compar (const void *ap, const void *bp)
+{
+ const struct block *a = *(const struct block **) ap;
+ const struct block *b = *(const struct block **) bp;
+
+ return ((BLOCK_START (b) > BLOCK_START (a))
+ - (BLOCK_START (b) < BLOCK_START (a)));
+}
+
/* Finish the symbol definitions for one main source file, close off
all the lexical contexts for that file (creating struct block's for
them), then make the struct symtab for that file and put it in the
@@ -952,32 +965,28 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
OBJF_REORDERED is true, then sort the pending blocks. */
if ((objfile->flags & OBJF_REORDERED) && pending_blocks)
{
- /* FIXME! Remove this horrid bubble sort and use merge sort!!! */
- int swapped;
- do
- {
- struct pending_block *pb, *pbnext;
+ unsigned count = 0;
+ struct pending_block *pb;
+ struct block **barray, **bp;
+ struct cleanup *back_to;
- pb = pending_blocks;
- pbnext = pb->next;
- swapped = 0;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ count++;
- while (pbnext)
- {
- /* swap blocks if unordered! */
+ barray = xmalloc (sizeof (*barray) * count);
+ back_to = make_cleanup (xfree, barray);
- if (BLOCK_START (pb->block) < BLOCK_START (pbnext->block))
- {
- struct block *tmp = pb->block;
- pb->block = pbnext->block;
- pbnext->block = tmp;
- swapped = 1;
- }
- pb = pbnext;
- pbnext = pbnext->next;
- }
- }
- while (swapped);
+ bp = barray;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ *bp++ = pb->block;
+
+ qsort (barray, count, sizeof (*barray), block_compar);
+
+ bp = barray;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ pb->block = *bp++;
+
+ do_cleanups (back_to);
}
/* Cleanup any undefined types that have been left hanging around