[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