[svn:parrot] r47512 - in trunk: src/pmc t/pmc
NotFound at svn.parrot.org
NotFound at svn.parrot.org
Wed Jun 9 14:48:57 UTC 2010
Author: NotFound
Date: Wed Jun 9 14:48:57 2010
New Revision: 47512
URL: https://trac.parrot.org/parrot/changeset/47512
Log:
avoid excesive reallocations when grown a ByteBuffer byte by byte, add a test to exercise that, and fixes a cast
Modified:
trunk/src/pmc/bytebuffer.pmc
trunk/t/pmc/bytebuffer.t
Modified: trunk/src/pmc/bytebuffer.pmc
==============================================================================
--- trunk/src/pmc/bytebuffer.pmc Wed Jun 9 14:24:07 2010 (r47511)
+++ trunk/src/pmc/bytebuffer.pmc Wed Jun 9 14:48:57 2010 (r47512)
@@ -28,9 +28,11 @@
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+static INTVAL grow_to(INTVAL position);
#define ASSERT_ARGS_build_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(content))
+#define ASSERT_ARGS_grow_to __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
@@ -173,7 +175,7 @@
GET_ATTR_allocated_size(INTERP, SELF, allocated_size);
if (position >= allocated_size) {
- INTVAL newsize = position + 1;
+ INTVAL newsize = grow_to(position);
if (allocated_size == 0) {
INTVAL copysize = newsize;
STRING * source;
@@ -271,6 +273,11 @@
=over 4
+=item C<static INTVAL grow_to(INTVAL position)>
+
+Calculate new size enough for using position and with some margin to
+decrease the number of reallocations.
+
=item C<static STRING * build_string(PARROT_INTERP, const unsigned char
*content, INTVAL size, const CHARSET *charset, const ENCODING *encoding)>
@@ -280,6 +287,17 @@
*/
+static INTVAL
+grow_to(INTVAL position)
+{
+ const UINTVAL blocksize = 2048;
+ UINTVAL minsize = position + 1;
+ return (INTVAL) (minsize < 64 ? 64 :
+ minsize < 256 ? 256 :
+ minsize < 1024 ? 1024 :
+ ((minsize + blocksize - 1) / blocksize) * blocksize);
+}
+
PARROT_CANNOT_RETURN_NULL
static STRING *
build_string(PARROT_INTERP, ARGIN(const unsigned char *content),
@@ -295,7 +313,7 @@
if (encoding == NULL)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
"Invalid encoding");
- result = Parrot_str_new_init(interp, (char *)content, size, encoding, charset, 0);
+ result = Parrot_str_new_init(interp, (const char *)content, size, encoding, charset, 0);
if (!CHARSET_VALIDATE(interp, result))
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_INVALID_STRING_REPRESENTATION,
Modified: trunk/t/pmc/bytebuffer.t
==============================================================================
--- trunk/t/pmc/bytebuffer.t Wed Jun 9 14:24:07 2010 (r47511)
+++ trunk/t/pmc/bytebuffer.t Wed Jun 9 14:48:57 2010 (r47512)
@@ -16,14 +16,17 @@
=cut
+.include 'iglobals.pasm'
+
.sub 'main' :main
.include 'test_more.pir'
- plan(17)
+ plan(18)
test_init()
test_set_string()
test_set_byte()
test_get_string()
+ test_alloc()
.end
.sub test_init
@@ -122,6 +125,63 @@
is(n, 0xD1, "getting utf8 from buffer gives correct codepoint")
.end
+.sub test_alloc
+ # Exercise buffer reallocation building a utf16 string with the
+ # codepoints 32-8192
+ .local pmc bb
+ .local int i, big, pos, b0, b1, c
+
+ # Get endianess to set the bytes in the appropiate order.
+ # *** XXX *** Need report from big endian platforms.
+ $P0 = getinterp
+ $P0 = $P0[.IGLOBALS_CONFIG_HASH]
+ big = $P0['bigendian']
+
+ bb = new ['ByteBuffer']
+ pos = 0
+ i = 32
+loopset:
+ b0 = div i, 256
+ b1 = mod i, 256
+ if big goto setbig
+ bb[pos] = b1
+ inc pos
+ bb[pos] = b0
+ inc pos
+ goto setdone
+setbig:
+ bb[pos] = b0
+ inc pos
+ bb[pos] = b1
+ inc pos
+setdone:
+ inc i
+ if i < 8192 goto loopset
+
+ .local string s
+ s = bb.'get_string'('unicode', 'utf16')
+
+ # Check string size
+ i = length s
+ if i != 8160 goto failed
+
+ # Check string content
+ i = 32
+ pos = 0
+loopcheck:
+ c = ord s, pos
+ if c != i goto failed
+ inc pos
+ inc i
+ if i < 8192 goto loopcheck
+ ok(1, "reallocation")
+ goto end
+failed:
+ say i
+ ok(0, "reallocation")
+end:
+.end
+
# Local Variables:
# mode: pir
# fill-column: 100
More information about the parrot-commits
mailing list