This is the mail archive of the gdb-patches@sources.redhat.com 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, rfc] Give gdbarch an obstack part 1 of 2


Hello,

This patch adds an obstack to the per-architecture object. If per-architecture code needs to allocate extra per-architecture memory they can just grab it from the obstack knowing that, should the architecture ever be discarded then so too will the memory.

This eliminates the need to include a free method in per-architecture data, and makes memory management for this part of gdb more consistent with other parts (namely the symbol table).

I'll look to commit in a week, and then follow up with a patch to convert the clients to using the obstack-alloc instead of xmalloc.

comments,
Andrew
2003-07-15  Andrew Cagney  <cagney@redhat.com>

	* gdbarch.c Include "gdb_obstack.h".
	(struct gdbarch): Add an "obstack".
	(alloc_gdbarch_data): Allocate the gdbarch data using
	GDBARCH_OBSTACK_CALLOC.
	(free_gdbarch_data): Delete function.
	(gdbarch_obstack_zalloc): New function.
	(gdbarch_free): Free the obstack, do not call free_gdbarch_data.
	Assert that the architecture is not initialized.
	(gdbarch_alloc): Allocate an obstack, allocate the architecture
	vector from the obstack.
	(alloc_gdbarch_data, init_gdbarch_swap): Allocate memory using the
	architecture obstack.
	(GDBARCH_OBSTACK_CALLOC, GDBARCH_OBSTACK_ZALLOC): Define.
	(set_gdbarch_data): Assert that the data is not initialized.
	(struct gdbarch_data): Delete member "free".
	(register_gdbarch_data): Do not initialize "free".
	* gdbarch.h, gdbarch.c: Re-generate.
	
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.235
diff -u -r1.235 gdbarch.c
--- gdbarch.c	11 Jul 2003 01:35:54 -0000	1.235
+++ gdbarch.c	16 Jul 2003 02:07:02 -0000
@@ -67,12 +67,12 @@
 #include "reggroups.h"
 #include "osabi.h"
 #include "symfile.h"		/* For entry_point_address.  */
+#include "gdb_obstack.h"
 
 /* Static function declarations */
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
 static void alloc_gdbarch_data (struct gdbarch *);
-static void free_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_swap (struct gdbarch *);
 static void clear_gdbarch_swap (struct gdbarch *);
 static void swapout_gdbarch_swap (struct gdbarch *);
@@ -92,6 +92,12 @@
 {
   /* Has this architecture been fully initialized?  */
   int initialized_p;
+
+  /* An obstack bound to the lifetime of the architecture.
+     Everything, including the architecture's ``struct gdbarch'' (but
+     obviously including the obstack) is allocated using this.  */
+  struct obstack *obstack;
+
   /* basic architectural information */
   const struct bfd_arch_info * bfd_arch_info;
   int byte_order;
@@ -292,6 +298,7 @@
 struct gdbarch startup_gdbarch =
 {
   1, /* Always initialized.  */
+  NULL, /* The obstack.  */
   /* basic architecture information */
   &bfd_default_arch_struct,  /* bfd_arch_info */
   BFD_ENDIAN_BIG,  /* byte_order */
@@ -479,8 +486,15 @@
      architecture.  This ensures that the new architectures initial
      values are not influenced by the previous architecture.  Once
      everything is parameterised with gdbarch, this will go away.  */
-  struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+  struct gdbarch *current_gdbarch;
+
+  /* Create an obstack for allocating all the per-architecture memory,
+     then use that to allocate the architecture vector.  */
+  struct obstack *obstack = XMALLOC (struct obstack);
+  obstack_init (obstack);
+  current_gdbarch = obstack_alloc (obstack, sizeof (*current_gdbarch));
   memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+  current_gdbarch->obstack = obstack;
 
   alloc_gdbarch_data (current_gdbarch);
 
@@ -568,6 +582,17 @@
 }
 
 
+/* Allocate extra space using the per-architecture obstack.  */
+
+void *
+gdbarch_obstack_zalloc (struct gdbarch *arch, long size)
+{
+  void *data = obstack_alloc (arch->obstack, size);
+  memset (data, 0, size);
+  return data;
+}
+
+
 /* Free a gdbarch struct.  This should never happen in normal
    operation --- once you've created a gdbarch, you keep it around.
    However, if an architecture's init function encounters an error
@@ -577,9 +602,12 @@
 void
 gdbarch_free (struct gdbarch *arch)
 {
+  struct obstack *obstack;
   gdb_assert (arch != NULL);
-  free_gdbarch_data (arch);
-  xfree (arch);
+  gdb_assert (!arch->initialized_p);
+  obstack = arch->obstack;
+  obstack_free (obstack, 0); /* Includes the ARCH.  */
+  xfree (obstack);
 }
 
 
@@ -5650,7 +5678,6 @@
   unsigned index;
   int init_p;
   gdbarch_data_init_ftype *init;
-  gdbarch_data_free_ftype *free;
 };
 
 struct gdbarch_data_registration
@@ -5685,7 +5712,6 @@
   (*curr)->data->index = gdbarch_data_registry.nr++;
   (*curr)->data->init = init;
   (*curr)->data->init_p = 1;
-  (*curr)->data->free = free;
   return (*curr)->data;
 }
 
@@ -5697,31 +5723,9 @@
 {
   gdb_assert (gdbarch->data == NULL);
   gdbarch->nr_data = gdbarch_data_registry.nr;
-  gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
-}
-
-static void
-free_gdbarch_data (struct gdbarch *gdbarch)
-{
-  struct gdbarch_data_registration *rego;
-  gdb_assert (gdbarch->data != NULL);
-  for (rego = gdbarch_data_registry.registrations;
-       rego != NULL;
-       rego = rego->next)
-    {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->free != NULL && gdbarch->data[data->index] != NULL)
-        {
-          data->free (gdbarch, gdbarch->data[data->index]);
-          gdbarch->data[data->index] = NULL;
-        }
-    }
-  xfree (gdbarch->data);
-  gdbarch->data = NULL;
+  gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *);
 }
 
-
 /* Initialize the current value of the specified per-architecture
    data-pointer. */
 
@@ -5731,11 +5735,7 @@
                   void *pointer)
 {
   gdb_assert (data->index < gdbarch->nr_data);
-  if (gdbarch->data[data->index] != NULL)
-    {
-      gdb_assert (data->free != NULL);
-      data->free (gdbarch, gdbarch->data[data->index]);
-    }
+  gdb_assert (gdbarch->data[data->index] == NULL);
   gdbarch->data[data->index] = pointer;
 }
 
@@ -5832,9 +5832,9 @@
     {
       if (rego->data != NULL)
 	{
-	  (*curr) = XMALLOC (struct gdbarch_swap);
+	  (*curr) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdbarch_swap);
 	  (*curr)->source = rego;
-	  (*curr)->swap = xmalloc (rego->sizeof_data);
+	  (*curr)->swap = gdbarch_obstack_zalloc (gdbarch, rego->sizeof_data);
 	  (*curr)->next = NULL;
 	  curr = &(*curr)->next;
 	}
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.202
diff -u -r1.202 gdbarch.h
--- gdbarch.h	3 Jul 2003 22:14:41 -0000	1.202
+++ gdbarch.h	16 Jul 2003 02:07:07 -0000
@@ -3262,6 +3262,15 @@
 extern void gdbarch_free (struct gdbarch *);
 
 
+/* Helper function.  Allocate memory from the ``struct gdbarch''
+   obstack.  The memory is freed when the corresponding architecture
+   is also freed.  */
+
+extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size);
+#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE)))
+#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE)))
+
+
 /* Helper function. Force an update of the current architecture.
 
    The actual architecture selected is determined by INFO, ``(gdb) set
@@ -3283,9 +3292,7 @@
 
    The per-architecture data-pointer is either initialized explicitly
    (set_gdbarch_data()) or implicitly (by INIT() via a call to
-   gdbarch_data()).  FREE() is called to delete either an existing
-   data-pointer overridden by set_gdbarch_data() or when the
-   architecture object is being deleted.
+   gdbarch_data()).
 
    When a previously created architecture is re-selected, the
    per-architecture data-pointer for that previous architecture is
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.258
diff -u -r1.258 gdbarch.sh
--- gdbarch.sh	11 Jul 2003 03:01:38 -0000	1.258
+++ gdbarch.sh	16 Jul 2003 02:07:12 -0000
@@ -1146,6 +1146,15 @@
 extern void gdbarch_free (struct gdbarch *);
 
 
+/* Helper function.  Allocate memory from the \`\`struct gdbarch''
+   obstack.  The memory is freed when the corresponding architecture
+   is also freed.  */
+
+extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size);
+#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE)))
+#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE)))
+
+
 /* Helper function. Force an update of the current architecture.
 
    The actual architecture selected is determined by INFO, \`\`(gdb) set
@@ -1167,9 +1176,7 @@
 
    The per-architecture data-pointer is either initialized explicitly
    (set_gdbarch_data()) or implicitly (by INIT() via a call to
-   gdbarch_data()).  FREE() is called to delete either an existing
-   data-pointer overridden by set_gdbarch_data() or when the
-   architecture object is being deleted.
+   gdbarch_data()).  FREE() is ignored.
 
    When a previously created architecture is re-selected, the
    per-architecture data-pointer for that previous architecture is
@@ -1315,12 +1322,12 @@
 #include "reggroups.h"
 #include "osabi.h"
 #include "symfile.h"		/* For entry_point_address.  */
+#include "gdb_obstack.h"
 
 /* Static function declarations */
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
 static void alloc_gdbarch_data (struct gdbarch *);
-static void free_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_swap (struct gdbarch *);
 static void clear_gdbarch_swap (struct gdbarch *);
 static void swapout_gdbarch_swap (struct gdbarch *);
@@ -1343,6 +1350,10 @@
 printf "{\n"
 printf "  /* Has this architecture been fully initialized?  */\n"
 printf "  int initialized_p;\n"
+printf "\n"
+printf "  /* An obstack bound to the lifetime of the architecture.  */\n"
+printf "  struct obstack *obstack;\n"
+printf "\n"
 printf "  /* basic architectural information */\n"
 function_list | while do_read
 do
@@ -1416,6 +1427,7 @@
 printf "struct gdbarch startup_gdbarch =\n"
 printf "{\n"
 printf "  1, /* Always initialized.  */\n"
+printf "  NULL, /* The obstack.  */\n"
 printf "  /* basic architecture information */\n"
 function_list | while do_read
 do
@@ -1476,8 +1488,15 @@
      architecture.  This ensures that the new architectures initial
      values are not influenced by the previous architecture.  Once
      everything is parameterised with gdbarch, this will go away.  */
-  struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+  struct gdbarch *current_gdbarch;
+
+  /* Create an obstack for allocating all the per-architecture memory,
+     then use that to allocate the architecture vector.  */
+  struct obstack *obstack = XMALLOC (struct obstack);
+  obstack_init (obstack);
+  current_gdbarch = obstack_alloc (obstack, sizeof (*current_gdbarch));
   memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+  current_gdbarch->obstack = obstack;
 
   alloc_gdbarch_data (current_gdbarch);
 
@@ -1514,6 +1533,17 @@
 printf "\n"
 printf "\n"
 cat <<EOF
+/* Allocate extra space using the per-architecture obstack.  */
+
+void *
+gdbarch_obstack_zalloc (struct gdbarch *arch, long size)
+{
+  void *data = obstack_alloc (arch->obstack, size);
+  memset (data, 0, size);
+  return data;
+}
+
+
 /* Free a gdbarch struct.  This should never happen in normal
    operation --- once you've created a gdbarch, you keep it around.
    However, if an architecture's init function encounters an error
@@ -1523,9 +1553,12 @@
 void
 gdbarch_free (struct gdbarch *arch)
 {
+  struct obstack *obstack;
   gdb_assert (arch != NULL);
-  free_gdbarch_data (arch);
-  xfree (arch);
+  gdb_assert (!arch->initialized_p);
+  obstack = arch->obstack;
+  obstack_free (obstack, 0); /* Includes the ARCH.  */
+  xfree (obstack);
 }
 EOF
 
@@ -1838,7 +1871,6 @@
   unsigned index;
   int init_p;
   gdbarch_data_init_ftype *init;
-  gdbarch_data_free_ftype *free;
 };
 
 struct gdbarch_data_registration
@@ -1873,7 +1905,6 @@
   (*curr)->data->index = gdbarch_data_registry.nr++;
   (*curr)->data->init = init;
   (*curr)->data->init_p = 1;
-  (*curr)->data->free = free;
   return (*curr)->data;
 }
 
@@ -1885,31 +1916,9 @@
 {
   gdb_assert (gdbarch->data == NULL);
   gdbarch->nr_data = gdbarch_data_registry.nr;
-  gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+  gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *);
 }
 
-static void
-free_gdbarch_data (struct gdbarch *gdbarch)
-{
-  struct gdbarch_data_registration *rego;
-  gdb_assert (gdbarch->data != NULL);
-  for (rego = gdbarch_data_registry.registrations;
-       rego != NULL;
-       rego = rego->next)
-    {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->free != NULL && gdbarch->data[data->index] != NULL)
-        {
-          data->free (gdbarch, gdbarch->data[data->index]);
-          gdbarch->data[data->index] = NULL;
-        }
-    }
-  xfree (gdbarch->data);
-  gdbarch->data = NULL;
-}
-
-
 /* Initialize the current value of the specified per-architecture
    data-pointer. */
 
@@ -1919,11 +1928,7 @@
                   void *pointer)
 {
   gdb_assert (data->index < gdbarch->nr_data);
-  if (gdbarch->data[data->index] != NULL)
-    {
-      gdb_assert (data->free != NULL);
-      data->free (gdbarch, gdbarch->data[data->index]);
-    }
+  gdb_assert (gdbarch->data[data->index] == NULL);
   gdbarch->data[data->index] = pointer;
 }
 
@@ -2020,9 +2025,9 @@
     {
       if (rego->data != NULL)
 	{
-	  (*curr) = XMALLOC (struct gdbarch_swap);
+	  (*curr) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdbarch_swap);
 	  (*curr)->source = rego;
-	  (*curr)->swap = xmalloc (rego->sizeof_data);
+	  (*curr)->swap = gdbarch_obstack_zalloc (gdbarch, rego->sizeof_data);
 	  (*curr)->next = NULL;
 	  curr = &(*curr)->next;
 	}

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