Author: heimdall
Date: Thu Aug 18 09:24:06 2005
New Revision: 8991
Modified:
branches/gmc/include/parrot/smallobject.h
branches/gmc/src/gc_gmc.c
branches/gmc/src/headers.c
Log:
Change in smallobject.h for recording headers area. First (small) version of
gc_gmc_run that only wipes out memory at the end. 1% more tests passed,
cheers...
Modified: branches/gmc/include/parrot/smallobject.h
==============================================================================
--- branches/gmc/include/parrot/smallobject.h (original)
+++ branches/gmc/include/parrot/smallobject.h Thu Aug 18 09:24:06 2005
@@ -183,6 +183,23 @@ typedef struct _gc_gmc_hdr_list {
} Gc_gmc_hdr_list;
+typedef struct _gc_gmc_header_area {
+ void *fst;
+ void *lst;
+} Gc_gmc_header_area;
+
+typedef struct _gc_gmc_area_store {
+ struct _gc_gmc_area_store *next;
+ Gc_gmc_header_area **ptr;
+ Gc_gmc_header_area * (store[GC_GMC_STORE_SIZE]);
+} Gc_gmc_area_store;
+
+typedef struct _gc_gmc_area_list {
+ Gc_gmc_area_store *first;
+ Gc_gmc_area_store *last;
+} Gc_gmc_area_list;
+
+
/* A generation for GMC. */
typedef struct _gc_gmc_gen {
struct _gc_gmc_gen *next; /* Next generation in the linked list. */
@@ -257,6 +274,7 @@ struct Small_Object_Pool {
#if PARROT_GC_GMC
Gc_gmc *gc;
+ Gc_gmc_area_list *areas; /* pointers to the headers areas */
#endif
};
Modified: branches/gmc/src/gc_gmc.c
==============================================================================
--- branches/gmc/src/gc_gmc.c (original)
+++ branches/gmc/src/gc_gmc.c Thu Aug 18 09:24:06 2005
@@ -135,7 +135,15 @@ gc_gmc_pool_init(Interp *interpreter, st
struct Arenas *arena_base;
Gc_gmc *gc;
Gc_gmc_gen *gen;
+ Gc_gmc_area_store *store;
int i;
+
+ store = mem_sys_allocate_zeroed(sizeof(Gc_gmc_area_store));
+ store->ptr = &(store->store[0]);
+ store->next = NULL;
+ pool->areas = mem_sys_allocate(sizeof(Gc_gmc_area_list));
+ pool->areas->first = store;
+ pool->areas->last = store;
pool->add_free_object = gc_gmc_add_free_object;
pool->get_free_object = gc_gmc_get_free_object;
@@ -180,26 +188,28 @@ static void
gc_gmc_pool_deinit(Interp *interpreter, struct Small_Object_Pool *pool)
{
Gc_gmc *gc;
- Gc_gmc_gen *gen;
+ Gc_gmc_gen *gen, *gen_nxt;
Gc_gmc_hdr_store *store, *st2;
gc = pool->gc;
- for (gen = gc->yng_fst; gen; gen = gen->next)
+ for (gen = gc->yng_fst; gen;)
{
- if (gen->prev)
- mem_sys_free(gen->prev);
+ gen_nxt = gen->next;
mem_sys_free(gen->first);
+ mem_sys_free(gen);
for (store = gen->IGP->first; store; st2 =
store->next,mem_sys_free(store),
store = st2);
+ gen = gen_nxt;
}
- for (gen = gc->old_fst; gen; gen = gen->next)
+ for (gen = gc->old_fst; gen;)
{
- if (gen->prev)
- mem_sys_free(gen->prev);
+ gen_nxt = gen->next;
mem_sys_free(gen->first);
+ mem_sys_free(gen);
for (store = gen->IGP->first; store; st2 =
store->next,mem_sys_free(store),
store = st2);
+ gen = gen_nxt;
}
}
@@ -208,22 +218,73 @@ static void gc_gmc_deinit(Interp *interp
{
struct Arenas *arena_base = interpreter->arena_base;
- gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);
+ /* This is done in gc_gmc_do_dod_run when given the right flag. */
+ /*gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);*/
+
+}
+static int sweep_pmc (Interp *interpreter, struct Small_Object_Pool *pool,
+ int flag, void *arg)
+{
+ struct Arenas *arena_base = interpreter->arena_base;
+ PMC *ptr;
+ Gc_gmc_area_store *store;
+ Gc_gmc_header_area *area;
+ for (store = pool->areas->first; store; store = store->next)
+ {
+ for (area = store->store[0]; (UINTVAL)area < (UINTVAL)store->ptr;
area++)
+ {
+ for (ptr = (PMC*)area->fst; (UINTVAL)ptr < (UINTVAL)area->lst;
+ ptr = (PMC*)((char*)ptr + pool->object_size))
+ {
+ if (PObj_live_TEST(ptr))
+ {
+ /* This shouldn't be necessary. */
+ if (PObj_needs_early_DOD_TEST(ptr))
+ --arena_base->num_early_DOD_PMCs;
+ if (PObj_active_destroy_TEST(ptr))
+ VTABLE_destroy(interpreter, ptr);
+ if (Gmc_has_PMC_EXT_TEST(ptr) && PMC_data(ptr))
+ {
+ mem_sys_free(PMC_data(ptr));
+ PMC_data(ptr) = NULL;
+ }
+ PObj_live_CLEAR(ptr);
+ }
+ }
+ }
+ }
+ return 0;
}
static void gc_gmc_run(Interp *interpreter, int flags)
{
- if (flags & DOD_finish_FLAG) {
+ struct Arenas *arena_base = interpreter->arena_base;
+
+ if (arena_base->DOD_block_level)
+ return;
+ ++arena_base->DOD_block_level;
+
+ /* This interpreter will be destroyed, free everything. */
+ if (flags & DOD_finish_FLAG) {
+ /* First the pmc headers */
+ Parrot_forall_header_pools(interpreter, POOL_PMC, 0, sweep_pmc);
+
+ /* Then the pmc_bodies. */
+ /* TODO: free the PMC_data too. */
+ gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);
+
#ifdef GMC_DEBUG
- fprintf (stderr, "GMC: Trying to run dod_run for final sweeping\n");
+ fprintf (stderr, "GMC: Trying to run dod_run for final sweeping\n");
#endif /* GMC_DEBUG */
- return;
- } else {
+ --arena_base->DOD_block_level;
+ return;
+ } else {
#ifdef GMC_DEBUG
- fprintf (stderr, "GMC: Trying to run dod_run for normal allocation\n");
+ fprintf (stderr, "GMC: Trying to run dod_run for normal allocation\n");
#endif /* GMC_DEBUG */
- }
+ --arena_base->DOD_block_level;
+ }
}
@@ -527,6 +588,25 @@ gc_gmc_more_objects(Interp *interpreter,
void *fst = mem_sys_allocate_zeroed(NUM_NEW_OBJ * pool->object_size);
int i;
char *obj;
+ Gc_gmc_area_store *store = pool->areas->last;
+
+ /* If we have no more space in the store, expand it. */
+ if ((UINTVAL)(*(store->ptr)) >=
(UINTVAL)&(store->store[GC_GMC_STORE_SIZE-1]))
+ {
+ store = mem_sys_allocate_zeroed(sizeof(Gc_gmc_area_store));
+ store->ptr = &(store->store[0]);
+ store->next = NULL;
+ pool->areas->last->next = store;
+ pool->areas->last = store;
+ }
+
+ /* Record the new area. */
+ *store->ptr = mem_sys_allocate(sizeof(Gc_gmc_header_area));
+ (*store->ptr)->fst = fst;
+ (*store->ptr)->lst = (void *)((char*)fst + NUM_NEW_OBJ *
pool->object_size);
+ store->ptr++;
+
+ /* Set the internal state correctly. */
for (i = 0, obj = (char*)fst; i < NUM_NEW_OBJ; i++, obj +=
pool->object_size)
*(void**)obj = obj + pool->object_size;
*(void**)(obj - pool->object_size) = NULL;
Modified: branches/gmc/src/headers.c
==============================================================================
--- branches/gmc/src/headers.c (original)
+++ branches/gmc/src/headers.c Thu Aug 18 09:24:06 2005
@@ -690,6 +690,7 @@ Parrot_initialize_header_pools(Interp *i
arena_base->constant_pmc_pool->name = "constant_pmc";
arena_base->constant_pmc_pool->objects_per_alloc =
CONSTANT_PMC_HEADERS_PER_ALLOC;
+
}
/*