[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