From 3de722e9ab05c1b3f7bff8dd0a097152f3cb3b74 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 19 Aug 2009 10:32:49 -0300 Subject: [PATCH] dwarves: Delete list entries in reverse order It doesn't matter when using a traditional malloc/free allocator, but with obstacks we need to do it in reverse order. For the usual case where we successfully process an object this doesn't matter, as when we started using obstacks we don't traverse all the tags calling their destructors anymore, we just free the whole obstack in one go. Noticed when processing object files built from non-supported languages such as FORTRAN and Pascal, where there are some DWARF tags that are not supported, which makes the object file load to be prematurely aborted and that calls destructors for things like classes and functions that in turn free space for their parameter/member lists, which now have to be done in reverse order. We could just stop calling the destructors and then destroying the whole obstack, but I think that partially processed files are a nice feature, so keep the interface in a way that both obstacks and traditinal malloc alocators can be used. Signed-off-by: Arnaldo Carvalho de Melo --- dwarves.c | 12 ++++++------ dwarves.h | 30 ++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dwarves.c b/dwarves.c index ac35df6..6867251 100644 --- a/dwarves.c +++ b/dwarves.c @@ -49,7 +49,7 @@ static void lexblock__delete_tags(struct tag *tself, struct cu *cu) struct lexblock *self = tag__lexblock(tself); struct tag *pos, *n; - list_for_each_entry_safe(pos, n, &self->tags, node) { + list_for_each_entry_safe_reverse(pos, n, &self->tags, node) { list_del_init(&pos->node); tag__delete(pos, cu); } @@ -222,7 +222,7 @@ void namespace__delete(struct namespace *self, struct cu *cu) { struct tag *pos, *n; - namespace__for_each_tag_safe(self, pos, n) { + namespace__for_each_tag_safe_reverse(self, pos, n) { list_del_init(&pos->node); /* Look for nested namespaces */ @@ -854,7 +854,7 @@ static void type__delete_class_members(struct type *self, struct cu *cu) { struct class_member *pos, *next; - type__for_each_data_member_safe(self, pos, next) { + type__for_each_tag_safe_reverse(self, pos, next) { list_del_init(&pos->tag.node); class_member__delete(pos, cu); } @@ -882,7 +882,7 @@ static void enumerator__delete(struct enumerator *self, struct cu *cu) void enumeration__delete(struct type *self, struct cu *cu) { struct enumerator *pos, *n; - type__for_each_enumerator_safe(self, pos, n) { + type__for_each_enumerator_safe_reverse(self, pos, n) { list_del_init(&pos->tag.node); enumerator__delete(pos, cu); } @@ -989,7 +989,7 @@ void ftype__delete(struct ftype *self, struct cu *cu) if (self == NULL) return; - ftype__for_each_parameter_safe(self, pos, n) { + ftype__for_each_parameter_safe_reverse(self, pos, n) { list_del_init(&pos->tag.node); parameter__delete(pos, cu); } @@ -1254,7 +1254,7 @@ static int list__for_all_tags(struct list_head *self, struct cu *cu, { struct tag *pos, *n; - list_for_each_entry_safe(pos, n, self, node) { + list_for_each_entry_safe_reverse(pos, n, self, node) { if (tag__has_namespace(pos)) { struct namespace *space = tag__namespace(pos); diff --git a/dwarves.h b/dwarves.h index 0f7bcd8..0c67529 100644 --- a/dwarves.h +++ b/dwarves.h @@ -507,13 +507,13 @@ void namespace__delete(struct namespace *self, struct cu *cu); list_for_each_entry(pos, &(self)->tags, node) /** - * namespace__for_each_tag_safe - safely iterate thru all the tags + * namespace__for_each_tag_safe_reverse - safely iterate thru all the tags, in reverse order * @self: struct namespace instance to iterate * @pos: struct tag iterator * @n: struct class_member temp iterator */ -#define namespace__for_each_tag_safe(self, pos, n) \ - list_for_each_entry_safe(pos, n, &(self)->tags, node) +#define namespace__for_each_tag_safe_reverse(self, pos, n) \ + list_for_each_entry_safe_reverse(pos, n, &(self)->tags, node) void namespace__add_tag(struct namespace *self, struct tag *tag); @@ -657,6 +657,15 @@ void ftype__delete(struct ftype *self, struct cu *cu); #define ftype__for_each_parameter_safe(self, pos, n) \ list_for_each_entry_safe(pos, n, &(self)->parms, tag.node) +/** + * ftype__for_each_parameter_safe_reverse - safely iterate thru all the parameters, in reverse order + * @self: struct ftype instance to iterate + * @pos: struct parameter iterator + * @n: struct parameter temp iterator + */ +#define ftype__for_each_parameter_safe_reverse(self, pos, n) \ + list_for_each_entry_safe_reverse(pos, n, &(self)->parms, tag.node) + void ftype__add_parameter(struct ftype *self, struct parameter *parm); size_t ftype__fprintf(const struct ftype *self, const struct cu *cu, const char *name, const int inlined, @@ -836,14 +845,14 @@ void type__delete(struct type *self, struct cu *cu); list_for_each_entry(pos, __type__for_each_enumerator_head, tag.node) /** - * type__for_each_enumerator_safe - safely iterate thru the enumerator entries + * type__for_each_enumerator_safe_reverse - safely iterate thru the enumerator entries, in reverse order * @self: struct type instance to iterate * @pos: struct enumerator iterator * @n: struct enumerator temp iterator */ -#define type__for_each_enumerator_safe(self, pos, n) \ +#define type__for_each_enumerator_safe_reverse(self, pos, n) \ if ((self)->namespace.shared_tags) /* Do nothing */ ; else \ - list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) + list_for_each_entry_safe_reverse(pos, n, &(self)->namespace.tags, tag.node) /** * type__for_each_member - iterate thru the entries that use space @@ -894,6 +903,15 @@ void type__delete(struct type *self, struct cu *cu); continue; \ else +/** + * type__for_each_tag_safe_reverse - safely iterate thru all tags in a type, in reverse order + * @self: struct type instance to iterate + * @pos: struct class_member iterator + * @n: struct class_member temp iterator + */ +#define type__for_each_tag_safe_reverse(self, pos, n) \ + list_for_each_entry_safe_reverse(pos, n, &(self)->namespace.tags, tag.node) + void type__add_member(struct type *self, struct class_member *member); struct class_member * type__find_first_biggest_size_base_type_member(struct type *self,