| parrotcode: Freeze and thaw functionality | |
| Contents | C |

src/pmc_freeze.c - Freeze and thaw functionality

Freeze uses the next_for_GC pointer() to remember seen PMCs.
PMCs are written as IDs (or tags),
which are calculated from their arena address.
This PMC number is multiplied by four.
The 2 low bits indicate a seen PMC or a PMC of the same type as the previous one respectively.
Thawing PMCs uses a list with (maximum) size of the amount of PMCs to keep track of retrieved PMCs.
The individual information of PMCs is frozen/thawed by their vtables.
To avoid recursion,
the whole functionality is driven by pmc->vtable->visit,
which is called for the first PMC initially.
Container PMCs call a "todo-callback" for all contained PMCs.
The individual action vtable (freeze/thaw) is then called for all todo-PMCs.
In the current implementation IMAGE_IO is a stand-in for some kind of serializer PMC which will eventually be written.
It associates a Parrot STRING with a vtable.

static void str_appendlen bytes from buffer *b to string *s.Plain ascii - for testing only:For speed reasons we mess around with the string buffers directly.No encoding of strings,
no transcoding.
static void push_ascii_integerv onto the end of the *io "stream".
static void push_ascii_numberv onto the end of the *io "stream".
static void push_ascii_string*s onto the end of the *io "stream".For testing only - no encodings and such.XXX no string delimiters - so no space allowed.
static void push_ascii_pmc*v onto the end of the *io "stream".
static INTVAL shift_ascii_integer*io "stream".
static FLOATVAL shift_ascii_number*io "stream".
static STRING *shift_ascii_string*io "stream".
static PMC *shift_ascii_pmc*io "stream".opcode_t IO Functions 
static void op_check_sizelen more bytes.
If not then the buffer is expanded.
static void op_appendb to the string *s.
static void push_opcode_integerv onto the end of the *io "stream".XXX assumes sizeof (opcode_t) == sizeof (INTVAL).
static void push_opcode_numberv onto the end of the *io "stream".
static void push_opcode_string*v onto the end of the *io "stream".
static void push_opcode_pmc*v onto the end of the *io "stream".
static INTVAL shift_opcode_integer*io "stream".TODO - The shift functions aren't portable yet.
We need to have a packfile header for wordsize and endianess.
static PMC *shift_opcode_pmc*io "stream".Note that this actually reads a PMC id,
not a PMC.
static FLOATVAL shift_opcode_number*io "stream".
static STRING *shift_opcode_string*io "stream".
static void pmc_add_extPMC_EXT to *pmc.
static void cleanup_next_for_GC_poolnext_for_GC pointers to NULL.
static void cleanup_next_for_GCnext_for_GC pointers.
static void ft_initstatic void todo_list_init*info lists.
static void freeze_pmcstatic int thaw_pmcArray
P0 = [P1=666, P2=777, P0]may look like this:
0xdf4 30 3 0xdf8 33 666 0xdf2 777 0xdf5where 30 is
class_enum_Array, 33 is class_enum_Integer, the type of the second Integer is suppressed, the repeated P0 has bit 0 set.
static void do_actionvisit_next_for_GC() and visit_todo_list() to perform the action specified in info->what.Currently only VISIT_FREEZE_NORMAL is implemented.
static PMC *thaw_create_pmcdo_thaw() to attach the vtable etc. to *pmc.
static void do_thawvisit_todo_list_thaw() to thaw and return a PMC.seen is false if this is the first time the PMC has been encountered.
static UINTVAL id_from_pmcstatic void add_pmc_next_for_GCstatic int next_for_GC_seennext_for_GC pointer generate a unique ID per PMC and freeze the ID (not the PMC address) so thaw the hash-lookup can be replaced by an array lookup then which is a lot faster.
static void add_pmc_todo_liststatic int todo_list_seenstatic void visit_next_for_GCvisit_child callbacks:Checks if the PMC was seen, generate an ID for it if not, then do the appropriate action.
static void visit_todo_liststatic void visit_todo_list_thawdo_thaw().
static void visit_loop_next_for_GCstatic void visit_loop_todo_liststatic void create_imagestatic PMC *run_thawwhat indicates what to be thawed.Thaw could use the next_for_GC pointers as todo-list too, but this would need 2 runs through the arenas to clean the next_for_GC pointers.For now it seems cheaper to use a list for remembering contained aggregates. We could of course decide dynamically, which strategy to use, e.g.: given a big image, the first thawed item is a small aggregate. This implies, it probably contains (or some big strings) more nested containers, for which the next_for_GC approach could be a win.
STRING *Parrot_freeze_at_destructnext_for_GC pointer, so its not reentrant and must not be interrupted by a DOD run.
STRING *Parrot_freezePMC *Parrot_thawthaw opcode.
PMC *Parrot_thaw_constantsPMC *Parrot_clone
The seen-hash version for freezing might go away sometimes.

Lot of discussion on p6i and docs/dev/pmc_freeze.pod.

Initial version by leo 2003.11.03 - 2003.11.07.
|
|
|