[svn:parrot] r43963 - in branches/tt362: . src/pmc t/pmc

plobsing at svn.parrot.org plobsing at svn.parrot.org
Mon Feb 15 05:38:32 UTC 2010


Author: plobsing
Date: Mon Feb 15 05:38:31 2010
New Revision: 43963
URL: https://trac.parrot.org/parrot/changeset/43963

Log:
add ImageIOSize PMC type to efficiently get the size of an image. see tt362 for why.

Added:
   branches/tt362/src/pmc/imageiosize.pmc   (contents, props changed)
   branches/tt362/t/pmc/imageiosize.t   (contents, props changed)
Modified:
   branches/tt362/MANIFEST

Modified: branches/tt362/MANIFEST
==============================================================================
--- branches/tt362/MANIFEST	Mon Feb 15 04:45:58 2010	(r43962)
+++ branches/tt362/MANIFEST	Mon Feb 15 05:38:31 2010	(r43963)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Sun Feb 14 22:53:39 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Mon Feb 15 05:20:54 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -1430,6 +1430,7 @@
 src/pmc/hashiterator.pmc                                    [devel]src
 src/pmc/hashiteratorkey.pmc                                 [devel]src
 src/pmc/imageio.pmc                                         [devel]src
+src/pmc/imageiosize.pmc                                     [devel]src
 src/pmc/integer.pmc                                         [devel]src
 src/pmc/iterator.pmc                                        [devel]src
 src/pmc/key.pmc                                             [devel]src
@@ -1897,6 +1898,7 @@
 t/pmc/hashiterator.t                                        [test]
 t/pmc/hashiteratorkey.t                                     [test]
 t/pmc/imageio.t                                             [test]
+t/pmc/imageiosize.t                                         [test]
 t/pmc/integer.t                                             [test]
 t/pmc/io.t                                                  [test]
 t/pmc/io_iterator.t                                         [test]

Added: branches/tt362/src/pmc/imageiosize.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt362/src/pmc/imageiosize.pmc	Mon Feb 15 05:38:31 2010	(r43963)
@@ -0,0 +1,267 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/imageiosize.pmc - ImageIOSize PMC
+
+=head1 DESCRIPTION
+
+Gets the size of an ImageIO image without the allocation costs.
+
+=cut
+
+*/
+
+#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))
+
+enum {
+    enum_PackID_normal     = 0,
+    enum_PackID_seen       = 1,
+};
+
+static void
+visit_todo_list_freeze(PARROT_INTERP, PMC* pmc, PMC* info)
+{
+    UINTVAL id;
+    int packid_type;
+
+    PARROT_ASSERT(PARROT_IMAGEIOSIZE(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_IMAGEIOSIZE(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_IMAGEIOSIZE(info)->id++; /* next id to freeze */
+            id = PARROT_IMAGEIOSIZE(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_IMAGEIOSIZE(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_push_pmc(interp, PARROT_IMAGEIOSIZE(info)->todo, pmc);
+        VTABLE_freeze(interp, pmc, info);
+    }
+}
+
+pmclass ImageIOSize auto_attrs {
+    ATTR PMC             *seen;           /* seen hash */
+    ATTR PMC             *todo;           /* todo list */
+    ATTR UINTVAL          id;             /* freze ID of PMC */
+    ATTR struct PackFile *pf;
+    ATTR INTVAL           size;
+
+/*
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+    VTABLE void init() {
+        PARROT_IMAGEIOSIZE(SELF)->todo = pmc_new(INTERP, enum_class_ResizablePMCArray);
+        PARROT_IMAGEIOSIZE(SELF)->id   = 0;
+        PARROT_IMAGEIOSIZE(SELF)->pf   = PackFile_new(INTERP, 0);
+        PARROT_IMAGEIOSIZE(SELF)->size = 0;
+
+        PARROT_IMAGEIOSIZE(SELF)->seen = pmc_new(INTERP, enum_class_Hash);
+        VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen,
+            parrot_new_intval_hash(INTERP));
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+    }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+    VTABLE void destroy() {
+        PackFile_destroy(INTERP, PARROT_IMAGEIOSIZE(SELF)->pf);
+    }
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->todo);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
+    }
+
+/*
+
+=item C<VTABLE PMC *get_pmc()>
+
+Gets the result PMC after a thaw.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc() {
+        PMC *ret = pmc_new(INTERP, enum_class_Integer);
+        VTABLE_set_integer_native(INTERP, ret, PARROT_IMAGEIOSIZE(SELF)->size);
+        return ret;
+    }
+
+/*
+
+=item C<VTABLE PMC *get_iter()>
+
+Get the C<todo> list for this freeze/thaw for iterating over.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_iter() {
+        return PARROT_IMAGEIOSIZE(SELF)->todo;
+    }
+
+/*
+
+=item C<VTABLE INTVAL get_integer()>
+
+Returns the flags describing the visit action
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer() {
+        return VISIT_FREEZE_NORMAL;
+    }
+
+/*
+
+=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);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+
+/*
+
+=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);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+
+/*
+
+=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);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+/*
+
+=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) {
+        visit_todo_list_freeze(INTERP, v, SELF);
+    }
+
+    VTABLE void set_pmc(PMC *p)
+    {
+        UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+        PARROT_IMAGEIOSIZE(SELF)->size += header_length;
+
+        visit_todo_list_freeze(INTERP, p, SELF);
+        Parrot_visit_loop_visit(INTERP, SELF);
+    }
+
+/*
+
+=back
+
+=cut
+
+*/
+
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/tt362/t/pmc/imageiosize.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt362/t/pmc/imageiosize.t	Mon Feb 15 05:38:31 2010	(r43963)
@@ -0,0 +1,74 @@
+#! parrot
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+t/pmc/imageiosize.t - test ImageIOSize PMC
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/imagiosize.t
+
+=head1 DESCRIPTION
+
+Tests the ImageIOSize PMC.
+
+=cut
+
+.sub main :main
+    .include 'test_more.pir'
+
+    plan(4)
+
+    .local pmc iios
+    iios = new ['ImageIOSize']
+    ok(1, 'instantiated ImageIOSize')
+
+    .local pmc test_pmc
+    test_pmc = null
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (null)')
+
+    iios = new ['ImageIOSize']
+    test_pmc = 'get_test_simple'()
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (simple)')
+
+    iios = new ['ImageIOSize']
+    test_pmc = 'get_test_aggregate'()
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (aggregate)')
+.end
+
+.sub get_test_simple
+    $P0 = new ['Integer']
+    $P0 = -99
+    .return ($P0)
+.end
+
+.sub get_test_aggregate
+    $P0 = new ['ResizableStringArray']
+    $P0[0] = 'parrot'
+    $P0[1] = '???'
+    $P0[2] = 'profit'
+    .return ($P0)
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir


More information about the parrot-commits mailing list