This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[type-refcount] [commit] Implement TYPEs reference counting forVAROBJs.
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: archer at sourceware dot org
- Date: Fri, 13 Mar 2009 15:33:10 +0100
- Subject: [type-refcount] [commit] Implement TYPEs reference counting forVAROBJs.
commit 79ec68e9e31e73cb97eb9832fbf41baea3acdacc
It fixes a regression for gdb.mi/mi-var-invalidate.exp on the both derived
branches [archer-jankratochvil-vla] and [archer-jankratochvil-python].
Types copying should not be needed in principle as VAROBJ in a file being
free_objfile()d should be also deleted. This would mean varobj_invalidate()
should be called during each free_objfile(). Unfortunately varobj_invalidate()
deletes any non-global tracking VAROBJs now (even from unrelated OBJFILEs)
- that may be the reason why varobj_invalidate() is not called unconditionally
from free_objfile() as it should, there is even a notice about it in
free_objfile():
/* Not all our callers call clear_symtab_users (objfile_purge_solibs,
for example), so we need to call this here. */
clear_pc_function_cache ();
Such call is for example present at syms_from_objfile() - the cleanup chain is
not executed anywhere soon creating the stale references state:
if (mainline)
{
/* We will modify the main symbol table, make sure that all its users
will be cleaned up if an error occurs during symbol reading. */
make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
/* Since no error yet, throw away the old symbol table. */
if (symfile_objfile != NULL)
{
free_objfile (symfile_objfile);
symfile_objfile = NULL;
}
[...]
Even with this patch free_objfile() without varobj_invalidate() still leaves
live VAROBJs with stale (pointing to the freed OBJFILE's obstack)
`varobj_root->valid_block'. Although currently `varobj_root->valid_block' is
IMO always NULL as this feature does not look to be implemented (so such stale
reference cannot happen).
After the proper OBJFILE-specific VAROBJs invalidation gets implemented this
patch could be be reverted (although it still at least keeps the inter-object
referencing coherent). VAROBJs having `varobj->root->valid_block != NULL'
should be invalidated/removed and global VAROBJs (having VALID_BLOCK == NULL)
get reevaluated from their expression string and thus their TYPEs get used from
other OBJFILEs or they get invalidated as no longer expression-parseable with
leftover OBJFILEs.
gdb/
Implement types reference counting for VAROBJs.
* value.c: Include "varobj.h".
(preserve_one_value): Remove `static'.
(preserve_values): Call also preserve_variables.
* value.h (preserve_one_value): New declaration.
* varobj.c (varobj_create): Call type_incref on `var->type'.
(preserve_variables): New function.
(create_child): Call type_incref on `child->type'.
(free_variable): Call type_decref.
(varobj_invalidate): New FIXME comment.
* varobj.h (preserve_variables): New declaration.
---
gdb/value.c | 5 ++++-
gdb/value.h | 3 +++
gdb/varobj.c | 39 +++++++++++++++++++++++++++++++++++++++
gdb/varobj.h | 2 ++
4 files changed, 48 insertions(+), 1 deletions(-)
diff --git a/gdb/value.c b/gdb/value.c
index fca7055..0002cf9 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -37,6 +37,7 @@
#include "dfp.h"
#include "objfiles.h"
#include "valprint.h"
+#include "varobj.h"
#include "python/python.h"
@@ -1086,7 +1087,7 @@ internalvar_name (struct internalvar *var)
/* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to
prevent cycles / duplicates. */
-static void
+void
preserve_one_value (struct value *value, struct objfile *objfile,
htab_t copied_types)
{
@@ -1139,6 +1140,8 @@ preserve_values (struct objfile *objfile)
for (val = values_in_python; val; val = val->next)
preserve_one_value (val, objfile, copied_types);
+ preserve_variables (objfile, copied_types);
+
htab_delete (copied_types);
}
diff --git a/gdb/value.h b/gdb/value.h
index aa43365..6bfb1d9 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -636,6 +636,9 @@ extern void typedef_print (struct type *type, struct symbol *news,
extern char *internalvar_name (struct internalvar *var);
+extern void preserve_one_value (struct value *value, struct objfile *objfile,
+ htab_t copied_types);
+
extern void preserve_values (struct objfile *);
/* From values.c */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 0147ecb..27bcf24 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -541,6 +541,7 @@ varobj_create (char *objname,
}
else
var->type = value_type (value);
+ type_incref (var->type);
install_new_value (var, value, 1 /* Initial assignment */);
@@ -1425,6 +1426,38 @@ uninstall_variable (struct varobj *var)
}
+/* Update GDB variable objects when OBJFILE is discarded; we must copy the
+ types out of the objfile. Usually varobj_invalidate (by clear_symtab_users)
+ gets called which does not require this functionality. But according to the
+ free_objfile comment this is not always the case. */
+
+void
+preserve_variables (struct objfile *objfile, htab_t copied_types)
+{
+ unsigned int index;
+
+ for (index = 0; index < VAROBJ_TABLE_SIZE; index++)
+ {
+ struct vlist *vlist;
+
+ for (vlist = varobj_table[index]; vlist; vlist = vlist->next)
+ {
+ struct varobj *var = vlist->var;
+
+ if (var->value)
+ preserve_one_value (var->value, objfile, copied_types);
+
+ if (var->type && TYPE_OBJFILE (var->type) == objfile)
+ {
+ /* No need to decref the old type here, since we know it has no
+ reference count. */
+ var->type = copy_type_recursive (var->type, copied_types);
+ type_incref (var->type);
+ }
+ }
+ }
+}
+
/* Create and install a child of the parent of the given name */
static struct varobj *
create_child (struct varobj *parent, int index, char *name)
@@ -1455,6 +1488,8 @@ create_child (struct varobj *parent, int index, char *name)
/* Otherwise, we must compute the type. */
child->type = (*child->root->lang->type_of_child) (child->parent,
child->index);
+ if (child->type)
+ type_incref (child->type);
install_new_value (child, value, 1);
return child;
@@ -1513,6 +1548,8 @@ static void
free_variable (struct varobj *var)
{
value_free (var->value);
+ if (var->type)
+ type_decref (var->type);
/* Free the expression if this is a root variable. */
if (is_root_p (var))
@@ -2784,6 +2821,8 @@ varobj_invalidate (void)
else
(*varp)->root->is_valid = 0;
}
+ /* FIXME: If VALID_BLOCK does not belong to OBJFILE being removed we
+ should keep this varobj valid. */
else /* locals must be invalidated. */
(*varp)->root->is_valid = 0;
diff --git a/gdb/varobj.h b/gdb/varobj.h
index f2cdcf8..14b978b 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -141,4 +141,6 @@ extern int varobj_editable_p (struct varobj *var);
extern int varobj_floating_p (struct varobj *var);
+extern void preserve_variables (struct objfile *objfile, htab_t copied_types);
+
#endif /* VAROBJ_H */
--
1.6.0.6