Expand the gdbarch per-architecture data vector as needed, rather
authorJim Blandy <jimb@codesourcery.com>
Sat, 2 Jun 2001 03:50:56 +0000 (03:50 +0000)
committerJim Blandy <jimb@codesourcery.com>
Sat, 2 Jun 2001 03:50:56 +0000 (03:50 +0000)
than requiring that all per-architecture data be registered before
the first gdbarch object is allocated.
* gdbarch.sh: Changes to effect the following:
* gdbarch.c (alloc_gdbarch_data, init_gdbarch_data): Delete
declarations and definitions.
(check_gdbarch_data): New function, and declaration.
(gdbarch_alloc): Don't call alloc_gdbarch_data; leaving the fields
zero is good enough.
(free_gdbarch_data): Tolerate a null data pointer.  Free only
those data items gdbarch->data actually has allocated.
(set_gdbarch_data, gdbarch_data): Call check_gdbarch_data.
(gdbarch_update_p): No need to call init_gdbarch_data.

gdb/ChangeLog
gdb/gdbarch.c
gdb/gdbarch.sh

index 507c5c0614fbdaf6e4d86e9de2897a90c6189ad4..12cbfc50b11f2943e6e2261f8d1e6ede536d1214 100644 (file)
@@ -1,3 +1,19 @@
+2001-06-01  Jim Blandy  <jimb@redhat.com>
+
+       Expand the gdbarch per-architecture data vector as needed, rather
+       than requiring that all per-architecture data be registered before
+       the first gdbarch object is allocated.
+       * gdbarch.sh: Changes to effect the following:
+       * gdbarch.c (alloc_gdbarch_data, init_gdbarch_data): Delete
+       declarations and definitions.
+       (check_gdbarch_data): New function, and declaration.
+       (gdbarch_alloc): Don't call alloc_gdbarch_data; leaving the fields
+       zero is good enough.
+       (free_gdbarch_data): Tolerate a null data pointer.  Free only
+       those data items gdbarch->data actually has allocated.
+       (set_gdbarch_data, gdbarch_data): Call check_gdbarch_data.
+       (gdbarch_update_p): No need to call init_gdbarch_data.
+
 2001-06-01  Kevin Buettner  <kevinb@redhat.com>
 
        * ia64-tdep.c (is_float_or_hfa_type_recurse): Call check_typedef()
index 2bd957f6e018a66e80b7a73eb9c195a8b413a91a..adf2f81c2eec6cb3cd6f50492aed215b2442667a 100644 (file)
@@ -65,8 +65,7 @@
 /* Static function declarations */
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
-static void alloc_gdbarch_data (struct gdbarch *);
-static void init_gdbarch_data (struct gdbarch *);
+static void check_gdbarch_data (struct gdbarch *);
 static void free_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_swap (struct gdbarch *);
 static void swapout_gdbarch_swap (struct gdbarch *);
@@ -398,8 +397,6 @@ gdbarch_alloc (const struct gdbarch_info *info,
   struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
   memset (gdbarch, 0, sizeof (*gdbarch));
 
-  alloc_gdbarch_data (gdbarch);
-
   gdbarch->tdep = tdep;
 
   gdbarch->bfd_arch_info = info->bfd_arch_info;
@@ -4337,66 +4334,81 @@ register_gdbarch_data (gdbarch_data_init_ftype *init,
 }
 
 
-/* Walk through all the registered users initializing each in turn. */
+/* Delete GDBARCH's data vector. */
 
 static void
-init_gdbarch_data (struct gdbarch *gdbarch)
+free_gdbarch_data (struct gdbarch *gdbarch)
 {
-  struct gdbarch_data_registration *rego;
-  for (rego = gdbarch_data_registry.registrations;
-       rego != NULL;
-       rego = rego->next)
+  if (gdbarch->data != NULL)
     {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->init != NULL)
+      struct gdbarch_data_registration *rego;
+
+      for (rego = gdbarch_data_registry.registrations;
+           rego != NULL;
+           rego = rego->next)
         {
-          void *pointer = data->init (gdbarch);
-          set_gdbarch_data (gdbarch, data, pointer);
+          struct gdbarch_data *data = rego->data;
+      
+          if (data->index < gdbarch->nr_data
+              && 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;
     }
 }
 
-/* Create/delete the gdbarch data vector. */
 
+/* Make sure that GDBARCH has space for all registered per-
+   architecture data.  If not, expand the table and initialize the
+   data values.  */
 static void
-alloc_gdbarch_data (struct gdbarch *gdbarch)
+check_gdbarch_data (struct gdbarch *gdbarch)
 {
-  gdb_assert (gdbarch->data == NULL);
-  gdbarch->nr_data = gdbarch_data_registry.nr;
-  gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
-}
+  int nr_allocated = gdbarch->nr_data;
 
-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)
+  /* How many per-architecture data items are registered so far?  */
+  int nr_registered = gdbarch_data_registry.nr;
+
+  if (nr_allocated < nr_registered)
     {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->free != NULL && gdbarch->data[data->index] != NULL)
+      /* Get enough room for all registered items, not just DATA.  */
+      int new_size = sizeof (gdbarch->data[0]) * nr_registered;
+      struct gdbarch_data_registration *rego;
+      
+      /* Expand the array, or perhaps allocate it for the first time.  */
+      gdbarch->data = (void **) (gdbarch->data
+                                 ? xrealloc (gdbarch->data, new_size)
+                                 : xmalloc (new_size));
+
+      /* Record the size now allocated.  */
+      gdbarch->nr_data = nr_registered;
+
+      /* Initialize the elements we just added.  */
+      for (rego = gdbarch_data_registry.registrations;
+           rego != NULL;
+           rego = rego->next)
         {
-          data->free (gdbarch, gdbarch->data[data->index]);
-          gdbarch->data[data->index] = NULL;
+          struct gdbarch_data *data = rego->data;
+          
+          if (data->index >= nr_allocated)
+            gdbarch->data[data->index]
+              = (data->init != NULL ? data->init (gdbarch) : NULL);
         }
     }
-  xfree (gdbarch->data);
-  gdbarch->data = NULL;
 }
 
 
-/* Initialize the current value of thee specified per-architecture
-   data-pointer. */
-
 void
 set_gdbarch_data (struct gdbarch *gdbarch,
                   struct gdbarch_data *data,
                   void *pointer)
 {
+  check_gdbarch_data (gdbarch);
   gdb_assert (data->index < gdbarch->nr_data);
   if (data->free != NULL && gdbarch->data[data->index] != NULL)
     data->free (gdbarch, gdbarch->data[data->index]);
@@ -4409,6 +4421,7 @@ set_gdbarch_data (struct gdbarch *gdbarch,
 void *
 gdbarch_data (struct gdbarch_data *data)
 {
+  check_gdbarch_data (current_gdbarch);
   gdb_assert (data->index < current_gdbarch->nr_data);
   return current_gdbarch->data[data->index];
 }
@@ -4777,11 +4790,6 @@ gdbarch_update_p (struct gdbarch_info info)
      called. */
   init_gdbarch_swap (new_gdbarch);
   
-  /* Initialize the per-architecture data-pointer of all parties that
-     registered an interest in this architecture.  CURRENT_GDBARCH
-     must be updated before these modules are called. */
-  init_gdbarch_data (new_gdbarch);
-  
   if (gdbarch_debug)
     gdbarch_dump (current_gdbarch, gdb_stdlog);
 
index 14e88c30a83f12724de977dca7877379427805f9..75480900d9663e2c56efe536259b70d7459a31e0 100755 (executable)
@@ -1118,8 +1118,7 @@ cat <<EOF
 /* Static function declarations */
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
-static void alloc_gdbarch_data (struct gdbarch *);
-static void init_gdbarch_data (struct gdbarch *);
+static void check_gdbarch_data (struct gdbarch *);
 static void free_gdbarch_data (struct gdbarch *);
 static void init_gdbarch_swap (struct gdbarch *);
 static void swapout_gdbarch_swap (struct gdbarch *);
@@ -1264,8 +1263,6 @@ gdbarch_alloc (const struct gdbarch_info *info,
   struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
   memset (gdbarch, 0, sizeof (*gdbarch));
 
-  alloc_gdbarch_data (gdbarch);
-
   gdbarch->tdep = tdep;
 EOF
 printf "\n"
@@ -1631,66 +1628,81 @@ register_gdbarch_data (gdbarch_data_init_ftype *init,
 }
 
 
-/* Walk through all the registered users initializing each in turn. */
+/* Delete GDBARCH's data vector. */
 
 static void
-init_gdbarch_data (struct gdbarch *gdbarch)
+free_gdbarch_data (struct gdbarch *gdbarch)
 {
-  struct gdbarch_data_registration *rego;
-  for (rego = gdbarch_data_registry.registrations;
-       rego != NULL;
-       rego = rego->next)
+  if (gdbarch->data != NULL)
     {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->init != NULL)
+      struct gdbarch_data_registration *rego;
+
+      for (rego = gdbarch_data_registry.registrations;
+           rego != NULL;
+           rego = rego->next)
         {
-          void *pointer = data->init (gdbarch);
-          set_gdbarch_data (gdbarch, data, pointer);
+          struct gdbarch_data *data = rego->data;
+      
+          if (data->index < gdbarch->nr_data
+              && 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;
     }
 }
 
-/* Create/delete the gdbarch data vector. */
 
+/* Make sure that GDBARCH has space for all registered per-
+   architecture data.  If not, expand the table and initialize the
+   data values.  */
 static void
-alloc_gdbarch_data (struct gdbarch *gdbarch)
+check_gdbarch_data (struct gdbarch *gdbarch)
 {
-  gdb_assert (gdbarch->data == NULL);
-  gdbarch->nr_data = gdbarch_data_registry.nr;
-  gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
-}
+  int nr_allocated = gdbarch->nr_data;
 
-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)
+  /* How many per-architecture data items are registered so far?  */
+  int nr_registered = gdbarch_data_registry.nr;
+
+  if (nr_allocated < nr_registered)
     {
-      struct gdbarch_data *data = rego->data;
-      gdb_assert (data->index < gdbarch->nr_data);
-      if (data->free != NULL && gdbarch->data[data->index] != NULL)
+      /* Get enough room for all registered items, not just DATA.  */
+      int new_size = sizeof (gdbarch->data[0]) * nr_registered;
+      struct gdbarch_data_registration *rego;
+      
+      /* Expand the array, or perhaps allocate it for the first time.  */
+      gdbarch->data = (void **) (gdbarch->data
+                                 ? xrealloc (gdbarch->data, new_size)
+                                 : xmalloc (new_size));
+
+      /* Record the size now allocated.  */
+      gdbarch->nr_data = nr_registered;
+
+      /* Initialize the elements we just added.  */
+      for (rego = gdbarch_data_registry.registrations;
+           rego != NULL;
+           rego = rego->next)
         {
-          data->free (gdbarch, gdbarch->data[data->index]);
-          gdbarch->data[data->index] = NULL;
+          struct gdbarch_data *data = rego->data;
+          
+          if (data->index >= nr_allocated)
+            gdbarch->data[data->index]
+              = (data->init != NULL ? data->init (gdbarch) : NULL);
         }
     }
-  xfree (gdbarch->data);
-  gdbarch->data = NULL;
 }
 
 
-/* Initialize the current value of thee specified per-architecture
-   data-pointer. */
-
 void
 set_gdbarch_data (struct gdbarch *gdbarch,
                   struct gdbarch_data *data,
                   void *pointer)
 {
+  check_gdbarch_data (gdbarch);
   gdb_assert (data->index < gdbarch->nr_data);
   if (data->free != NULL && gdbarch->data[data->index] != NULL)
     data->free (gdbarch, gdbarch->data[data->index]);
@@ -1703,6 +1715,7 @@ set_gdbarch_data (struct gdbarch *gdbarch,
 void *
 gdbarch_data (struct gdbarch_data *data)
 {
+  check_gdbarch_data (current_gdbarch);
   gdb_assert (data->index < current_gdbarch->nr_data);
   return current_gdbarch->data[data->index];
 }
@@ -2071,11 +2084,6 @@ gdbarch_update_p (struct gdbarch_info info)
      called. */
   init_gdbarch_swap (new_gdbarch);
   
-  /* Initialize the per-architecture data-pointer of all parties that
-     registered an interest in this architecture.  CURRENT_GDBARCH
-     must be updated before these modules are called. */
-  init_gdbarch_data (new_gdbarch);
-  
   if (gdbarch_debug)
     gdbarch_dump (current_gdbarch, gdb_stdlog);