Make defspaces typed.

Simply "backed" and "virutal". Backed spaces have memory allocated to them
while virtual spaces do not. Virtual spaces are intended for local
variables and entity fields.
This commit is contained in:
Bill Currie 2012-12-04 14:08:51 +09:00
parent c7b2996798
commit 0585471723
5 changed files with 53 additions and 16 deletions

View file

@ -39,10 +39,18 @@
*/
//@{
typedef enum {
ds_backed, ///< data space is globally addressable (near/far/type) and
///< has backing store
ds_virtual, ///< data space has no backing store (local vars, entity
///< fields)
} ds_type_t;
/** Represent a block of memory in the progs data space.
*/
typedef struct defspace_s {
struct defspace_s *next; ///< for ALLOC
ds_type_t type; ///< basic type of defspace
struct locref_s *free_locs; ///< list of free blocks in this space
struct def_s *defs; ///< list of defs using this space
struct def_s **def_tail; ///< for appending to \a defs
@ -52,13 +60,17 @@ typedef struct defspace_s {
/** Grow the backing memory of the defspace.
This function is called when more memory is needed for the space.
The default \a grow function expands the backing memory by 1024
pr_type_t words and initializes them to 0. If null, more space cannot
be allocated and an internal error will be generated.
The default \a grow function for ds_backed defspaces expands the
backing memory by 1024 pr_type_t words and initializes them to 0.
Other defspace types do not actually allocate backing memory as it
is not needed. If null, more space cannot be allocated and an
internal error will be generated.
\param space This defspace.
\return 1 for success, 0 for failure. On failure, an internal
error will be generated.
\note Setting to null forces failure and thus an internal error.
*/
int (*grow) (struct defspace_s *space);
int qfo_space; ///< index to space in qfo spaces
@ -70,9 +82,13 @@ typedef struct defspace_s {
initialized to the default grow function so the backing memory may be
accessed after space has been allocated via defspace_alloc_loc().
\param type The type of defspace to create. Affects only the default
defspace_t::grow function: ds_backed uses a grow function
that allocates backing memory, while ds_virtual uses a
grow function that only increases defspace_t::max_size
\return The new, empty defspace.
*/
defspace_t *defspace_new (void);
defspace_t *defspace_new (ds_type_t type);
/** Allocate space from the defspace's backing memory.

View file

@ -65,7 +65,7 @@ static locref_t *free_locrefs;
#define GROW 1024
static int
grow_space (defspace_t *space)
grow_space_global (defspace_t *space)
{
int size;
@ -80,14 +80,35 @@ grow_space (defspace_t *space)
return 1;
}
static int
grow_space_virtual (defspace_t *space)
{
int size;
if (space->size <= space->max_size)
return 1;
size = space->size + GROW;
size -= size % GROW;
space->max_size = size;
return 1;
}
defspace_t *
defspace_new (void)
defspace_new (ds_type_t type)
{
defspace_t *space;
ALLOC (1024, defspace_t, spaces, space);
space->def_tail = &space->defs;
space->grow = grow_space;
space->type = type;
if (type == ds_backed) {
space->grow = grow_space_global;
} else if (type == ds_virtual) {
space->grow = grow_space_virtual;
} else {
internal_error (0, "unknown defspace type");
}
return space;
}

View file

@ -452,7 +452,7 @@ build_scope (symbol_t *fsym, symtab_t *parent)
symtab = new_symtab (parent, stab_local);
fsym->s.func->symtab = symtab;
symtab->space = defspace_new ();
symtab->space = defspace_new (ds_virtual);
current_symtab = symtab;
if (fsym->type->t.func.num_params < 0) {

View file

@ -649,10 +649,10 @@ linker_begin (void)
work_strings = strpool_new ();
work_code = codespace_new ();
work_near_data = defspace_new ();
work_far_data = defspace_new ();
work_entity_data = defspace_new ();
work_type_data = defspace_new ();
work_near_data = defspace_new (ds_backed);
work_far_data = defspace_new (ds_backed);
work_entity_data = defspace_new (ds_virtual);
work_type_data = defspace_new (ds_backed);
pr.strings = work_strings;

View file

@ -155,21 +155,21 @@ InitData (void)
line->fa.func = -1;
line->line = -1;
pr.far_data = defspace_new ();
pr.far_data = defspace_new (ds_backed);
pr.near_data = defspace_new ();
pr.near_data = defspace_new (ds_backed);
pr.near_data->data = calloc (65536, sizeof (pr_type_t));
pr.near_data->max_size = 65536;
pr.near_data->grow = 0;
pr.type_data = defspace_new ();
pr.type_data = defspace_new (ds_backed);
defspace_alloc_loc (pr.type_data, 4);// reserve space for a null descriptor
pr.symtab = new_symtab (0, stab_global);
pr.symtab->space = pr.near_data;
current_symtab = pr.symtab;
pr.entity_data = defspace_new ();
pr.entity_data = defspace_new (ds_virtual);
pr.entity_fields = new_symtab (0, stab_global);
pr.entity_fields->space = pr.entity_data;;