[svn:parrot] r49048 - branches/string_gc_encapsulate/src/gc
bacek at svn.parrot.org
bacek at svn.parrot.org
Thu Sep 16 10:58:36 UTC 2010
Author: bacek
Date: Thu Sep 16 10:58:36 2010
New Revision: 49048
URL: https://trac.parrot.org/parrot/changeset/49048
Log:
Copy-paste string-related functions from gc_ms and make them public.
Modified:
branches/string_gc_encapsulate/src/gc/gc_private.h
branches/string_gc_encapsulate/src/gc/string_gc.c
Modified: branches/string_gc_encapsulate/src/gc/gc_private.h
==============================================================================
--- branches/string_gc_encapsulate/src/gc/gc_private.h Thu Sep 16 10:58:15 2010 (r49047)
+++ branches/string_gc_encapsulate/src/gc/gc_private.h Thu Sep 16 10:58:36 2010 (r49048)
@@ -674,6 +674,57 @@
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/gc/gc_inf.c */
+
+/* HEADERIZER BEGIN: src/gc/string_gc.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+void Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP,
+ ARGOUT(Buffer *buffer),
+ size_t size)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_str_allocate_string_storage(PARROT_INTERP,
+ ARGOUT(STRING *str),
+ size_t size)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*str);
+
+void Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP,
+ ARGMOD(Buffer *buffer),
+ size_t newsize)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_str_reallocate_string_storage(PARROT_INTERP,
+ ARGMOD(STRING *str),
+ size_t newsize)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*str);
+
+#define ASSERT_ARGS_Parrot_gc_str_allocate_buffer_storage \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(buffer))
+#define ASSERT_ARGS_Parrot_gc_str_allocate_string_storage \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(str))
+#define ASSERT_ARGS_Parrot_gc_str_reallocate_buffer_storage \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(buffer))
+#define ASSERT_ARGS_Parrot_gc_str_reallocate_string_storage \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(str))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+/* HEADERIZER END: src/gc/string_gc.c */
+
#endif /* PARROT_GC_PRIVATE_H_GUARD */
/*
Modified: branches/string_gc_encapsulate/src/gc/string_gc.c
==============================================================================
--- branches/string_gc_encapsulate/src/gc/string_gc.c Thu Sep 16 10:58:15 2010 (r49047)
+++ branches/string_gc_encapsulate/src/gc/string_gc.c Thu Sep 16 10:58:36 2010 (r49048)
@@ -18,6 +18,237 @@
*/
+#include "parrot/parrot.h"
+#include "gc_private.h"
+
+/* HEADERIZER HFILE: src/gc/gc_private.h */
+
+/*
+
+=item C<void Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP, Buffer
+*buffer, size_t size)>
+
+Allocates a chunk of memory of at least size C<size> for the given Buffer.
+buffer is guaranteed to be properly aligned for things like C<FLOATVALS>,
+so the size may be rounded up or down to guarantee that this alignment holds.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_allocate_buffer_storage(PARROT_INTERP,
+ ARGOUT(Buffer *buffer), size_t size)
+{
+ ASSERT_ARGS(Parrot_gc_str_allocate_buffer_storage)
+ const size_t new_size = ALIGNED_STRING_SIZE(size);
+
+ Buffer_bufstart(buffer) = (void *)aligned_mem(buffer,
+ (char *)mem_allocate(interp,
+ interp->mem_pools, new_size, interp->mem_pools->memory_pool));
+
+ /* Save pool used to allocate into buffer header */
+ *Buffer_poolptr(buffer) = interp->mem_pools->memory_pool->top_block;
+
+ Buffer_buflen(buffer) = new_size - sizeof (void *);
+}
+
+/*
+
+=item C<void Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP, Buffer
+*buffer, size_t newsize)>
+
+Reallocate the Buffer's buffer memory to the given size. The
+allocated buffer will not shrink. If the buffer was allocated with
+L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
+all reallocation, the new buffer might have moved and the additional
+memory is not cleared.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_reallocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer),
+ size_t newsize)
+{
+ ASSERT_ARGS(Parrot_gc_str_reallocate_buffer_storage)
+ size_t copysize;
+ char *mem;
+ Variable_Size_Pool * const pool = interp->mem_pools->memory_pool;
+ size_t new_size, needed, old_size;
+
+ /* we don't shrink buffers */
+ if (newsize <= Buffer_buflen(buffer))
+ return;
+
+ /*
+ * same as below but barely used and tested - only 3 list related
+ * tests do use true reallocation
+ *
+ * list.c, which does _reallocate, has 2 reallocations
+ * normally, which play ping pong with buffers.
+ * The normal case is therefore always to allocate a new block
+ */
+ new_size = ALIGNED_STRING_SIZE(newsize);
+ old_size = ALIGNED_STRING_SIZE(Buffer_buflen(buffer));
+ needed = new_size - old_size;
+
+ if ((pool->top_block->free >= needed)
+ && (pool->top_block->top == (char *)Buffer_bufstart(buffer) + old_size)) {
+ pool->top_block->free -= needed;
+ pool->top_block->top += needed;
+ interp->mem_pools->memory_used += needed;
+ Buffer_buflen(buffer) = newsize;
+ return;
+ }
+
+ copysize = Buffer_buflen(buffer);
+
+ mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+ mem = aligned_mem(buffer, mem);
+
+ /* We shouldn't ever have a 0 from size, but we do. If we can track down
+ * those bugs, this can be removed which would make things cheaper */
+ if (copysize)
+ memcpy(mem, Buffer_bufstart(buffer), copysize);
+
+ Buffer_bufstart(buffer) = mem;
+
+ new_size -= sizeof (void *);
+
+ Buffer_buflen(buffer) = new_size;
+
+ /* Save pool used to allocate into buffer header */
+ *Buffer_poolptr(buffer) = interp->mem_pools->memory_pool->top_block;
+}
+
+/*
+
+=item C<void Parrot_gc_str_allocate_string_storage(PARROT_INTERP, STRING *str,
+size_t size)>
+
+Allocate the STRING's buffer memory to the given size. The allocated
+buffer maybe slightly bigger than the given C<size>. This function
+sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
+is B<not> changed.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_allocate_string_storage(PARROT_INTERP, ARGOUT(STRING *str),
+ size_t size)
+{
+ ASSERT_ARGS(Parrot_gc_str_allocate_string_storage)
+ size_t new_size;
+ Variable_Size_Pool *pool;
+ char *mem;
+
+ Buffer_buflen(str) = 0;
+ Buffer_bufstart(str) = NULL;
+
+ if (size == 0)
+ return;
+
+ pool = PObj_constant_TEST(str)
+ ? interp->mem_pools->constant_string_pool
+ : interp->mem_pools->memory_pool;
+
+ new_size = ALIGNED_STRING_SIZE(size);
+ mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+ mem += sizeof (void *);
+
+ Buffer_bufstart(str) = str->strstart = mem;
+ Buffer_buflen(str) = new_size - sizeof (void *);
+
+ /* Save pool used to allocate into buffer header */
+ *Buffer_poolptr(str) = pool->top_block;
+}
+
+/*
+
+=item C<void Parrot_gc_str_reallocate_string_storage(PARROT_INTERP, STRING *str,
+size_t newsize)>
+
+Reallocate the STRING's buffer memory to the given size. The allocated
+buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
+new buffer location, C<str-E<gt>bufused> is B<not> changed.
+
+=cut
+
+*/
+
+void
+Parrot_gc_str_reallocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str),
+ size_t newsize)
+{
+ ASSERT_ARGS(Parrot_gc_str_reallocate_string_storage)
+ size_t copysize;
+ char *mem, *oldmem;
+ size_t new_size, needed, old_size;
+
+ Variable_Size_Pool * const pool =
+ PObj_constant_TEST(str)
+ ? interp->mem_pools->constant_string_pool
+ : interp->mem_pools->memory_pool;
+
+ /* if the requested size is smaller then buflen, we are done */
+ if (newsize <= Buffer_buflen(str))
+ return;
+
+ /*
+ * first check, if we can reallocate:
+ * - if the passed strings buffer is the last string in the pool and
+ * - if there is enough size, we can just move the pool's top pointer
+ */
+ new_size = ALIGNED_STRING_SIZE(newsize);
+ old_size = ALIGNED_STRING_SIZE(Buffer_buflen(str));
+ needed = new_size - old_size;
+
+ if (pool->top_block->free >= needed
+ && pool->top_block->top == (char *)Buffer_bufstart(str) + old_size) {
+ pool->top_block->free -= needed;
+ pool->top_block->top += needed;
+ interp->mem_pools->memory_used += needed;
+ Buffer_buflen(str) = new_size - sizeof (void *);
+ return;
+ }
+
+ PARROT_ASSERT(str->bufused <= newsize);
+
+ /* only copy used memory, not total string buffer */
+ copysize = str->bufused;
+
+ mem = (char *)mem_allocate(interp, interp->mem_pools, new_size, pool);
+ mem += sizeof (void *);
+
+ /* Update Memory_Block usage */
+ /* We must not reallocate non-movable buffers! */
+ PARROT_ASSERT(PObj_is_movable_TESTALL(str));
+
+ /* We must not reallocate shared buffers! */
+ PARROT_ASSERT(!(*Buffer_bufflagsptr(str) & Buffer_shared_FLAG));
+
+ /* Decrease usage */
+ PARROT_ASSERT(Buffer_pool(str));
+ Buffer_pool(str)->freed += old_size;
+
+ /* copy mem from strstart, *not* bufstart */
+ oldmem = str->strstart;
+ Buffer_bufstart(str) = (void *)mem;
+ str->strstart = mem;
+ Buffer_buflen(str) = new_size - sizeof (void *);
+
+ /* We shouldn't ever have a 0 from size, but we do. If we can track down
+ * those bugs, this can be removed which would make things cheaper */
+ if (copysize)
+ memcpy(mem, oldmem, copysize);
+
+ /* Save pool used to allocate into buffer header */
+ *Buffer_poolptr(str) = pool->top_block;
+}
/*
More information about the parrot-commits
mailing list