[svn:parrot] r40368 - in trunk: . include/parrot src/gc
whiteknight at svn.parrot.org
whiteknight at svn.parrot.org
Sat Aug 1 23:51:24 UTC 2009
Author: whiteknight
Date: Sat Aug 1 23:51:24 2009
New Revision: 40368
URL: https://trac.parrot.org/parrot/changeset/40368
Log:
[TT #895] Add some new experimental functions to the GC to help with automatic management of fixed-size structure allocations. Untested. Testing these things depends on future changes described in that ticket. Will be removed if not used and properly tested when that ticket is closed
Modified:
trunk/DEPRECATED.pod
trunk/include/parrot/gc_api.h
trunk/src/gc/api.c
trunk/src/gc/gc_private.h
trunk/src/gc/mark_sweep.c
Modified: trunk/DEPRECATED.pod
==============================================================================
--- trunk/DEPRECATED.pod Sat Aug 1 23:05:54 2009 (r40367)
+++ trunk/DEPRECATED.pod Sat Aug 1 23:51:24 2009 (r40368)
@@ -202,6 +202,14 @@
L<https://trac.parrot.org/parrot/ticket/443>
+=item PMC Attributes Allocation Functions [experimental]
+
+ Parrot_gc_allocate_pmc_attributes
+ Parrot_gc_free_pmc_attributes
+
+These items and related helper functions are added as experimental support
+for TT #895
+
=back
=head1 Compiler tools
Modified: trunk/include/parrot/gc_api.h
==============================================================================
--- trunk/include/parrot/gc_api.h Sat Aug 1 23:05:54 2009 (r40367)
+++ trunk/include/parrot/gc_api.h Sat Aug 1 23:51:24 2009 (r40368)
@@ -189,6 +189,11 @@
__attribute__nonnull__(2)
FUNC_MODIFIES(*buffer);
+void Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pmc);
+
void Parrot_gc_allocate_string_storage(PARROT_INTERP,
ARGOUT(STRING *str),
size_t size)
@@ -233,6 +238,12 @@
__attribute__nonnull__(2)
FUNC_MODIFIES(*obj);
+PARROT_CANNOT_RETURN_NULL
+void Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pmc);
+
void Parrot_gc_free_pmc_ext(PARROT_INTERP, ARGMOD(PMC *p))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
@@ -360,6 +371,10 @@
__attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(buffer)
+#define ASSERT_ARGS_Parrot_gc_allocate_pmc_attributes \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp) \
+ || PARROT_ASSERT_ARG(pmc)
#define ASSERT_ARGS_Parrot_gc_allocate_string_storage \
__attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
@@ -391,6 +406,9 @@
__attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(obj)
+#define ASSERT_ARGS_Parrot_gc_free_pmc_attributes __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp) \
+ || PARROT_ASSERT_ARG(pmc)
#define ASSERT_ARGS_Parrot_gc_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(p)
Modified: trunk/src/gc/api.c
==============================================================================
--- trunk/src/gc/api.c Sat Aug 1 23:05:54 2009 (r40367)
+++ trunk/src/gc/api.c Sat Aug 1 23:51:24 2009 (r40368)
@@ -264,6 +264,9 @@
ASSERT_ARGS(Parrot_gc_initialize)
interp->arena_base = mem_allocate_zeroed_typed(Arenas);
interp->arena_base->sized_header_pools = NULL;
+ interp->arena_base->num_sized = 0;
+ interp->arena_base->attrib_pools = NULL;
+ interp->arena_base->num_attribs = 0;
interp->lo_var_ptr = stacktop;
@@ -1071,6 +1074,9 @@
interp->arena_base->pmc_ext_pool = NULL;
mem_internal_free(interp->arena_base->sized_header_pools);
+ if (interp->arena_base->attrib_pools)
+ mem_internal_free(interp->arena_base->attrib_pools);
+ interp->arena_base->attrib_pools;
interp->arena_base->sized_header_pools = NULL;
}
@@ -1655,6 +1661,49 @@
/*
+=item C<void Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, PMC *pmc)>
+
+=item C<void Parrot_gc_free_pmc_attributes(PARROT_INTERP, PMC *pmc)>
+
+EXPERIMENTAL!!!
+
+Allocation and deallocation function for PMC Attribute structures.
+
+These functions are not currently used. They are waiting for changes to
+the PMC allocation/deallocation mechanisms. See TT #895 for details.
+
+=cut
+
+*/
+
+void
+Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
+{
+ ASSERT_ARGS(Parrot_gc_allocate_pmc_attributes)
+ const size_t attr_size = 0; /*pmc->vtable->attr_size; */
+ PMC_Attribute_Pool * pool = Parrot_gc_get_attribute_pool(interp, attr_size);
+ void * attrs = Parrot_gc_get_attributes_from_pool(interp, pool);
+ PMC_data(pmc) = attrs;
+}
+
+PARROT_CANNOT_RETURN_NULL
+void
+Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
+{
+ ASSERT_ARGS(Parrot_gc_free_pmc_attributes)
+ void * const data = PMC_data(pmc);
+ const size_t size = 0; /* pmc->vtable->attr_size; */
+ if (data != NULL) {
+ PMC_Attribute_Pool * const pool = Parrot_gc_get_attribute_pool(interp, size);
+ PMC_Attribute_Free_List * const item = (PMC_Attribute_Free_List *)data;
+ item->next = pool->free_list;
+ pool->free_list = item;
+ PMC_data(pmc) = NULL;
+ }
+}
+
+/*
+
=back
=head1 SEE ALSO
Modified: trunk/src/gc/gc_private.h
==============================================================================
--- trunk/src/gc/gc_private.h Sat Aug 1 23:05:54 2009 (r40367)
+++ trunk/src/gc/gc_private.h Sat Aug 1 23:51:24 2009 (r40368)
@@ -36,6 +36,10 @@
#endif /* __ia64__ */
+/* these values are used for the attribute allocator */
+#define GC_ATTRIB_POOLS_HEADROOM 8
+#define GC_ATTRIBS_INITIAL_ALLOC 128
+
/* We're using this here to add an additional pointer to a PObj without
having to actually add an entire pointer to every PObj-alike structure
in Parrot. Astute observers may notice that if the PObj is comprised of
@@ -56,6 +60,18 @@
void *start_objects;
} Small_Object_Arena;
+typedef struct PMC_Attribute_Free_List {
+ struct PMC_Attribute_Free_List * next;
+} PMC_Attribute_Free_List;
+
+typedef struct PMC_Attribute_Arena {
+ size_t used;
+ size_t total_objects;
+ struct PMC_Attribute_Arena * next;
+ struct PMC_Attribute_Arena * prev;
+ void *start_objects;
+} PMC_Attribute_Arena;
+
#if PARROT_GC_GMS
/*
* all objects have this header in front of the actual
@@ -111,6 +127,15 @@
#endif /* PARROT_GC_GMS */
+typedef struct PMC_Attribute_Pool {
+ size_t attr_size;
+ size_t total_objects;
+ size_t objects_per_alloc;
+ size_t num_free_objects;
+ PMC_Attribute_Free_List * free_list;
+ PMC_Attribute_Arena * top_arena;
+} PMC_Attribute_Pool;
+
/* Tracked resource pool */
typedef struct Small_Object_Pool {
Small_Object_Arena *last_Arena;
@@ -162,6 +187,10 @@
struct Small_Object_Pool *constant_string_header_pool;
struct Small_Object_Pool **sized_header_pools;
size_t num_sized;
+
+ PMC_Attribute_Pool **attrib_pools;
+ size_t num_attribs;
+
/*
* function slots that each subsystem must provide
*/
@@ -353,11 +382,34 @@
FUNC_MODIFIES(*pool)
FUNC_MODIFIES(*new_arena);
+void Parrot_gc_allocate_new_attributes_arena(PARROT_INTERP,
+ ARGMOD(PMC_Attribute_Pool *pool))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
void Parrot_gc_clear_live_bits(PARROT_INTERP,
ARGIN(const Small_Object_Pool *pool))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_CANNOT_RETURN_NULL
+PMC_Attribute_Pool * Parrot_gc_create_attrib_pool(PARROT_INTERP,
+ size_t attrib_size)
+ __attribute__nonnull__(1);
+
+PARROT_CANNOT_RETURN_NULL
+PMC_Attribute_Pool * Parrot_gc_get_attribute_pool(PARROT_INTERP,
+ size_t attrib_size)
+ __attribute__nonnull__(1);
+
+PARROT_CANNOT_RETURN_NULL
+void * Parrot_gc_get_attributes_from_pool(PARROT_INTERP,
+ ARGMOD(PMC_Attribute_Pool * pool))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(* pool);
+
void Parrot_gc_profile_end(PARROT_INTERP, int what)
__attribute__nonnull__(1);
@@ -399,9 +451,21 @@
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(pool) \
|| PARROT_ASSERT_ARG(new_arena)
+#define ASSERT_ARGS_Parrot_gc_allocate_new_attributes_arena \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp) \
+ || PARROT_ASSERT_ARG(pool)
#define ASSERT_ARGS_Parrot_gc_clear_live_bits __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp) \
|| PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_Parrot_gc_create_attrib_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_get_attribute_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_get_attributes_from_pool \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+ PARROT_ASSERT_ARG(interp) \
+ || PARROT_ASSERT_ARG(pool)
#define ASSERT_ARGS_Parrot_gc_profile_end __attribute__unused__ int _ASSERT_ARGS_CHECK = \
PARROT_ASSERT_ARG(interp)
#define ASSERT_ARGS_Parrot_gc_profile_start __attribute__unused__ int _ASSERT_ARGS_CHECK = \
Modified: trunk/src/gc/mark_sweep.c
==============================================================================
--- trunk/src/gc/mark_sweep.c Sat Aug 1 23:05:54 2009 (r40367)
+++ trunk/src/gc/mark_sweep.c Sat Aug 1 23:51:24 2009 (r40368)
@@ -1184,6 +1184,108 @@
return 0;
}
+/*
+
+=item C<void * Parrot_gc_get_attributes_from_pool(PARROT_INTERP,
+PMC_Attribute_Pool * pool)>
+
+=item C<void Parrot_gc_allocate_new_attributes_arena(PARROT_INTERP,
+PMC_Attribute_Pool *pool)>
+
+=item C<PMC_Attribute_Pool * Parrot_gc_get_attribute_pool(PARROT_INTERP, size_t
+attrib_size)>
+
+=item C<PMC_Attribute_Pool * Parrot_gc_create_attrib_pool(PARROT_INTERP, size_t
+attrib_size)>
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+void *
+Parrot_gc_get_attributes_from_pool(PARROT_INTERP, ARGMOD(PMC_Attribute_Pool * pool))
+{
+ ASSERT_ARGS(Parrot_gc_get_attributes_from_pool)
+ PMC_Attribute_Free_List * item;
+ if (pool->top_arena == NULL || pool->free_list == NULL)
+ Parrot_gc_allocate_new_attributes_arena(interp, pool);
+ item = pool->free_list;
+ pool->free_list = item->next;
+ return (void *)item;
+}
+
+void
+Parrot_gc_allocate_new_attributes_arena(PARROT_INTERP, ARGMOD(PMC_Attribute_Pool *pool))
+{
+ ASSERT_ARGS(Parrot_gc_allocate_new_attributes_arena)
+ size_t const num_items = GC_ATTRIBS_INITIAL_ALLOC;
+ size_t const item_size = pool->attr_size;
+ size_t i;
+ PMC_Attribute_Free_List * list;
+ PMC_Attribute_Arena * const new_arena = (PMC_Attribute_Arena *)mem_internal_allocate(
+ sizeof (PMC_Attribute_Arena) + (pool->attr_size * num_items));
+ new_arena->used = 0;
+ new_arena->total_objects = num_items;
+ new_arena->prev = NULL;
+ new_arena->next = pool->top_arena;
+ pool->top_arena = new_arena;
+ list = (PMC_Attribute_Free_List *)(pool + 1);
+ new_arena->start_objects = list;
+ for (i = 0; i < num_items; i++) {
+ list->next = (PMC_Attribute_Free_List *)((char *)list + item_size);
+ list = list->next;
+ }
+ list->next = pool->free_list;
+ pool->free_list = (PMC_Attribute_Free_List *)new_arena->start_objects;
+}
+
+PARROT_CANNOT_RETURN_NULL
+PMC_Attribute_Pool *
+Parrot_gc_get_attribute_pool(PARROT_INTERP, size_t attrib_size)
+{
+ ASSERT_ARGS(Parrot_gc_get_attribute_pool)
+ Arenas * const arenas = interp->arena_base;
+ PMC_Attribute_Pool ** pools = arenas->attrib_pools;
+ size_t size = (attrib_size < sizeof (void *))?(sizeof (void *)):(attrib_size);
+ size_t idx = size - sizeof (void *);
+ if (pools == NULL) {
+ size_t total_size = idx + GC_ATTRIB_POOLS_HEADROOM;
+ /* Allocate more then we strictly need, hoping that we can reduce the
+ number of resizes. 8 is just an arbitrary number */
+ pools = (PMC_Attribute_Pool **)mem_internal_allocate(total_size);
+ memset(pools, 0, total_size * sizeof (void*));
+ arenas->num_attribs = total_size;
+ }
+ if (arenas->num_attribs < idx) {
+ size_t total_size = idx + GC_ATTRIB_POOLS_HEADROOM;
+ size_t current_size = arenas->num_attribs;
+ size_t diff = total_size - current_size;
+ pools = (PMC_Attribute_Pool **)mem_internal_realloc(pools, total_size);
+ memset(pools + current_size, 0, diff * sizeof (void *));
+ arenas->attrib_pools = pools;
+ arenas->num_attribs = total_size;
+ }
+ if (pools[idx] == NULL)
+ pools[idx] = Parrot_gc_create_attrib_pool(interp, attrib_size);
+ return pools[idx];
+}
+
+PARROT_CANNOT_RETURN_NULL
+PMC_Attribute_Pool *
+Parrot_gc_create_attrib_pool(PARROT_INTERP, size_t attrib_size)
+{
+ ASSERT_ARGS(Parrot_gc_create_attrib_pool)
+ PMC_Attribute_Pool * const newpool = mem_internal_allocate_typed(PMC_Attribute_Pool);
+ newpool->attr_size = attrib_size;
+ newpool->total_objects = 0;
+ newpool->objects_per_alloc = 0;
+ newpool->num_free_objects = 0;
+ newpool->free_list = NULL;
+ newpool->top_arena = NULL;
+ return newpool;
+}
+
/*
More information about the parrot-commits
mailing list