This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Convert uiout->levels to a vector


Currently the "levels" sub-structure of uiout is an array of fixed
length.  This patch converts that array to a vector.  This is to
remove the limitation of how many levels a uiout structure can have.

This is needed as a frame filter that elides a frame consumes one
extra uiout level per elided frame.  So if a frame elides one frame,
and that (elided) frame elides another frame (and so on) we will soon
run out of uiout levels and an assert will be triggered.  

Tested on x8664, Fedora 18 with no regressions.

Cheers,

Phil
2013-05-21  Phil Muldoon  <pmuldoon@redhat.com>

	* ui-out.c: Create typedef ui_out_level_p and define vector
	operations for that type.
	(struct ui_out): Use a vector instead of an array.
	(current_level): Return level from a vector.
	(push_level): Create a level in a vector.
	(pop_level): Delete a level in a vector.
	(ui_out_new): Create initial level zero level, and store in a
	vector.
	(ui_out_destroy): Add vector cleanup.

--
	
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 36c4b15..d702c54 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -53,6 +53,10 @@ struct ui_out_level
     enum ui_out_type type;
   };
 
+/* Define uiout->level vector types and operations.  */
+typedef struct ui_out_level *ui_out_level_p;
+DEF_VEC_P (ui_out_level_p);
+
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
    but that restriction might eventually be lifted.  */
@@ -101,9 +105,11 @@ struct ui_out
     struct ui_out_impl *impl;
     void *data;
 
-    /* Sub structure tracking the ui-out depth.  */
+    /* Current level.  */
     int level;
-    struct ui_out_level levels[MAX_UI_OUT_LEVELS];
+
+    /* Vector to store and track the ui-out levels.  */
+    VEC (ui_out_level_p) *levels;
 
     /* A table, if any.  At present only a single table is supported.  */
     struct ui_out_table table;
@@ -113,7 +119,7 @@ struct ui_out
 static struct ui_out_level *
 current_level (struct ui_out *uiout)
 {
-  return &uiout->levels[uiout->level];
+  return VEC_index (ui_out_level_p, uiout->levels, uiout->level);
 }
 
 /* Create a new level, of TYPE.  Return the new level's index.  */
@@ -124,12 +130,11 @@ push_level (struct ui_out *uiout,
 {
   struct ui_out_level *current;
 
-  /* We had better not overflow the buffer.  */
   uiout->level++;
-  gdb_assert (uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS);
-  current = current_level (uiout);
+  current = XMALLOC (struct ui_out_level);
   current->field_count = 0;
   current->type = type;
+  VEC_safe_push (ui_out_level_p, uiout->levels, current);
   return uiout->level;
 }
 
@@ -139,9 +144,13 @@ static int
 pop_level (struct ui_out *uiout,
 	   enum ui_out_type type)
 {
+  struct ui_out_level *current;
+
   /* We had better not underflow the buffer.  */
-  gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS);
+  gdb_assert (uiout->level > 0);
   gdb_assert (current_level (uiout)->type == type);
+  current = VEC_pop (ui_out_level_p, uiout->levels);
+  xfree (current);
   uiout->level--;
   return uiout->level + 1;
 }
@@ -1090,6 +1099,7 @@ ui_out_new (struct ui_out_impl *impl, void *data,
 	    int flags)
 {
   struct ui_out *uiout = XMALLOC (struct ui_out);
+  struct ui_out_level *current = XMALLOC (struct ui_out_level);
 
   uiout->data = data;
   uiout->impl = impl;
@@ -1097,7 +1107,13 @@ ui_out_new (struct ui_out_impl *impl, void *data,
   uiout->table.flag = 0;
   uiout->table.body_flag = 0;
   uiout->level = 0;
-  memset (uiout->levels, 0, sizeof (uiout->levels));
+  uiout->levels = NULL;
+
+  /* Create uiout->level 0, the default level.  */
+  current->type = ui_out_type_tuple;
+  current->field_count = 0;
+  VEC_safe_push (ui_out_level_p, uiout->levels, current);
+
   uiout->table.header_first = NULL;
   uiout->table.header_last = NULL;
   uiout->table.header_next = NULL;
@@ -1109,6 +1125,18 @@ ui_out_new (struct ui_out_impl *impl, void *data,
 void
 ui_out_destroy (struct ui_out *uiout)
 {
+  int i;
+  struct ui_out_level *current;
+
+  /* Make sure that all levels are freed in the case where levels have
+     been pushed, but not popped before the ui_out object is
+     destroyed.  */
+  for (i = 0;
+       VEC_iterate (ui_out_level_p, uiout->levels, i, current);
+       ++i)
+    xfree (current);
+
+  VEC_free (ui_out_level_p, uiout->levels);
   uo_data_destroy (uiout);
   clear_table (uiout);
   xfree (uiout);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]