#549: Kill UnionVal
-------------------------+--------------------------------------------------
Reporter: whiteknight | Owner:
Type: todo | Status: new
Priority: normal | Milestone:
Component: none | Version:
Severity: medium | Keywords: UnionVal
Lang: | Patch:
Platform: |
-------------------------+--------------------------------------------------
Comment(by doughera):
There is additional discussion of this ticket on the parrot-dev maililng
list,
starting at
[http://lists.parrot.org/pipermail/parrot-dev/2009-July/002627.html].
In summary, Whiteknight suggested the following:
{{{
In the long term, I suspect PMCs will look like this:
struct PMC {
Parrot_UInt flags;
VTABLE *vtable;
DPOINTER *data;
struct PMC_EXT *pmc_ext;
};
Or maybe this, if PMC_EXT is common enough that we can prevent it from
being a separate structure:
struct PMC {
Parrot_UInt flags;
VTABLE *vtable;
DPOINTER *data;
PMC *metadata;
struct _Sync *synchronize;
};
STRING will look like this:
struct parrot_string_t {
Parrot_UInt flags;
char *strstart;
void *_bufstart;
UINTVAL _buflen;
UINTVAL bufused;
UINTVAL strlen;
UINTVAL hashval;
const struct _encoding *encoding;
const struct _charset *charset;
};
}}}
In attempting to think through the implications, I drew up the following
notes for one way I thought all the different pieces might fit together.
Apologies in advance if I get the details wrong.
We start with the following basic structures:
{{{
/* From include/parrot/pobj.h */
typedef struct pobj_t {
Parrot_UInt flags;
} pobj_t;
struct PMC {
Parrot_UInt flags;
VTABLE *vtable;
DPOINTER *data;
struct PMC_EXT *pmc_ext;
};
}}}
When a PMC is no longer needed, the following function in src/gc/gc_ms.c
is called to add it to the free list:
{{{
static void
gc_ms_add_free_object(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool),
ARGIN(void *to_add))
{
ASSERT_ARGS(gc_ms_add_free_object)
PObj *object = (PObj *)to_add;
PObj_flags_SETTO(object, PObj_on_free_list_FLAG);
((GC_MS_PObj_Wrapper*)object)->next_ptr = (PObj *)pool->free_list;
pool->free_list = object;
}
}}}
The {{{ GC_MS_PObj_Wrapper }}} structure is currently defined in
src/gc/gc_private.h as
{{{
typedef union GC_MS_PObj_Wrapper {
PObj obj;
PObj *next_ptr;
} GC_MS_PObj_Wrapper;
}}}
The intent is to take an existing field of a PObj-derived structure and
use it to hold the pool->free_list pointer. Currently, it overwrites
the UnionVal location. With the proposed layout, the flags would be
overwritten, but presumably the GC_MS_PObj_Wrapper structure would be
adjusted to match the new structure layouts.
A related issue has to do with the many calls to POBj_bufstart()
and POBj_buflen(). Not every PMC needs a bufstart or buflen field,
so those won't be available in the pobj_t structure anymore.
What this seems to imply is a somewhat richer hierarchy of structures
than exists now. Specifically, right now, pobj_t and Buffer structures
are identical. It might make sense to change that. pobj_t would still
be the "base class for all others", and Buffer would be the "base class"
used for structures that need the bufstart and buflen members.
Perhaps something like this:
{{{
/* Parrot Object - base class for all others */
typedef struct pobj_t {
Parrot_UInt flags;
} pobj_t;
typedef pobj_t PObj;
struct PMC {
Parrot_UInt flags;
VTABLE *vtable;
DPOINTER *data;
struct PMC_EXT *pmc_ext;
};
/* plain Buffer is the base class for all "buffer-like"
parrot objects.
*/
typedef struct Buffer {
Parrot_UInt flags;
void *_bufstart;
UINTVAL _buflen;
} Buffer;
struct parrot_string_t {
Parrot_UInt flags;
void *_bufstart;
UINTVAL _buflen;
char *strstart;
UINTVAL bufused;
UINTVAL strlen;
UINTVAL hashval;
const struct _encoding *encoding;
const struct _charset *charset;
};
}}}
(Note I've rearranged the first few elements of parrot_string_t to
be isomorphic with Buffer.)
Over in src/gc/gc_private.h, the Wrapper structure becomes
{{{
typedef struct GC_MS_PObj_Wrapper {
Parrot_UInt flags;
PObj *next_ptr;
} GC_MS_PObj_Wrapper;
}}}
where the next_ptr overlays either vtable in a PMC or
_bufstart in a "Buffer-like" structure.
Then the PObj_buflen() and PObj_bufstart macros would be defined as:
{{{
#define PObj_bufstart(b) (b)->_bufstart
#define PObj_buflen(b) (b)->_buflen
}}}
with the new requirement that they can only be used on "Buffer-like"
objects, not on PMCs or PObjs.
Thanks to WhiteKnight for explaining this task in more detail.
--
Ticket URL: <https://trac.parrot.org/parrot/ticket/549#comment:6>
Parrot <https://trac.parrot.org/parrot/>
Parrot Development
_______________________________________________
parrot-tickets mailing list
[email protected]
http://lists.parrot.org/mailman/listinfo/parrot-tickets