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 <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2009-08-19 10:32:49 -03:00
parent d2581fa5aa
commit 3de722e9ab
2 changed files with 30 additions and 12 deletions

View File

@ -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);

View File

@ -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,