[svn:parrot] r47132 - branches/gc_massacre/src/gc
bacek at svn.parrot.org
bacek at svn.parrot.org
Sun May 30 08:15:45 UTC 2010
Author: bacek
Date: Sun May 30 08:15:45 2010
New Revision: 47132
URL: https://trac.parrot.org/parrot/changeset/47132
Log:
Cargo-cult PMC_Attributes_Pool as Pool_Allocator
Modified:
branches/gc_massacre/src/gc/pool_allocator.c
branches/gc_massacre/src/gc/pool_allocator.h
Modified: branches/gc_massacre/src/gc/pool_allocator.c
==============================================================================
--- branches/gc_massacre/src/gc/pool_allocator.c Sun May 30 08:14:59 2010 (r47131)
+++ branches/gc_massacre/src/gc/pool_allocator.c Sun May 30 08:15:45 2010 (r47132)
@@ -14,17 +14,193 @@
*/
+#include "parrot/parrot.h"
+#include "pool_allocator.h"
+
/* HEADERIZER HFILE: src/gc/pool_allocator.h */
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-
+static void allocate_new_pool_arena(ARGMOD(Pool_Allocator *pool))
+ __attribute__nonnull__(1)
+ FUNC_MODIFIES(*pool);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_MALLOC
+static Pool_Allocator * Parrot_gc_create_pool_allocator(size_t object_size);
+
+#define ASSERT_ARGS_allocate_new_pool_arena __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_Parrot_gc_create_pool_allocator \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
/*
+=over 4
+
+=item C<static void * Parrot_gc_get_attributes_from_pool(PARROT_INTERP,
+Pool_Allocator * pool)>
+
+Get a new fixed-size storage space from the given pool. The pool contains
+information on the size of the item to allocate already.
+
+=item C<static void Parrot_gc_allocate_new_attributes_arena(Pool_Allocator
+*pool)>
+
+Allocate a new arena of fixed-sized data structures for the given pool.
+
+=item C<static void Parrot_gc_initialize_fixed_size_pools(PARROT_INTERP,
+Memory_Pools *mem_pools, size_t init_num_pools)>
+
+Initialize the pools (zeroize)
+
+=item C<static Pool_Allocator * Parrot_gc_get_attribute_pool(PARROT_INTERP,
+Memory_Pools *mem_pools, size_t attrib_size)>
+
+Find a fixed-sized data structure pool given the size of the object to
+allocate. If the pool does not exist, create it.
+
+=item C<static Pool_Allocator * Parrot_gc_create_attrib_pool(size_t
+attrib_idx)>
+
+Create a new pool for fixed-sized data items with the given C<attrib_size>.
+
+=back
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_MALLOC
+static Pool_Allocator *
+Parrot_gc_create_pool_allocator(size_t object_size)
+{
+ ASSERT_ARGS(Parrot_gc_create_pool_allocator)
+ const size_t attrib_size = object_size + sizeof (void *);
+ const size_t num_objs_raw =
+ (GC_FIXED_SIZE_POOL_SIZE - sizeof (Pool_Allocator_Arena)) / attrib_size;
+ const size_t num_objs = (num_objs_raw == 0)?(1):(num_objs_raw);
+ Pool_Allocator * const newpool = mem_internal_allocate_typed(Pool_Allocator);
+
+ newpool->attr_size = attrib_size;
+ newpool->total_objects = 0;
+ newpool->objects_per_alloc = num_objs;
+ newpool->num_free_objects = 0;
+ newpool->free_list = NULL;
+ newpool->top_arena = NULL;
+
+ return newpool;
+}
+
+PARROT_EXPORT
+void
+Parrot_gc_destroy_pool_alloctor(PARROT_INTERP, ARGMOD(Pool_Allocator *pool))
+{
+ // TODO
+}
+
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_EXPORT
+void *
+Parrot_gc_pool_allocate(PARROT_INTERP, ARGMOD(Pool_Allocator * pool))
+{
+ ASSERT_ARGS(Parrot_gc_pool_allocate)
+ Pool_Allocator_Free_List *item;
+
+#if GC_USE_LAZY_ALLOCATOR
+ if (pool->free_list) {
+ item = pool->free_list;
+ pool->free_list = item->next;
+ }
+ else if (pool->newfree) {
+ item = pool->newfree;
+ pool->newfree = (Pool_Allocator_Free_List *)
+ ((char *)(pool->newfree) + pool->attr_size);
+ if (pool->newfree >= pool->newlast)
+ pool->newfree = NULL;
+ }
+ else {
+ allocate_new_pool_arena(pool);
+ return Parrot_gc_pool_allocate(interp, pool);
+ }
+#else
+ if (pool->free_list == NULL)
+ allocate_new_pool_arena(pool);
+ item = pool->free_list;
+ pool->free_list = item->next;
+#endif
+
+ --pool->num_free_objects;
+ return (void *)item;
+}
+
+/*
+
+=item C<static void gc_ms_free_attributes_from_pool(Pool_Allocator_Pool *pool,
+void *data)>
+
+Frees a fixed-size data item back to the pool for later reallocation. Private
+to this file.
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_gc_pool_free(ARGMOD(Pool_Allocator *pool), ARGMOD(void *data))
+{
+ ASSERT_ARGS(Parrot_gc_pool_free)
+ Pool_Allocator_Free_List * const item = (Pool_Allocator_Free_List *)data;
+
+ item->next = pool->free_list;
+ pool->free_list = item;
+
+ ++pool->num_free_objects;
+}
+
+
+static void
+allocate_new_pool_arena(ARGMOD(Pool_Allocator *pool))
+{
+ ASSERT_ARGS(allocate_new_pool_arena)
+ Pool_Allocator_Free_List *next;
+
+ const size_t num_items = pool->objects_per_alloc;
+ const size_t item_size = pool->attr_size;
+ const size_t item_space = item_size * num_items;
+ const size_t total_size = sizeof (Pool_Allocator_Arena) + item_space;
+
+ Pool_Allocator_Arena * const new_arena = (Pool_Allocator_Arena *)mem_internal_allocate(
+ total_size);
+
+ new_arena->prev = NULL;
+ new_arena->next = pool->top_arena;
+ pool->top_arena = new_arena;
+ next = (Pool_Allocator_Free_List *)(new_arena + 1);
+
+#if GC_USE_LAZY_ALLOCATOR
+ pool->newfree = next;
+ pool->newlast = (Pool_Allocator_Free_List *)((char *)next + item_space);
+#else
+ pool->free_list = next;
+ for (i = 0; i < num_items; ++i) {
+ list = next;
+ list->next = (Pool_Allocator_Free_List *)((char *)list + item_size);
+ next = list->next;
+ }
+ list->next = pool->free_list;
+#endif
+
+ pool->num_free_objects += num_items;
+ pool->total_objects += num_items;
+}
+
+/*
+
=back
=cut
Modified: branches/gc_massacre/src/gc/pool_allocator.h
==============================================================================
--- branches/gc_massacre/src/gc/pool_allocator.h Sun May 30 08:14:59 2010 (r47131)
+++ branches/gc_massacre/src/gc/pool_allocator.h Sun May 30 08:15:45 2010 (r47132)
@@ -17,6 +17,16 @@
#include "parrot/settings.h"
+/* these values are used for the attribute allocator */
+#define GC_ATTRIB_POOLS_HEADROOM 8
+#define GC_FIXED_SIZE_POOL_SIZE 4096
+
+/* Use the lazy allocator. Since it amortizes arena allocation costs, turn
+ this on at the same time that you increase the size of allocated arenas.
+ increase *_HEADERS_PER_ALLOC and GC_FIXED_SIZE_POOL_SIZE to be large
+ enough to satisfy most startup costs. */
+#define GC_USE_LAZY_ALLOCATOR 1
+
typedef struct Pool_Allocator_Free_List {
struct Pool_Allocator_Free_List * next;
} Pool_Allocator_Free_List;
@@ -26,7 +36,7 @@
struct Pool_Allocator_Arena * prev;
} Pool_Allocator_Arena;
-typedef struct Pool_Allocator_Pool {
+typedef struct Pool_Allocator {
size_t attr_size;
size_t total_objects;
size_t objects_per_alloc;
@@ -37,11 +47,43 @@
Pool_Allocator_Free_List * newfree;
Pool_Allocator_Free_List * newlast;
#endif
-} Pool_Allocator_Pool;
+} Pool_Allocator;
+
/* HEADERIZER BEGIN: src/gc/pool_allocator.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+PARROT_EXPORT
+void Parrot_gc_destroy_pool_alloctor(PARROT_INTERP,
+ ARGMOD(Pool_Allocator *pool))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_EXPORT
+void * Parrot_gc_pool_allocate(PARROT_INTERP, ARGMOD(Pool_Allocator * pool))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(* pool);
+
+PARROT_EXPORT
+void Parrot_gc_pool_free(ARGMOD(Pool_Allocator *pool), ARGMOD(void *data))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool)
+ FUNC_MODIFIES(*data);
+
+#define ASSERT_ARGS_Parrot_gc_destroy_pool_alloctor \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_Parrot_gc_pool_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_Parrot_gc_pool_free __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool) \
+ , PARROT_ASSERT_ARG(data))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/gc/pool_allocator.c */
More information about the parrot-commits
mailing list