Skip to content
Browse files

Merge pmc_freeze_with_pmcs into trunk.

git-svn-id: https://svn.parrot.org/parrot/trunk@43706 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent 52aeb10 commit b101f2cade121e73b1f5f3b7d1f0bf691495d8f9 @darbelo darbelo committed Feb 2, 2010
View
1 MANIFEST
@@ -1428,6 +1428,7 @@ src/pmc/handle.pmc [devel]src
src/pmc/hash.pmc [devel]src
src/pmc/hashiterator.pmc [devel]src
src/pmc/hashiteratorkey.pmc [devel]src
+src/pmc/imageio.pmc [devel]src
src/pmc/integer.pmc [devel]src
src/pmc/iterator.pmc [devel]src
src/pmc/key.pmc [devel]src
View
1 PBC_COMPAT
@@ -27,6 +27,7 @@
# please insert tab separated entries at the top of the list
+6.2 2010.01.31 cotto serialization-related changes to ParrotInterpreter
6.1 2010.01.30 whiteknight remove Array PMC
6.0 2010.01.19 chromatic released 2.0.0
5.1 2009.08.06 cotto remove branch_cs opcode
View
44 include/parrot/pmc_freeze.h
@@ -14,7 +14,7 @@
#define PARROT_PMC_FREEZE_H_GUARD
struct _visit_info;
-typedef void (*visit_f)(PARROT_INTERP, ARGIN_NULLOK(PMC*), ARGIN(struct _visit_info*));
+typedef void (*visit_f)(PARROT_INTERP, ARGIN_NULLOK(PMC*), ARGIN(PMC*));
typedef enum {
VISIT_HOW_PMC_TO_VISITOR = 0x00, /* push to visitor */
@@ -40,53 +40,11 @@ typedef enum {
#define VISIT_THAW_NORMAL (VISIT_HOW_VISITOR_TO_PMC | VISIT_WHAT_PMC)
#define VISIT_THAW_CONSTANTS VISIT_THAW_NORMAL
-struct _visit_info;
-typedef INTVAL (*get_integer_f) (PARROT_INTERP, struct _visit_info*);
-typedef void (*push_integer_f) (PARROT_INTERP, struct _visit_info*, INTVAL);
-typedef void (*push_string_f) (PARROT_INTERP, struct _visit_info*, STRING*);
-typedef void (*push_number_f) (PARROT_INTERP, struct _visit_info*, FLOATVAL);
-typedef void (*push_pmc_f) (PARROT_INTERP, struct _visit_info*, PMC*);
-typedef INTVAL (*shift_integer_f) (PARROT_INTERP, struct _visit_info*);
-typedef STRING* (*shift_string_f) (PARROT_INTERP, struct _visit_info*);
-typedef FLOATVAL (*shift_number_f) (PARROT_INTERP, struct _visit_info*);
-typedef PMC* (*shift_pmc_f) (PARROT_INTERP, struct _visit_info*);
-
-typedef struct _image_funcs {
- get_integer_f get_integer;
- push_integer_f push_integer;
- push_string_f push_string;
- push_number_f push_float;
- push_pmc_f push_pmc;
- shift_integer_f shift_integer;
- shift_string_f shift_string;
- shift_number_f shift_float;
- shift_pmc_f shift_pmc;
-} image_funcs;
-
typedef enum {
EXTRA_IS_NULL,
EXTRA_IS_PROP_HASH,
} extra_flags_enum;
-typedef struct _visit_info {
- visit_f visit_pmc_now;
- size_t pos; /* current read/write position in buffer */
- Buffer *buffer;
- size_t input_length; /* */
- INTVAL what;
- PMC **thaw_ptr; /* where to thaw a new PMC */
- PMC *seen; /* seen hash */
- PMC *todo; /* todo list */
- PMC *id_list; /* seen list used by thaw */
- UINTVAL id; /* freze ID of PMC */
- INTVAL extra_flags; /* concerning to extra */
- struct PackFile *pf;
- const image_funcs *vtable;
- struct _visit_info *image_io; /* dummy backwards-compat pointer. */
-} visit_info;
-
-#define IMAGE_IO visit_info
-
#define VISIT_PMC(interp, visit, pmc) do {\
const INTVAL _visit_pmc_flags = VTABLE_get_integer((interp), (visit)); \
if (_visit_pmc_flags & VISIT_WHAT_PMC) { \
View
16 src/hash.c
@@ -55,15 +55,15 @@ static void expand_hash(PARROT_INTERP, ARGMOD(Hash *hash))
static void hash_freeze(PARROT_INTERP,
ARGIN(const Hash * const hash),
- ARGMOD(visit_info *info))
+ ARGMOD(PMC *info))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(*info);
static void hash_thaw(PARROT_INTERP,
ARGMOD(Hash *hash),
- ARGMOD(visit_info *info))
+ ARGMOD(PMC *info))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
@@ -541,7 +541,7 @@ parrot_mark_hash_both(PARROT_INTERP, ARGIN(Hash *hash))
/*
-=item C<static void hash_thaw(PARROT_INTERP, Hash *hash, visit_info *info)>
+=item C<static void hash_thaw(PARROT_INTERP, Hash *hash, PMC *info)>
Visits the contents of a hash during freeze/thaw.
@@ -552,7 +552,7 @@ C<pinfo> is the visit info, (see include/parrot/pmc_freeze.h>).
*/
static void
-hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(visit_info *info))
+hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(PMC *info))
{
ASSERT_ARGS(hash_thaw)
@@ -608,8 +608,8 @@ hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(visit_info *info))
/*
-=item C<static void hash_freeze(PARROT_INTERP, const Hash * const hash,
-visit_info *info)>
+=item C<static void hash_freeze(PARROT_INTERP, const Hash * const hash, PMC
+*info)>
Freezes hash into a string.
@@ -623,7 +623,7 @@ Use by parrot_hash_visit.
*/
static void
-hash_freeze(PARROT_INTERP, ARGIN(const Hash * const hash), ARGMOD(visit_info *info))
+hash_freeze(PARROT_INTERP, ARGIN(const Hash * const hash), ARGMOD(PMC *info))
{
ASSERT_ARGS(hash_freeze)
size_t i;
@@ -677,7 +677,7 @@ void
parrot_hash_visit(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(void *pinfo))
{
ASSERT_ARGS(parrot_hash_visit)
- visit_info* const info = (visit_info*) pinfo;
+ PMC* const info = (PMC*) pinfo;
switch (VTABLE_get_integer(interp, info)) {
case VISIT_THAW_NORMAL:
View
16 src/pmc/class.pmc
@@ -1421,7 +1421,7 @@ Returns the integer type of the class.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the class.
@@ -1431,7 +1431,7 @@ C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
/* 1) visit the attribute description hash */
VISIT_PMC_ATTR(INTERP, info, SELF, Class, attrib_metadata);
@@ -1453,15 +1453,15 @@ C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the class.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
Parrot_Class_attributes * const class_data = PARROT_CLASS(SELF);
STRING *serial_namespace = CONST_STRING(interp, "");
@@ -1483,15 +1483,15 @@ Used to archive the class.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the class.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
/* The class might already exist in the interpreter, so create it as an
* anonymous class and later decide whether to link it into the
* namespace. */
@@ -1549,15 +1549,15 @@ with functions like pmc_new and pmc_reuse, which take type ID numbers still.
/*
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Called after the class has been thawed.
=cut
*/
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);
UNUSED(info)
View
16 src/pmc/default.pmc
@@ -1043,15 +1043,15 @@ Add class C<parent> to the list of our parents.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
Used by GC to mark the PMC.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
}
/*
@@ -1070,45 +1070,45 @@ Clones this PMC. By default, this just does a freeze and thaw.
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Does nothing.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
UNUSED(info)
/* default - no action */
}
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Initializes the PMC during unarchiving.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
/* default - initialize the PMC */
SELF.init();
}
/*
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Does nothing.
=cut
*/
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
UNUSED(info)
/* default - no action */
}
View
8 src/pmc/eval.pmc
@@ -320,26 +320,26 @@ Returns the Sub PMC of the element at index C<key> or PMCNULL.
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Archives the evaled code
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Unarchives the code.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
STRING *packed = SELF.get_string();
VTABLE_push_string(INTERP, info, packed);
SUPER(info);
}
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
STRING *packed = VTABLE_shift_string(INTERP, info);
PackFile *pf;
PackFile_Segment *seg;
View
8 src/pmc/fixedbooleanarray.pmc
@@ -506,14 +506,14 @@ Return a new iterator for SELF.
=over 4
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the string.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
UINTVAL size, resize_threshold;
unsigned char * bit_array;
STRING * s;
@@ -530,14 +530,14 @@ Used to archive the string.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the string.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
{
View
12 src/pmc/fixedintegerarray.pmc
@@ -537,29 +537,29 @@ Return a new Iterator for this PMC.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the array.
C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the array.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the array.
=cut
*/
- /*VTABLE void visit(visit_info *info) {
+ /*VTABLE void visit(PMC *info) {
SUPER(info);
}*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
INTVAL *int_array;
INTVAL i, n;
@@ -573,7 +573,7 @@ Used to unarchive the array.
VTABLE_push_integer(INTERP, info, int_array[i]);
}
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
INTVAL n;
SUPER(info);
View
15 src/pmc/fixedpmcarray.pmc
@@ -690,43 +690,42 @@ of this array.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the array.
C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the array.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the array.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
INTVAL i;
const INTVAL n = VTABLE_elements(INTERP, SELF);
PMC **pos = PMC_array(SELF);
for (i = 0; i < n; ++i, ++pos) {
- info->thaw_ptr = pos;
- (info->visit_pmc_now)(INTERP, *pos, info);
+ VISIT_PMC(INTERP, info, *pos);
}
SUPER(info);
}
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
SUPER(info);
VTABLE_push_integer(INTERP, info, VTABLE_elements(INTERP, SELF));
}
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
}
View
8 src/pmc/fixedstringarray.pmc
@@ -559,14 +559,14 @@ The C<==> operation. Compares two array to hold equal elements.
=over 4
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the string.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
STRING **str_array;
UINTVAL size, i;
@@ -580,14 +580,14 @@ Used to archive the string.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the string.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
UINTVAL i, size;
STRING **str_array;
View
8 src/pmc/float.pmc
@@ -344,28 +344,28 @@ Sets C<dest> to the absolute value of SELF.
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the number.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
SUPER(info);
VTABLE_push_float(INTERP, info, SELF.get_number());
}
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the number.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
SET_ATTR_fv(INTERP, SELF, VTABLE_shift_float(INTERP, info));
}
View
12 src/pmc/hash.pmc
@@ -1078,30 +1078,30 @@ Return a new iterator for the slice PMC C<key>
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
Used during archiving to visit the elements in the hash.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
parrot_hash_visit(INTERP, (Hash *)SELF.get_pointer(), info);
SUPER(info);
}
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the hash.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
Hash * const hash = (Hash *)SELF.get_pointer();;
SUPER(info);
@@ -1112,15 +1112,15 @@ Used to archive the hash.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the hash.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
{
View
590 src/pmc/imageio.pmc
@@ -0,0 +1,590 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/imageio.pmc - ImageIO PMC
+
+=head1 DESCRIPTION
+
+Freezes and thaws other PMCs.
+
+*/
+
+#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
+
+/* when thawing a string longer then this size, we first do a GC run and then
+ * block GC - the system can't give us more headers */
+
+#define THAW_BLOCK_GC_SIZE 100000
+
+/* preallocate freeze image for aggregates with this estimation */
+#define FREEZE_BYTES_PER_ITEM 9
+
+/* macros/constants to handle packing/unpacking of PMC IDs and flags
+ * the 2 LSBs are used for flags, all other bits are used for PMC ID
+ */
+#define PackID_new(id, flags) (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3))
+#define PackID_get_PMCID(id) ((UINTVAL)(id) / 4)
+#define PackID_set_PMCID(lv, id) (lv) = PackID_new((id), PackID_get_FLAGS(lv))
+#define PackID_get_FLAGS(id) ((UINTVAL)(id) & 3)
+#define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags))
+
+enum {
+ enum_PackID_normal = 0,
+ enum_PackID_seen = 1,
+};
+
+PARROT_INLINE
+static opcode_t *
+GET_VISIT_CURSOR(PMC *pmc){
+ char *buf = (char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
+ size_t pos = PARROT_IMAGEIO(pmc)->pos;
+ return (opcode_t *)(buf + pos);
+}
+
+PARROT_INLINE
+static void
+SET_VISIT_CURSOR(PMC *pmc, char *cursor) {
+ char *bufstart = (char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
+ PARROT_IMAGEIO(pmc)->pos = (cursor - bufstart);
+}
+
+PARROT_INLINE
+static void
+INC_VISIT_CURSOR(PMC *pmc, UINTVAL inc) {
+ PARROT_IMAGEIO(pmc)->pos += inc;
+}
+
+#define BYTECODE_SHIFT_OK(pmc) PARROT_ASSERT( \
+ PARROT_IMAGEIO(pmc)->pos <= PARROT_IMAGEIO(pmc)->input_length)
+
+
+
+static void
+create_buffer(PARROT_INTERP, PMC *pmc, PMC *info)
+{
+ INTVAL len;
+
+ if (!PMC_IS_NULL(pmc)) {
+ STRING *array = CONST_STRING(interp, "array");
+ STRING *hash = CONST_STRING(interp, "hash");
+ INTVAL items = 1;
+
+ if (VTABLE_does(interp, pmc, array) || VTABLE_does(interp, pmc, hash)) {
+ items += VTABLE_elements(interp, pmc);
+ }
+ len = items * FREEZE_BYTES_PER_ITEM;
+ }
+ else
+ len = FREEZE_BYTES_PER_ITEM;
+
+ PARROT_IMAGEIO(info)->buffer =
+ (Buffer *)Parrot_gc_new_bufferlike_header(interp, sizeof (Buffer));
+ Parrot_gc_allocate_buffer_storage_aligned(interp,
+ PARROT_IMAGEIO(info)->buffer, len);
+ SET_VISIT_CURSOR(info, (char *)Buffer_bufstart(PARROT_IMAGEIO(info)->buffer));
+}
+
+
+/*
+static void ensure_buffer_size(PARROT_INTERP, PMC *io, size_t len)
+
+Checks the size of the buffer to see if it can accommodate 'len' more
+bytes. If not, expands the buffer.
+
+*/
+
+PARROT_INLINE
+static void
+ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
+{
+ Buffer *buf = PARROT_IMAGEIO(io)->buffer;
+ const size_t used = PARROT_IMAGEIO(io)->pos;
+ const int need_free = Buffer_buflen(buf) - used - len;
+
+ /* grow by factor 1.5 or such */
+ if (need_free <= 16) {
+ size_t new_size = (size_t) (Buffer_buflen(buf) * 1.5);
+ if (new_size < Buffer_buflen(buf) - need_free + 512)
+ new_size = Buffer_buflen(buf) - need_free + 512;
+ Parrot_gc_reallocate_buffer_storage(interp, buf, new_size);
+ PARROT_ASSERT(Buffer_buflen(buf) - used - len >= 15);
+ }
+
+#ifndef DISABLE_GC_DEBUG
+ Parrot_gc_compact_memory_pool(INTERP);
+#endif
+
+}
+
+PARROT_INLINE
+static INTVAL
+INFO_HAS_DATA(ARGIN(PMC *io)) {
+ return PARROT_IMAGEIO(io)->pos < PARROT_IMAGEIO(io)->input_length;
+}
+
+PARROT_INLINE
+static PMC*
+id_list_get(PARROT_INTERP, PMC *io, UINTVAL id) {
+ return VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(io)->id_list, id);
+}
+
+PARROT_INLINE
+static void
+visit_todo_list_thaw(PARROT_INTERP, SHIM(PMC* pmc_not_used), ARGIN(PMC* info))
+{
+ UINTVAL n = VTABLE_shift_integer(interp, info);
+ UINTVAL id = PackID_get_PMCID(n);
+ int packid_flags = PackID_get_FLAGS(n);
+ PMC *pmc = PMCNULL;
+
+ PARROT_ASSERT(PARROT_IMAGEIO(info)->what == VISIT_THAW_NORMAL);
+
+ switch (packid_flags) {
+ case enum_PackID_seen:
+ if (id) /* got a non-NULL PMC */
+ pmc = id_list_get(interp, info, id);
+ break;
+ case enum_PackID_normal:
+ {
+ INTVAL type = VTABLE_shift_integer(interp, info);
+ if (type <= 0 || type > interp->n_vtable_max)
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC type to thaw %d", type);
+
+ pmc = pmc_new_noinit(interp, type);
+ VTABLE_thaw(interp, pmc, info);
+
+ {
+ PMC * const todo = PARROT_IMAGEIO(info)->todo;
+ PMC * const id_list = PARROT_IMAGEIO(info)->id_list;
+ VTABLE_set_pmc_keyed_int(interp, id_list, id, pmc);
+ /* remember nested aggregates depth first */
+ VTABLE_unshift_pmc(interp, todo, pmc);
+ }
+ }
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC id args thaw %d", packid_flags);
+ break;
+ }
+
+ *(PARROT_IMAGEIO(info)->thaw_ptr) = pmc;
+}
+
+static void
+visit_todo_list_freeze(PARROT_INTERP, PMC* pmc, PMC* info)
+{
+ UINTVAL id;
+ int packid_type;
+
+ PARROT_ASSERT(PARROT_IMAGEIO(info)->what == VISIT_FREEZE_NORMAL);
+
+ if (PMC_IS_NULL(pmc)) {
+ id = 0;
+ packid_type = enum_PackID_seen;
+ }
+ else {
+ Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIO(info)->seen);
+ HashBucket * const b = parrot_hash_get_bucket(interp, hash, pmc);
+ if (b) {
+ id = (UINTVAL) b->value;
+ packid_type = enum_PackID_seen;
+ }
+ else {
+ PARROT_IMAGEIO(info)->id++; /* next id to freeze */
+ id = PARROT_IMAGEIO(info)->id;
+ packid_type = enum_PackID_normal;
+ }
+ }
+
+ VTABLE_push_integer(interp, info, PackID_new(id, packid_type));
+
+ if (packid_type == enum_PackID_normal) {
+ Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIO(info)->seen);
+ PARROT_ASSERT(pmc);
+ VTABLE_push_integer(interp, info,
+ PObj_is_object_TEST(pmc) ? enum_class_Object : pmc->vtable->base_type);
+ parrot_hash_put(interp, hash, pmc, (void *)id);
+ VTABLE_unshift_pmc(interp, PARROT_IMAGEIO(info)->todo, pmc);
+ VTABLE_freeze(interp, pmc, info);
+ }
+}
+
+static void
+visit_loop_todo_list(PARROT_INTERP, PMC *current, PMC *info)
+{
+ PMC * const todo = PARROT_IMAGEIO(info)->todo;
+ const int thawing = PARROT_IMAGEIO(info)->what == VISIT_THAW_NORMAL;
+
+ (PARROT_IMAGEIO(info)->visit_pmc_now)(interp, current, info);
+
+ /* can't cache upper limit, visit may append items */
+ while (VTABLE_get_bool(interp, todo)) {
+ current = VTABLE_shift_pmc(interp, todo);
+ if (!current)
+ Parrot_ex_throw_from_c_args(interp, NULL, 1,
+ "NULL current PMC in visit_loop_todo_list");
+
+ PARROT_ASSERT(current->vtable);
+
+ VTABLE_visit(interp, current, info);
+
+ VISIT_PMC(interp, info, PMC_metadata(current));
+ }
+
+ if (thawing)
+ /* we're done reading the image */
+ PARROT_ASSERT(!INFO_HAS_DATA(info));
+
+ if (thawing) {
+ /* on thawing call thawfinish for each processed PMC */
+ const INTVAL n = VTABLE_elements(interp, PARROT_IMAGEIO(info)->id_list);
+ int i;
+
+ /*
+ * Thaw in reverse order. We have to fully thaw younger PMCs
+ * before use them in older.
+ *
+ * XXX There are no younger or older pmcs in a directed graph
+ * that allows cycles. Any code that requires a specific
+ * order here is likely broken.
+ */
+ for (i = n-1; i >= 0; --i) {
+ current = VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(info)->id_list, i);
+ if (!PMC_IS_NULL(current))
+ VTABLE_thawfinish(interp, current, info);
+ }
+ }
+}
+
+pmclass ImageIO auto_attrs {
+ ATTR visit_f visit_pmc_now;
+ ATTR Buffer *buffer; /* buffer to store the image */
+ ATTR size_t pos; /* current read/write position in buffer */
+ ATTR size_t input_length;
+ ATTR INTVAL what;
+ ATTR PMC **thaw_ptr; /* where to thaw a new PMC */
+ ATTR PMC *seen; /* seen hash */
+ ATTR PMC *todo; /* todo list */
+ ATTR PMC *id_list; /* seen list used by thaw */
+ ATTR UINTVAL id; /* freze ID of PMC */
+ ATTR INTVAL extra_flags; /* concerning to extra */
+ ATTR struct PackFile *pf;
+
+/*
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+ VTABLE void init() {
+ PARROT_IMAGEIO(SELF)->thaw_ptr = NULL;
+ PARROT_IMAGEIO(SELF)->buffer = NULL;
+ PARROT_IMAGEIO(SELF)->todo = pmc_new(INTERP, enum_class_ResizablePMCArray);
+ PARROT_IMAGEIO(SELF)->seen = PMCNULL;
+ PARROT_IMAGEIO(SELF)->id_list = PMCNULL;
+ PARROT_IMAGEIO(SELF)->id = 0;
+ PARROT_IMAGEIO(SELF)->extra_flags = EXTRA_IS_NULL;
+ PARROT_IMAGEIO(SELF)->pf = PackFile_new(INTERP, 0);
+
+ PObj_custom_mark_destroy_SETALL(SELF);
+ }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+ VTABLE void destroy() {
+ PackFile_destroy(INTERP, PARROT_IMAGEIO(SELF)->pf);
+ }
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+ VTABLE void mark() {
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *)(PARROT_IMAGEIO(SELF)->buffer));
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->todo);
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->seen);
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->id_list);
+ }
+
+/*
+
+=item C<STRING *get_string()>
+
+Returns the content of the image as a string.
+
+=cut
+
+*/
+
+ VTABLE STRING *get_string() {
+ return Parrot_str_new_from_buffer(INTERP,
+ PARROT_IMAGEIO(SELF)->buffer,
+ PARROT_IMAGEIO(SELF)->pos);
+ }
+/*
+
+/*
+
+=item C<VTABLE void set_pointer()>
+
+Sets the location where to thaw a new PMC.
+
+=cut
+
+*/
+
+VTABLE void set_pointer(void* value) {
+ PARROT_IMAGEIO(SELF)->thaw_ptr = value;
+}
+
+/*
+
+=item C<VTABLE INTVAL get_integer()>
+
+Returns the flags describing the visit action
+
+=cut
+
+*/
+
+VTABLE INTVAL get_integer() {
+ return PARROT_IMAGEIO(SELF)->what;
+}
+
+/*
+
+=item C<VTABLE void push_integer(INTVAL v)>
+
+Pushes the integer C<v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_integer(INTVAL v) {
+ size_t len = PF_size_integer() * sizeof (opcode_t);
+ ensure_buffer_size(interp, SELF, len);
+ SET_VISIT_CURSOR(SELF, (char *)PF_store_integer(GET_VISIT_CURSOR(SELF), v));
+}
+
+
+/*
+
+=item C<VTABLE void push_float(FLOATVAL v)>
+
+Pushes the float C<v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_float(FLOATVAL v)
+{
+ size_t len = PF_size_number() * sizeof (opcode_t);
+ ensure_buffer_size(interp, SELF, len);
+ SET_VISIT_CURSOR(SELF, (char *)PF_store_number(GET_VISIT_CURSOR(SELF), &v));
+}
+
+
+/*
+
+=item C<VTABLE void push_string(STRING *v)>
+
+Pushes the string C<*v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_string(STRING *v)
+{
+ size_t len = PF_size_string(v) * sizeof (opcode_t);
+ ensure_buffer_size(INTERP, SELF, len);
+ SET_VISIT_CURSOR(SELF, (char *)PF_store_string(GET_VISIT_CURSOR(SELF), v));
+}
+
+/*
+
+=item C<VTABLE void push_pmc(PMC *v)>
+
+Pushes a reference to pmc C<*v> onto the end of the image. If C<*v>
+hasn't been seen yet, it is also pushed onto the todo list.
+
+=cut
+
+*/
+
+VTABLE void push_pmc(PMC *v) {
+ VTABLE_set_pointer(interp, SELF, &v);
+ (PARROT_IMAGEIO(SELF)->visit_pmc_now)(INTERP, v, SELF);
+}
+
+/*
+
+=item C<VTABLE INTVAL shift_integer()>
+
+Removes and returns an integer from the start of the image.
+
+=cut
+
+*/
+
+VTABLE INTVAL shift_integer()
+{
+ opcode_t *pos = GET_VISIT_CURSOR(SELF);
+ const INTVAL i = PF_fetch_integer(PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+ SET_VISIT_CURSOR(SELF, (char *)pos);
+ BYTECODE_SHIFT_OK(SELF);
+ return i;
+}
+
+
+/*
+
+=item C<VTABLE FLOATVAL shift_float()>
+
+Removes and returns an number from the start of the image.
+
+=cut
+
+*/
+
+VTABLE FLOATVAL shift_float() {
+ opcode_t *pos = GET_VISIT_CURSOR(SELF);
+ const FLOATVAL f = PF_fetch_number(PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+ SET_VISIT_CURSOR(SELF, (char *)pos);
+ BYTECODE_SHIFT_OK(SELF);
+ return f;
+}
+
+
+/*
+
+=item C<VTABLE STRING* shift_string()>
+
+Removes and returns a string from the start of the image.
+
+=cut
+
+*/
+
+VTABLE STRING *shift_string()
+{
+ opcode_t *pos = GET_VISIT_CURSOR(SELF);
+ STRING * const s = PF_fetch_string(interp, PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+ SET_VISIT_CURSOR(SELF, (char *)pos);
+ BYTECODE_SHIFT_OK(SELF);
+ return s;
+}
+
+/*
+
+=item C<static PMC *shift_pmc()>
+
+Removes and returns a reference to a pmc from the start of the image.
+
+=cut
+
+*/
+
+VTABLE PMC *shift_pmc() {
+ PMC *result;
+ VTABLE_set_pointer(interp, SELF, &result);
+ (PARROT_IMAGEIO(SELF)->visit_pmc_now)(interp, NULL, SELF);
+ return result;
+}
+
+VTABLE void set_pmc(PMC *p)
+{
+ UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+
+ PARROT_IMAGEIO(SELF)->what = VISIT_FREEZE_NORMAL;
+ PARROT_IMAGEIO(SELF)->visit_pmc_now = visit_todo_list_freeze;
+ create_buffer(INTERP, p, SELF);
+ ensure_buffer_size(INTERP, SELF, header_length);
+ mem_sys_memcopy(GET_VISIT_CURSOR(SELF),
+ PARROT_IMAGEIO(SELF)->pf->header, PACKFILE_HEADER_BYTES);
+ INC_VISIT_CURSOR(SELF, header_length);
+
+ PARROT_IMAGEIO(SELF)->seen = pmc_new(INTERP, enum_class_Hash);
+ VTABLE_set_pointer(INTERP, PARROT_IMAGEIO(SELF)->seen,
+ parrot_new_intval_hash(INTERP));
+
+ visit_loop_todo_list(INTERP, p, SELF);
+}
+
+VTABLE void set_string_native(STRING *image) {
+ UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+ int unpacked_length;
+
+ PARROT_IMAGEIO(SELF)->what = VISIT_THAW_NORMAL;
+ PARROT_IMAGEIO(SELF)->visit_pmc_now = visit_todo_list_thaw;
+ PARROT_IMAGEIO(SELF)->buffer = (Buffer *)image;
+ PARROT_IMAGEIO(SELF)->id_list = pmc_new(INTERP, enum_class_ResizablePMCArray);
+
+ PARROT_ASSERT(image->_bufstart == image->strstart);
+
+ SET_VISIT_CURSOR(SELF, (char *)Buffer_bufstart(PARROT_IMAGEIO(SELF)->buffer));
+ PARROT_IMAGEIO(SELF)->input_length = image->strlen;
+
+ PARROT_IMAGEIO(SELF)->pf->options |= PFOPT_PMC_FREEZE_ONLY;
+ unpacked_length = PackFile_unpack(interp, PARROT_IMAGEIO(SELF)->pf,
+ GET_VISIT_CURSOR(SELF), PARROT_IMAGEIO(SELF)->input_length);
+
+ if (!unpacked_length) {
+ Parrot_ex_throw_from_c_args(interp, NULL,
+ EXCEPTION_INVALID_STRING_REPRESENTATION,
+ "PackFile header failed during unpack");
+ }
+ else {
+ INC_VISIT_CURSOR(SELF, header_length);
+ }
+
+ visit_loop_todo_list(interp, pmc, SELF);
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+}
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
View
8 src/pmc/integer.pmc
@@ -1304,29 +1304,29 @@ and 36, inclusive.
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the integer.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
SUPER(info);
VTABLE_push_integer(INTERP, info, SELF.get_integer());
}
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the integer.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
}
View
16 src/pmc/key.pmc
@@ -283,35 +283,35 @@ Returns the key itself.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the Key.
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Archives the Key.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Unarchives the Key.
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Called after the Key has been thawed: convert last PMC_NULL key to NULL.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
/* Sometimes visit gets an uninitialized Key. Initialize it. */
if (!PMC_data(SELF))
SELF.init();
VISIT_PMC_ATTR(INTERP, info, SELF, Key, next_key);
}
- void freeze(visit_info *info) {
+ void freeze(PMC *info) {
/* write flags */
const INTVAL flags = (PObj_get_FLAGS(SELF) & KEY_type_FLAGS);
@@ -340,7 +340,7 @@ Called after the Key has been thawed: convert last PMC_NULL key to NULL.
}
}
- void thaw(visit_info *info) {
+ void thaw(PMC *info) {
const INTVAL flags = VTABLE_shift_integer(INTERP, info) & KEY_type_FLAGS;
PObj_get_FLAGS(SELF) |= flags;
@@ -367,7 +367,7 @@ Called after the Key has been thawed: convert last PMC_NULL key to NULL.
}
}
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
PMC *key = SELF;
UNUSED(info)
View
8 src/pmc/lexinfo.pmc
@@ -125,11 +125,11 @@ C<symbols>, which gets an array of the names of the symbols in this lexpad.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Freeze/thaw interface used during freeze/thaw of the Sub PMC.
The implementation of the Hash PMC is called.
@@ -139,7 +139,7 @@ The implementation of the Hash PMC is called.
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
const INTVAL elems = VTABLE_shift_integer(INTERP, info);
const INTVAL k_type = VTABLE_shift_integer(INTERP, info);
const INTVAL v_type = VTABLE_shift_integer(INTERP, info);
View
21 src/pmc/object.pmc
@@ -725,7 +725,7 @@ Creates a clone of the object.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the object.
@@ -735,46 +735,41 @@ C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
Parrot_Object_attributes * const obj_data = PARROT_OBJECT(SELF);
- PMC **pos;
/* 1) visit class */
- pos = &obj_data->_class;
- info->thaw_ptr = pos;
- (info->visit_pmc_now)(INTERP, *pos, info);
+ VISIT_PMC(INTERP, info, obj_data->_class);
/* 2) visit the attributes */
- pos = &obj_data->attrib_store;
- info->thaw_ptr = pos;
- (info->visit_pmc_now)(INTERP, *pos, info);
+ VISIT_PMC(INTERP, info, obj_data->attrib_store);
}
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the object.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
return;
}
/*
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Called after the object has been thawed.
=cut
*/
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
/* Set custom GC mark and destroy on the object. */
PObj_custom_mark_SET(SELF);
PObj_custom_destroy_SET(SELF);
View
10 src/pmc/orderedhash.pmc
@@ -726,28 +726,28 @@ the clone via integers has different indices, if items were deleted.
}
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
Used during archiving to visit the elements in the hash.
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the hash.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the hash.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
VISIT_PMC_ATTR(INTERP, info, SELF, OrderedHash, hash);
SUPER(info);
}
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(SELF);
find_bounds(INTERP, attrs->hash, &attrs->first, &attrs->last);
SUPER(info);
View
23 src/pmc/parrotinterpreter.pmc
@@ -658,33 +658,32 @@ have the same thread id.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the interpreter.
C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the interpreter. Actually not the whole interpreter is
frozen but the state of the interpreter, which includes everything that
has changes since creating an empty interpreter.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the interpreter. This merges the changes into this
interpreter instance.
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Finish thawing.
=cut
*/
- VTABLE void visit(visit_info *info) {
- PMC **pos;
+ VTABLE void visit(PMC *info) {
/*
* the information frozen here is part of all PBCs
* we probably need to freeze all dynamic extensible
@@ -710,16 +709,14 @@ Finish thawing.
/* HLL_info */
if (VTABLE_get_integer(INTERP, info) == VISIT_THAW_NORMAL ||
VTABLE_get_integer(INTERP, info) == VISIT_THAW_CONSTANTS) {
- pos = &PMC_args(SELF);
+ VISIT_PMC(interp, info, PMC_args(SELF));
}
else
- pos = &INTERP->HLL_info;
+ VISIT_PMC(interp, info, INTERP->HLL_info);
- info->thaw_ptr = pos;
- (info->visit_pmc_now)(INTERP, *pos, info);
}
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
if (!PMC_data(SELF)) {
Parrot_ParrotInterpreter_attributes *attrs =
mem_allocate_zeroed_typed(Parrot_ParrotInterpreter_attributes);
@@ -730,7 +727,7 @@ Finish thawing.
PMC_interp(SELF) = INTERP;
}
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
PMC * const new_info = PMC_args(SELF);
const INTVAL m = VTABLE_elements(INTERP, new_info);
INTVAL i;
@@ -845,5 +842,3 @@ This method is experimental. See TT #264.
* End:
* vim: expandtab shiftwidth=4:
*/
-
-
View
8 src/pmc/resizablebooleanarray.pmc
@@ -404,14 +404,14 @@ Returns a copy of the array.
=over 4
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the string.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
/* XXX Dino - I'm concerned about freezing the entire
allocated block of memory, it's dependent on the
BITS_PER_CHAR value.
@@ -438,14 +438,14 @@ Used to archive the string.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the string.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
unsigned char *bit_array;
const UINTVAL head_pos = VTABLE_shift_integer(INTERP, info);
const UINTVAL tail_pos = VTABLE_shift_integer(INTERP, info);
View
8 src/pmc/resizableintegerarray.pmc
@@ -279,19 +279,19 @@ Creates and returns a copy of the array.
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the array.
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the array.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
INTVAL *int_array;
INTVAL i, n, rt;
@@ -308,7 +308,7 @@ Used to unarchive the array.
VTABLE_push_integer(INTERP, info, int_array[i]);
}
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
const INTVAL n = VTABLE_shift_integer(INTERP, info);
const INTVAL rt = VTABLE_shift_integer(INTERP, info);
View
16 src/pmc/scheduler.pmc
@@ -277,7 +277,7 @@ Marks any referenced strings and PMCs as live.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
Visits the contents of the scheduler (used by freeze/thaw).
@@ -287,7 +287,7 @@ C<*info> is the visit info (see F<include/parrot/pmc_freeze.h>).
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
/* 1) visit task list */
VISIT_PMC_ATTR(INTERP, info, SELF, Scheduler, task_list);
@@ -298,15 +298,15 @@ C<*info> is the visit info (see F<include/parrot/pmc_freeze.h>).
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Archives the scheduler.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
Parrot_Scheduler_attributes * const core_struct = PARROT_SCHEDULER(SELF);
/* 1) freeze scheduler id */
@@ -319,15 +319,15 @@ Archives the scheduler.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Unarchives the scheduler.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
/* 1. thaw scheduler id */
const INTVAL id = VTABLE_shift_integer(INTERP, info);
@@ -347,15 +347,15 @@ Unarchives the scheduler.
/*
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Finishes thawing the scheduler.
=cut
*/
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
Parrot_cx_refresh_task_list(INTERP, SELF);
}
View
22 src/pmc/schedulermessage.pmc
@@ -206,7 +206,7 @@ Mark any referenced strings and PMCs.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the scheduler message.
@@ -216,28 +216,22 @@ C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
*/
- VTABLE void visit(visit_info *info) {
- Parrot_SchedulerMessage_attributes * const core_struct =
- PARROT_SCHEDULERMESSAGE(SELF);
- PMC **pos;
-
- /* 1) visit message data */
- pos = &core_struct->data;
- info->thaw_ptr = pos;
- (info->visit_pmc_now)(INTERP, *pos, info);
+ VTABLE void visit(PMC *info) {
+ /* visit message data */
+ VISIT_PMC(INTERP, info, PARROT_SCHEDULERMESSAGE(SELF)->data);
}
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the scheduler message.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
Parrot_SchedulerMessage_attributes * const core_struct =
PARROT_SCHEDULERMESSAGE(SELF);
@@ -250,15 +244,15 @@ Used to archive the scheduler message.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the scheduler message.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
/* 1. thaw message id */
const INTVAL id = VTABLE_shift_integer(INTERP, info);
View
8 src/pmc/string.pmc
@@ -778,28 +778,28 @@ Return length of the string.
=over 4
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the string.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
SUPER(info);
VTABLE_push_string(INTERP, info, VTABLE_get_string(INTERP, SELF));
}
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the string.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
SUPER(info);
SET_ATTR_str_val(INTERP, SELF, VTABLE_shift_string(INTERP, info));
}
View
12 src/pmc/sub.pmc
@@ -619,19 +619,19 @@ Returns whether the two subroutines are equal.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the sub.
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Archives the subroutine.
=cut
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
VISIT_PMC_ATTR(INTERP, info, SELF, Sub, namespace_name);
VISIT_PMC_ATTR(INTERP, info, SELF, Sub, multi_signature);
@@ -651,7 +651,7 @@ Archives the subroutine.
SUPER(info);
}
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
Parrot_Sub_attributes *sub;
STRING *hll_name;
int i;
@@ -709,15 +709,15 @@ Archives the subroutine.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Unarchives the subroutine.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
Parrot_Sub_attributes *sub;
INTVAL flags;
int i;
View
16 src/pmc/task.pmc
@@ -385,7 +385,7 @@ Mark any referenced strings and PMCs.
/*
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
This is used by freeze/thaw to visit the contents of the task.
@@ -395,22 +395,22 @@ C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
*/
- VTABLE void visit(visit_info *info) {
+ VTABLE void visit(PMC *info) {
/* 1) visit code block */
VISIT_PMC_ATTR(INTERP, info, SELF, Task, codeblock);
}
/*
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
Used to archive the task.
=cut
*/
- VTABLE void freeze(visit_info *info) {
+ VTABLE void freeze(PMC *info) {
const Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
/* 1) freeze task id */
@@ -434,15 +434,15 @@ Used to archive the task.
/*
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
Used to unarchive the task.
=cut
*/
- VTABLE void thaw(visit_info *info) {
+ VTABLE void thaw(PMC *info) {
/* 1. thaw task id */
const INTVAL id = VTABLE_shift_integer(INTERP, info);
@@ -486,15 +486,15 @@ Used to unarchive the task.
/*
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
Called after the task has been thawed.
=cut
*/
- VTABLE void thawfinish(visit_info *info) {
+ VTABLE void thawfinish(PMC *info) {
Parrot_Task_attributes * core_struct = PARROT_TASK(SELF);
UNUSED(core_struct); /* TODO: Rebuild the task index. */
View
750 src/pmc_freeze.c
@@ -18,10 +18,6 @@ C<< 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 C<visit_info> is a stand-in for some kind of
-serializer PMC which will eventually be written. It associates a Parrot
-C<STRING> with a vtable.
-
=cut
*/
@@ -30,745 +26,13 @@ C<STRING> with a vtable.
#include "pmc/pmc_callcontext.h"
#include "pmc_freeze.str"
-/* HEADERIZER HFILE: include/parrot/pmc_freeze.h */
-/* HEADERIZER BEGIN: static */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
-static void create_buffer(PARROT_INTERP,
- ARGIN_NULLOK(PMC *pmc),
- ARGMOD(visit_info *info))
- __attribute__nonnull__(1)
- __attribute__nonnull__(3)
- FUNC_MODIFIES(*info);
-
-PARROT_INLINE
-static void ensure_buffer_size(PARROT_INTERP,
- ARGIN(visit_info *io),
- size_t len)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-static INTVAL get_visit_integer(PARROT_INTERP, ARGIN(visit_info *io))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-PARROT_INLINE
-static INTVAL INFO_HAS_DATA(ARGIN(visit_info *io))
- __attribute__nonnull__(1);
-
-PARROT_INLINE
-static INTVAL OUTPUT_LENGTH(ARGIN(visit_info *io))
- __attribute__nonnull__(1);
-
-static void push_opcode_integer(PARROT_INTERP,
- ARGIN(visit_info *io),
- INTVAL v)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-static void push_opcode_number(PARROT_INTERP,
- ARGIN(visit_info *io),
- FLOATVAL v)
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-static void push_opcode_string(PARROT_INTERP,
- ARGIN(visit_info *io),
- ARGIN(STRING *v))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(3);
-
-static INTVAL shift_opcode_integer(SHIM_INTERP, ARGIN(visit_info *io))
- __attribute__nonnull__(2);
-
-static FLOATVAL shift_opcode_number(SHIM_INTERP, ARGIN(visit_info *io))
- __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING* shift_opcode_string(PARROT_INTERP, ARGIN(visit_info *io))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2);
-
-static void visit_info_init(PARROT_INTERP,
- ARGOUT(visit_info *info),
- visit_enum_type what,
- ARGIN(STRING *input),
- ARGIN(PMC *pmc))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(4)
- __attribute__nonnull__(5)
- FUNC_MODIFIES(*info);
-
-static void visit_loop_todo_list(PARROT_INTERP,
- ARGIN_NULLOK(PMC *current),
- ARGIN(visit_info *info))
- __attribute__nonnull__(1)
- __attribute__nonnull__(3);
-
-static void visit_todo_list_freeze(PARROT_INTERP,
- ARGIN_NULLOK(PMC* pmc),
- ARGIN(visit_info* info))
- __attribute__nonnull__(1)
- __attribute__nonnull__(3);
-
-PARROT_INLINE
-static void visit_todo_list_thaw(PARROT_INTERP,
- SHIM(PMC* pmc_not_used),
- ARGIN(visit_info* info))
- __attribute__nonnull__(1)
- __attribute__nonnull__(3);
-
-#define ASSERT_ARGS_create_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_ensure_buffer_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_get_visit_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_INFO_HAS_DATA __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_OUTPUT_LENGTH __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io) \
- , PARROT_ASSERT_ARG(v))
-#define ASSERT_ARGS_shift_opcode_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_shift_opcode_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_shift_opcode_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_visit_info_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(info) \
- , PARROT_ASSERT_ARG(input) \
- , PARROT_ASSERT_ARG(pmc))
-#define ASSERT_ARGS_visit_loop_todo_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_visit_todo_list_freeze __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_visit_todo_list_thaw __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(info))
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: static */
-
/* when thawing a string longer then this size, we first do a GC run and then
* block GC - the system can't give us more headers */
#define THAW_BLOCK_GC_SIZE 100000
-/* preallocate freeze image for aggregates with this estimation */
-#define FREEZE_BYTES_PER_ITEM 9
-
-/* macros/constants to handle packing/unpacking of PMC IDs and flags
- * the 2 LSBs are used for flags, all other bits are used for PMC ID
- */
-#define PackID_new(id, flags) (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3))
-#define PackID_get_PMCID(id) ((UINTVAL)(id) / 4)
-#define PackID_set_PMCID(lv, id) (lv) = PackID_new((id), PackID_get_FLAGS(lv))
-#define PackID_get_FLAGS(id) ((UINTVAL)(id) & 3)
-#define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags))
-
-enum {
- enum_PackID_normal = 0,
- enum_PackID_seen = 1,
-};
-
-/*
-
-=head2 C<opcode_t> IO Functions
-
-=over 4
-
-=item C<static void ensure_buffer_size(PARROT_INTERP, visit_info *io, size_t
-len)>
-
-Checks the size of the "stream" buffer to see if it can accommodate
-C<len> more bytes. If not, expands the buffer.
-
-=cut
-
-*/
-
-#define GET_VISIT_CURSOR(io) \
- ((opcode_t *)(((char *)Buffer_bufstart((io)->buffer) + (io)->pos)))
-#define SET_VISIT_CURSOR(io, x) do {\
- (io)->pos = ((char *)(x) - (char *)Buffer_bufstart((io)->buffer)); \
-} while (0)
-#define INC_VISIT_CURSOR(io, x) do {\
- (io)->pos += (x); \
-} while (0)
-
-#define BYTECODE_SHIFT_OK(io) PARROT_ASSERT((io)->pos <= (io)->input_length)
-
-
-PARROT_INLINE
-static void
-ensure_buffer_size(PARROT_INTERP, ARGIN(visit_info *io), size_t len)
-{
- ASSERT_ARGS(ensure_buffer_size)
- Buffer *buf = io->buffer;
- const size_t used = io->pos;
- const int need_free = Buffer_buflen(buf) - used - len;
-
- /* grow by factor 1.5 or such */
- if (need_free <= 16) {
- size_t new_size = (size_t) (Buffer_buflen(buf) * 1.5);
- if (new_size < Buffer_buflen(buf) - need_free + 512)
- new_size = Buffer_buflen(buf) - need_free + 512;
- Parrot_gc_reallocate_buffer_storage(interp, buf, new_size);
-
- PARROT_ASSERT(Buffer_buflen(buf) - used - len >= 15);
- }
-
-#ifndef DISABLE_GC_DEBUG
- Parrot_gc_compact_memory_pool(interp);
-#endif
-
-}
-
-/*
-
-=item C<static INTVAL OUTPUT_LENGTH(visit_info *io)>
-
-XXX TODO
-
-=cut
-
-*/
-
-PARROT_INLINE
-static INTVAL
-OUTPUT_LENGTH(ARGIN(visit_info *io)) {
- ASSERT_ARGS(OUTPUT_LENGTH)
- return io->pos;
-}
-
-/*
-
-=item C<static INTVAL INFO_HAS_DATA(visit_info *io)>
-
-XXX TODO
-
-=cut
-
-*/
-
-PARROT_INLINE
-static INTVAL
-INFO_HAS_DATA(ARGIN(visit_info *io)) {
- ASSERT_ARGS(INFO_HAS_DATA)
- return io->pos < io->input_length;
-}
-
-
-/*
-
-=item C<static INTVAL get_visit_integer(PARROT_INTERP, visit_info *io)>
-
-get the flags describing the visit action
-
-=cut
-
-*/
-
-static INTVAL
-get_visit_integer(PARROT_INTERP, ARGIN(visit_info *io)) {
- ASSERT_ARGS(get_visit_integer)
- return io->what;
-}
-
-/*
-
-=item C<static void push_opcode_integer(PARROT_INTERP, visit_info *io, INTVAL
-v)>
-
-Pushes the integer C<v> onto the end of the C<*io> "stream".
-
-XXX assumes sizeof (opcode_t) == sizeof (INTVAL).
-
-=cut
-
-*/
-
-static void
-push_opcode_integer(PARROT_INTERP, ARGIN(visit_info *io), INTVAL v)
-{
- ASSERT_ARGS(push_opcode_integer)
- size_t len = PF_size_integer() * sizeof (opcode_t);
- ensure_buffer_size(interp, io, len);
- SET_VISIT_CURSOR(io, PF_store_integer(GET_VISIT_CURSOR(io), v));
-}
-
-
-/*
-
-=item C<static void push_opcode_number(PARROT_INTERP, visit_info *io, FLOATVAL
-v)>
-
-Pushes the number C<v> onto the end of the C<*io> "stream".
-
-=cut
-
-*/
-
-static void
-push_opcode_number(PARROT_INTERP, ARGIN(visit_info *io), FLOATVAL v)
-{
- ASSERT_ARGS(push_opcode_number)
- size_t len = PF_size_number() * sizeof (opcode_t);
- ensure_buffer_size(interp, io, len);
- SET_VISIT_CURSOR(io, PF_store_number(GET_VISIT_CURSOR(io), &v));
-}
-
-
-/*
-
-=item C<static void push_opcode_string(PARROT_INTERP, visit_info *io, STRING
-*v)>
-
-Pushes the string C<*v> onto the end of the C<*io> "stream".
-
-=cut
-
-*/
-
-static void
-push_opcode_string(PARROT_INTERP, ARGIN(visit_info *io), ARGIN(STRING *v))
-{
- ASSERT_ARGS(push_opcode_string)
- size_t len = PF_size_string(v) * sizeof (opcode_t);
- ensure_buffer_size(interp, io, len);
- SET_VISIT_CURSOR(io, PF_store_string(GET_VISIT_CURSOR(io), v));
-}
-
-/*
-
-=item C<static void push_opcode_pmc(PARROT_INTERP, visit_info *io, PMC *v)>
-
-Pushes a reference to pmc C<*v> onto the end of the C<*io> "stream". If C<*v>
-hasn't been seen yet, it is also pushed onto the todo list.
-
-=cut
-
-*/
-
-static void
-push_opcode_pmc(PARROT_INTERP, ARGIN(visit_info *io), ARGIN(PMC *v)) {
- io->thaw_ptr = &v;
- (io->visit_pmc_now)(interp, v, io);
-}
-
-/*
-
-=item C<static INTVAL shift_opcode_integer(PARROT_INTERP, visit_info *io)>
-
-Removes and returns an integer from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-static INTVAL
-shift_opcode_integer(SHIM_INTERP, ARGIN(visit_info *io))
-{
- ASSERT_ARGS(shift_opcode_integer)
- opcode_t *pos = GET_VISIT_CURSOR(io);
- const INTVAL i = PF_fetch_integer(io->pf, (const opcode_t **)&pos);
- SET_VISIT_CURSOR(io, pos);
- BYTECODE_SHIFT_OK(io);
- return i;
-}
-
-
/*
-=item C<static FLOATVAL shift_opcode_number(PARROT_INTERP, visit_info *io)>
-
-Removes and returns an number from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-static FLOATVAL
-shift_opcode_number(SHIM_INTERP, ARGIN(visit_info *io))
-{
- ASSERT_ARGS(shift_opcode_number)
- opcode_t *pos = GET_VISIT_CURSOR(io);
- const FLOATVAL f = PF_fetch_number(io->pf, (const opcode_t **)&pos);
- SET_VISIT_CURSOR(io, pos);
- BYTECODE_SHIFT_OK(io);
- return f;
-}
-
-
-/*
-
-=item C<static STRING* shift_opcode_string(PARROT_INTERP, visit_info *io)>
-
-Removes and returns a string from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-
-PARROT_WARN_UNUSED_RESULT