From 54333c3bf8e54fd15d4d3603c3877e080542b662 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 30 Jul 2009 13:12:54 +0000 Subject: gdb/ Replace public function varobj_list by all_root_varobjs iterator. * mi/mi-cmd-var.c (struct mi_cmd_var_update, mi_cmd_var_update_iter): New. (mi_cmd_var_update): Replace the varobj_list call by all_root_varobjs. Remove the variables rootlist, cr. New variable data. * varobj.c (rootcount, varobj_list): Remove. (install_variable, uninstall_variable): Remove the rootcount updates. (all_root_varobjs): New function. (varobj_invalidate): Use the all_root_varobjs call. Move the code to... (varobj_invalidate_iter): ... a new function. * varobj.h (varobj_list): Remove the prototype. (all_root_varobjs): New prototype. --- gdb/ChangeLog | 15 +++++++ gdb/mi/mi-cmd-var.c | 64 +++++++++++++++++---------- gdb/varobj.c | 123 ++++++++++++++++++++++------------------------------ gdb/varobj.h | 3 +- 4 files changed, 111 insertions(+), 94 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b76d68a..88d23b6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2009-07-30 Jan Kratochvil + + Replace public function varobj_list by all_root_varobjs iterator. + * mi/mi-cmd-var.c (struct mi_cmd_var_update, mi_cmd_var_update_iter): + New. + (mi_cmd_var_update): Replace the varobj_list call by all_root_varobjs. + Remove the variables rootlist, cr. New variable data. + * varobj.c (rootcount, varobj_list): Remove. + (install_variable, uninstall_variable): Remove the rootcount updates. + (all_root_varobjs): New function. + (varobj_invalidate): Use the all_root_varobjs call. Move the code to... + (varobj_invalidate_iter): ... a new function. + * varobj.h (varobj_list): Remove the prototype. + (all_root_varobjs): New prototype. + 2009-07-29 Paul Pluzhnikov PR gdb/6817 diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index 55ccdbd..0cf03d9 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -566,6 +566,41 @@ mi_cmd_var_assign (char *command, char **argv, int argc) ui_out_field_string (uiout, "value", varobj_get_value (var)); } +/* Type used for parameters passing to mi_cmd_var_update_iter. */ + +struct mi_cmd_var_update + { + int only_floating; + enum print_values print_values; + }; + +/* Helper for mi_cmd_var_update - update each VAR. */ + +static void +mi_cmd_var_update_iter (struct varobj *var, void *data_pointer) +{ + struct mi_cmd_var_update *data = data_pointer; + int thread_id, thread_stopped; + + thread_id = varobj_get_thread_id (var); + + if (thread_id == -1 && is_stopped (inferior_ptid)) + thread_stopped = 1; + else + { + struct thread_info *tp = find_thread_id (thread_id); + + if (tp) + thread_stopped = is_stopped (tp->ptid); + else + thread_stopped = 1; + } + + if (thread_stopped) + if (!data->only_floating || varobj_floating_p (var)) + varobj_update_one (var, data->print_values, 0 /* implicit */); +} + void mi_cmd_var_update (char *command, char **argv, int argc) { @@ -596,31 +631,16 @@ mi_cmd_var_update (char *command, char **argv, int argc) if ((*name == '*' || *name == '@') && (*(name + 1) == '\0')) { - struct varobj **rootlist, **cr; + struct mi_cmd_var_update data; - varobj_list (&rootlist); - make_cleanup (xfree, rootlist); + data.only_floating = *name == '@'; + data.print_values = print_values; - for (cr = rootlist; *cr != NULL; cr++) - { - int thread_id = varobj_get_thread_id (*cr); - int thread_stopped = 0; + /* varobj_update_one automatically updates all the children of VAROBJ. + Therefore update each VAROBJ only once by iterating only the root + VAROBJs. */ - if (thread_id == -1 && is_stopped (inferior_ptid)) - thread_stopped = 1; - else - { - struct thread_info *tp = find_thread_id (thread_id); - if (tp) - thread_stopped = is_stopped (tp->ptid); - else - thread_stopped = 1; - } - - if (thread_stopped) - if (*name == '*' || varobj_floating_p (*cr)) - varobj_update_one (*cr, print_values, 0 /* implicit */); - } + all_root_varobjs (mi_cmd_var_update_iter, &data); } else { diff --git a/gdb/varobj.c b/gdb/varobj.c index 5d69743..4a94988 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -424,7 +424,6 @@ static int format_code[] = { 0, 't', 'd', 'x', 'o' }; /* Header of the list of root variable objects */ static struct varobj_root *rootlist; -static int rootcount = 0; /* number of root varobjs in the list */ /* Prime number indicating the number of buckets in the hash table */ /* A prime large enough to avoid too many colisions */ @@ -1169,37 +1168,6 @@ varobj_set_value (struct varobj *var, char *expression) return 1; } -/* Returns a malloc'ed list with all root variable objects */ -int -varobj_list (struct varobj ***varlist) -{ - struct varobj **cv; - struct varobj_root *croot; - int mycount = rootcount; - - /* Alloc (rootcount + 1) entries for the result */ - *varlist = xmalloc ((rootcount + 1) * sizeof (struct varobj *)); - - cv = *varlist; - croot = rootlist; - while ((croot != NULL) && (mycount > 0)) - { - *cv = croot->rootvar; - mycount--; - cv++; - croot = croot->next; - } - /* Mark the end of the list */ - *cv = NULL; - - if (mycount || (croot != NULL)) - warning - ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)", - rootcount, mycount); - - return rootcount; -} - /* Assign a new value to a variable object. If INITIAL is non-zero, this is the first assignement after the variable object was just created, or changed type. In that case, just assign the value @@ -1746,7 +1714,6 @@ install_variable (struct varobj *var) else var->root->next = rootlist; rootlist = var->root; - rootcount++; } return 1; /* OK */ @@ -1823,7 +1790,6 @@ uninstall_variable (struct varobj *var) else prer->next = cr->next; } - rootcount--; } } @@ -3206,6 +3172,24 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format) { return cplus_value_of_variable (var, format); } + +/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them + with an arbitrary caller supplied DATA pointer. */ + +void +all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data) +{ + struct varobj_root *var_root, *var_root_next; + + /* Iterate "safely" - handle if the callee deletes its passed VAROBJ. */ + + for (var_root = rootlist; var_root != NULL; var_root = var_root_next) + { + var_root_next = var_root->next; + + (*func) (var_root->rootvar, data); + } +} extern void _initialize_varobj (void); void @@ -3226,48 +3210,45 @@ When non-zero, varobj debugging is enabled."), &setlist, &showlist); } -/* Invalidate the varobjs that are tied to locals and re-create the ones that - are defined on globals. - Invalidated varobjs will be always printed in_scope="invalid". */ +/* Invalidate varobj VAR if it is tied to locals and re-create it if it is + defined on globals. It is a helper for varobj_invalidate. */ -void -varobj_invalidate (void) +static void +varobj_invalidate_iter (struct varobj *var, void *unused) { - struct varobj **all_rootvarobj; - struct varobj **varp; + /* Floating varobjs are reparsed on each stop, so we don't care if the + presently parsed expression refers to something that's gone. */ + if (var->root->floating) + return; - if (varobj_list (&all_rootvarobj) > 0) + /* global var must be re-evaluated. */ + if (var->root->valid_block == NULL) { - for (varp = all_rootvarobj; *varp != NULL; varp++) - { - /* Floating varobjs are reparsed on each stop, so we don't care if - the presently parsed expression refers to something that's gone. - */ - if ((*varp)->root->floating) - continue; + struct varobj *tmp_var; - /* global var must be re-evaluated. */ - if ((*varp)->root->valid_block == NULL) - { - struct varobj *tmp_var; - - /* Try to create a varobj with same expression. If we succeed - replace the old varobj, otherwise invalidate it. */ - tmp_var = varobj_create (NULL, (*varp)->name, (CORE_ADDR) 0, - USE_CURRENT_FRAME); - if (tmp_var != NULL) - { - tmp_var->obj_name = xstrdup ((*varp)->obj_name); - varobj_delete (*varp, NULL, 0); - install_variable (tmp_var); - } - else - (*varp)->root->is_valid = 0; - } - else /* locals must be invalidated. */ - (*varp)->root->is_valid = 0; + /* Try to create a varobj with same expression. If we succeed + replace the old varobj, otherwise invalidate it. */ + tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0, + USE_CURRENT_FRAME); + if (tmp_var != NULL) + { + tmp_var->obj_name = xstrdup (var->obj_name); + varobj_delete (var, NULL, 0); + install_variable (tmp_var); } + else + var->root->is_valid = 0; } - xfree (all_rootvarobj); - return; + else /* locals must be invalidated. */ + var->root->is_valid = 0; +} + +/* Invalidate the varobjs that are tied to locals and re-create the ones that + are defined on globals. + Invalidated varobjs will be always printed in_scope="invalid". */ + +void +varobj_invalidate (void) +{ + all_root_varobjs (varobj_invalidate_iter, NULL); } diff --git a/gdb/varobj.h b/gdb/varobj.h index c1ad099..7297243 100644 --- a/gdb/varobj.h +++ b/gdb/varobj.h @@ -137,7 +137,8 @@ extern char *varobj_get_value (struct varobj *var); extern int varobj_set_value (struct varobj *var, char *expression); -extern int varobj_list (struct varobj ***rootlist); +extern void all_root_varobjs (void (*func) (struct varobj *var, void *data), + void *data); extern VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit); -- cgit v1.1