+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()
/* 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 *);
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;
}
-/* 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]);
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];
}
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);
/* 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 *);
struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
memset (gdbarch, 0, sizeof (*gdbarch));
- alloc_gdbarch_data (gdbarch);
-
gdbarch->tdep = tdep;
EOF
printf "\n"
}
-/* 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]);
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];
}
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);