[svn:parrot] r49125 - in trunk: . include/parrot src src/pmc

plobsing at svn.parrot.org plobsing at svn.parrot.org
Sat Sep 18 00:48:46 UTC 2010


Author: plobsing
Date: Sat Sep 18 00:48:46 2010
New Revision: 49125
URL: https://trac.parrot.org/parrot/changeset/49125

Log:
add ImageIOThaw PMC
this is similar to ImageIO PMC, but only goes one way.
also, uses pointer into immovable string in stead of index into string
gets 1.6% improvement in rakudo startup

Added:
   trunk/include/parrot/imageio.h
   trunk/src/pmc/imageiothaw.pmc
Modified:
   trunk/MANIFEST
   trunk/src/pmc/imageio.pmc
   trunk/src/pmc_freeze.c

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Sat Sep 18 00:39:15 2010	(r49124)
+++ trunk/MANIFEST	Sat Sep 18 00:48:46 2010	(r49125)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Thu Sep 16 15:48:25 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 18 00:46:33 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -962,6 +962,7 @@
 include/parrot/global_setup.h                               [main]include
 include/parrot/hash.h                                       [main]include
 include/parrot/hll.h                                        [main]include
+include/parrot/imageio.h                                    [main]include
 include/parrot/imcc.h                                       [main]include
 include/parrot/interpreter.h                                [main]include
 include/parrot/io.h                                         [main]include
@@ -1381,6 +1382,7 @@
 src/pmc/imageio.pmc                                         []
 src/pmc/imageiosize.pmc                                     []
 src/pmc/imageiostrings.pmc                                  []
+src/pmc/imageiothaw.pmc                                     []
 src/pmc/integer.pmc                                         []
 src/pmc/iterator.pmc                                        []
 src/pmc/key.pmc                                             []

Added: trunk/include/parrot/imageio.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/include/parrot/imageio.h	Sat Sep 18 00:48:46 2010	(r49125)
@@ -0,0 +1,23 @@
+#ifndef PARROT_IMAGEIO_H_GUARD
+#define PARROT_IMAGEIO_H_GUARD
+
+#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
+
+/* 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))
+
+/* preallocate freeze image for aggregates with this estimation */
+#define FREEZE_BYTES_PER_ITEM 9
+
+enum {
+    enum_PackID_normal     = 0,
+    enum_PackID_seen       = 1,
+};
+
+#endif /* PARROT_IMAGEIO_H_GUARD */

Modified: trunk/src/pmc/imageio.pmc
==============================================================================
--- trunk/src/pmc/imageio.pmc	Sat Sep 18 00:39:15 2010	(r49124)
+++ trunk/src/pmc/imageio.pmc	Sat Sep 18 00:48:46 2010	(r49125)
@@ -18,24 +18,7 @@
 
 */
 
-#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
-
-/* 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,
-};
+#include "parrot/imageio.h"
 
 /* HEADERIZER HFILE: none */
 /* HEADERIZER BEGIN: static */

Added: trunk/src/pmc/imageiothaw.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/imageiothaw.pmc	Sat Sep 18 00:48:46 2010	(r49125)
@@ -0,0 +1,354 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id: imageio.pmc 48634 2010-08-24 17:14:54Z plobsing $
+
+=head1 NAME
+
+src/pmc/imageiothaw.pmc - ImageIOThaw PMC
+
+=head1 DESCRIPTION
+
+Thaws PMCs from packfile images.
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/imageio.h"
+
+#define BYTECODE_SHIFT_OK(interp, pmc) PARROT_ASSERT( \
+    PARROT_IMAGEIOTHAW(pmc)->curs <= \
+    PARROT_IMAGEIOTHAW(pmc)->image->strstart + \
+    Parrot_str_byte_length(interp, PARROT_IMAGEIOTHAW(pmc)->image->strstart))
+
+
+/* HEADERIZER HFILE: none */
+
+pmclass ImageIOThaw auto_attrs {
+    ATTR STRING              *img;
+    ATTR opcode_t            *curs;
+    ATTR PMC                 *todo;
+    ATTR PackFile            *pf;
+    ATTR PackFile_ConstTable *pf_ct;
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        PARROT_IMAGEIOTHAW(SELF)->todo =
+            Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+
+        PObj_flag_CLEAR(private1, SELF);
+
+        PObj_custom_mark_SET(SELF);
+    }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        PackFile_destroy(INTERP, PARROT_IMAGEIOTHAW(SELF)->pf);
+        PARROT_IMAGEIOTHAW(SELF)->pf = NULL;
+    }
+
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+
+    VTABLE void mark() {
+        Parrot_gc_mark_STRING_alive(INTERP, PARROT_IMAGEIOTHAW(SELF)->img);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOTHAW(SELF)->todo);
+    }
+
+
+/*
+
+=item C<void set_string_native(STRING *image)>
+
+Thaws the PMC contained in C<image>.
+
+=cut
+
+*/
+
+    VTABLE void set_string_native(STRING *image) {
+	if (!PObj_external_TEST(image))
+	    Parrot_str_pin(INTERP, image);
+
+	PARROT_IMAGEIOTHAW(SELF)->img  = image;
+	PARROT_IMAGEIOTHAW(SELF)->curs = (opcode_t *)image->strstart;
+
+        if (PObj_flag_TEST(private1, SELF)) {
+            PARROT_IMAGEIOTHAW(SELF)->pf = PARROT_IMAGEIOTHAW(SELF)->pf_ct->base.pf;
+        }
+        else {
+            const UINTVAL header_length =
+                 GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+            int unpacked_length;
+
+            PARROT_IMAGEIOTHAW(SELF)->pf   = PackFile_new(INTERP, 0);
+            PObj_custom_destroy_SET(SELF);
+
+            PARROT_IMAGEIOTHAW(SELF)->pf->options |= PFOPT_PMC_FREEZE_ONLY;
+            unpacked_length = PackFile_unpack(INTERP, PARROT_IMAGEIOTHAW(SELF)->pf,
+                                PARROT_IMAGEIOTHAW(SELF)->curs, Parrot_str_byte_length(interp, image));
+
+            if (unpacked_length)
+                PARROT_IMAGEIOTHAW(SELF)->curs += header_length / sizeof (opcode_t*);
+            else
+                Parrot_ex_throw_from_c_args(INTERP, NULL,
+                        EXCEPTION_INVALID_STRING_REPRESENTATION,
+                        "PackFile header failed during unpack");
+	}
+
+	STATICSELF.shift_pmc();
+	Parrot_visit_loop_visit(INTERP, SELF);
+
+	/* we're done reading the image */
+	PARROT_ASSERT(image->strstart + Parrot_str_byte_length(interp, image) ==
+                    PARROT_IMAGEIOTHAW(SELF)->curs);
+
+	Parrot_visit_loop_thawfinish(INTERP, SELF);
+
+	if (!PObj_external_TEST(image))
+	    Parrot_str_unpin(INTERP, image);
+    }
+
+
+/*
+
+=item C<PMC *get_iter()>
+
+Gets the todo list for iterating over.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_iter() {
+        return PARROT_IMAGEIOTHAW(SELF)->todo;
+    }
+
+/*
+
+=item C<PMC *get_pmc()>
+
+Get the thawed PMC.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc() {
+        return VTABLE_get_pmc_keyed_int(INTERP,
+            (PARROT_IMAGEIOTHAW(SELF))->todo, 0);
+    }
+
+
+/*
+
+=item C<INTVAL get_integer()>
+
+Get the visit action.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer() {
+        return VISIT_THAW_NORMAL;
+    }
+
+
+/*
+
+=item C<void set_pointer(void *value)>
+
+Set an exterior constant table to use for cross-referencing constants.
+
+=cut
+
+*/
+
+    VTABLE void set_pointer(void *value) {
+        PObj_flag_SET(private1, SELF);
+        PARROT_IMAGEIOTHAW(SELF)->pf_ct = (PackFile_ConstTable *)value;
+    }
+
+
+/*
+
+=item C<INTVAL shift_integer()>
+
+Retreive an integer as the next item from the image.
+
+=cut
+
+*/
+
+    VTABLE INTVAL shift_integer() {
+        /* inlining PF_fetch_integer speeds up PBC thawing measurably */
+        const PackFile      *pf        = PARROT_IMAGEIOTHAW(SELF)->pf;
+        const unsigned char *stream    = (const unsigned char *)PARROT_IMAGEIOTHAW(SELF)->curs;
+        const INTVAL         i         = pf->fetch_iv(stream);
+        PARROT_IMAGEIOTHAW(SELF)->curs = (opcode_t *)(stream + pf->header->wordsize);
+        BYTECODE_SHIFT_OK(INTERP, SELF);
+        return i;
+    }
+
+
+/*
+
+=item C<FLOATVAL shift_float()>
+
+Retreive a float as the next item from the image.
+
+=cut
+
+*/
+
+    VTABLE FLOATVAL shift_float() {
+        const PackFile      *pf        = PARROT_IMAGEIOTHAW(SELF)->pf;
+        opcode_t *curs                 = PARROT_IMAGEIOTHAW(SELF)->curs;
+        FLOATVAL        f              = PF_fetch_number(pf, &curs);
+        PARROT_IMAGEIOTHAW(SELF)->curs = curs;
+        BYTECODE_SHIFT_OK(INTERP, SELF);
+        return f;
+    }
+
+
+/*
+
+=item C<STRING *shift_string()>
+
+Retreive a string as the next item from the image.
+
+=cut
+
+*/
+
+    VTABLE STRING *shift_string() {
+        if (PObj_flag_TEST(private1, SELF)) {
+            const INTVAL i = STATICSELF.shift_integer();
+            BYTECODE_SHIFT_OK(INTERP, SELF);
+
+            if (i >= 0) {
+                PackFile_ConstTable *table = PARROT_IMAGEIOTHAW(SELF)->pf_ct;
+
+                if (!table->constants[i].type)
+                    Parrot_ex_throw_from_c_args(interp, NULL,
+                            EXCEPTION_MALFORMED_PACKFILE,
+                            "Reference to constant not yet unpacked %d", i);
+                return table->constants[i].u.string;
+            }
+
+            /* XXX
+             * only got here because constant table doesn't contain the string
+             * fallback on inline strings
+             */
+        }
+
+        {
+            PackFile *pf                   = PARROT_IMAGEIOTHAW(SELF)->pf;
+            opcode_t *curs                 = PARROT_IMAGEIOTHAW(SELF)->curs;
+            STRING   *s                    = PF_fetch_string(INTERP, pf, &curs);
+            PARROT_IMAGEIOTHAW(SELF)->curs = curs;
+            BYTECODE_SHIFT_OK(INTERP, SELF);
+            return s;
+        }
+    }
+
+
+/*
+
+=item C<PMC *shift_pmc()>
+
+Retreive a PMC as the next item from the image.
+
+=cut
+
+*/
+
+    VTABLE PMC *shift_pmc() {
+        const UINTVAL  n            = SELF.shift_integer();
+        const INTVAL   id           = PackID_get_PMCID(n);
+        const int      packid_flags = PackID_get_FLAGS(n);
+        PMC           *pmc          = PMCNULL;
+        PMC           *todo         = PARROT_IMAGEIOTHAW(SELF)->todo;
+
+        switch (packid_flags) {
+            case enum_PackID_seen:
+                if (id) /* got a non-NULL PMC */
+                    pmc = VTABLE_get_pmc_keyed_int(INTERP, todo, id - 1);
+                break;
+            case enum_PackID_normal:
+                {
+                    const INTVAL type = SELF.shift_integer();
+
+                    PARROT_ASSERT(id - 1 == VTABLE_elements(INTERP, todo));
+
+                    if (type <= 0 || type > INTERP->n_vtable_max)
+                        Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                "Unknown PMC type to thaw %d", type);
+
+                    /* workaround to keep ParrotInterpreter PBC hack working */
+                    if (type == enum_class_ParrotInterpreter)
+                        PObj_flag_CLEAR(private1, SELF);
+
+                    pmc = Parrot_pmc_new_noinit(INTERP, type);
+
+                    VTABLE_set_pmc_keyed_int(INTERP, todo, id - 1, pmc);
+                }
+                break;
+            default:
+                Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                        "Unknown PMC id args thaw %d", packid_flags);
+                break;
+        }
+
+        return pmc;
+    }
+
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
+

Modified: trunk/src/pmc_freeze.c
==============================================================================
--- trunk/src/pmc_freeze.c	Sat Sep 18 00:39:15 2010	(r49124)
+++ trunk/src/pmc_freeze.c	Sat Sep 18 00:48:46 2010	(r49125)
@@ -199,7 +199,7 @@
     ASSERT_ARGS(Parrot_thaw)
 
     PMC        *result;
-    PMC * const info     = Parrot_pmc_new(interp, enum_class_ImageIO);
+    PMC * const info     = Parrot_pmc_new(interp, enum_class_ImageIOThaw);
     int         gc_block = 0;
 
     /*
@@ -251,7 +251,7 @@
     ASSERT_ARGS(Parrot_thaw_pbc)
     PackFile * const pf = ct->base.pf;
     STRING *image       = PF_fetch_buf(interp, pf, cursor);
-    PMC *info           = Parrot_pmc_new(interp, enum_class_ImageIO);
+    PMC *info           = Parrot_pmc_new(interp, enum_class_ImageIOThaw);
     VTABLE_set_pointer(interp, info, ct);
     VTABLE_set_string_native(interp, info, image);
     return VTABLE_get_pmc(interp, info);


More information about the parrot-commits mailing list