Author: heimdall
Date: Wed Aug 10 16:47:48 2005
New Revision: 8911
Modified:
branches/gmc/include/parrot/pobj.h
branches/gmc/include/parrot/smallobject.h
branches/gmc/src/gc_gmc.c
Log:
Small change of API for Gc_gmc_gen and get_free_object almost working (type info
needed for the real thing).
Modified: branches/gmc/include/parrot/pobj.h
==============================================================================
--- branches/gmc/include/parrot/pobj.h (original)
+++ branches/gmc/include/parrot/pobj.h Wed Aug 10 16:47:48 2005
@@ -98,13 +98,12 @@ typedef Buffer PObj;
#define PObj_bufstart(pmc) (pmc)->obj.u._b._bufstart
#define PObj_buflen(pmc) (pmc)->obj.u._b._buflen
#define PMC_body(pmc) (pmc)->body
-#define PMC_struct_val(pmc) LVALUE_CAST(DPOINTER*,PMC_body(pmc))
-#define PMC_pmc_val(pmc) LVALUE_CAST(PMC*,PMC_body(pmc))
-#define PMC_int_val(pmc) LVALUE_CAST(INTVAL,PMC_body(pmc))
-/* TODO: real int_val2 */
-#define PMC_int_val2(pmc) LVALUE_CAST(INTVAL,PMC_body(pmc))
-#define PMC_num_val(pmc) LVALUE_CAST(FLOATVAL,PMC_body(pmc))
-#define PMC_str_val(pmc) LVALUE_CAST(struct parrot_string_t
*,PMC_body(pmc))
+#define PMC_struct_val(pmc) PMC_body(pmc)->_ptrs._struct_val
+#define PMC_pmc_val(pmc) PMC_body(pmc)->_ptrs._pmc_val
+#define PMC_int_val(pmc) PMC_body(pmc)->_i._int_val
+#define PMC_int_val2(pmc) PMC_body(pmc)->_i._int_val2
+#define PMC_num_val(pmc) PMC_body(pmc)->_num_val
+#define PMC_str_val(pmc) PMC_body(pmc)->_string_val
#else
@@ -164,8 +163,8 @@ struct parrot_string_t {
/* TODO: Change to a real pmc_body type. */
#if PARROT_GC_GMC
-/* typedef UnionVal pmc_body;*/
-typedef void pmc_body;
+#define DEFAULT_BODY UnionVal
+#define PMC_BODY DEFAULT_BODY
/* Hack for the get_FLAGS macro to be happy. */
typedef struct flags_holder {
@@ -175,7 +174,7 @@ typedef struct flags_holder {
struct PMC {
#if PARROT_GC_GMC
- pmc_body *body;
+ PMC_BODY *body;
flags_holder obj;
#else
pobj_t obj;
Modified: branches/gmc/include/parrot/smallobject.h
==============================================================================
--- branches/gmc/include/parrot/smallobject.h (original)
+++ branches/gmc/include/parrot/smallobject.h Wed Aug 10 16:47:48 2005
@@ -126,7 +126,7 @@ typedef struct _gc_gmc_hdr {
* smallobject.h ? pobj.h ? gc_gmc.h ? */
typedef enum gmc_flags {
/* Private GC flags, for internal use. */
- Gmc_private_0_FLAG = 1 << 0,
+ Gmc_marking_FLAG = 1 << 0,
Gmc_private_1_FLAG = 1 << 1,
Gmc_private_2_FLAG = 1 << 2,
Gmc_private_3_FLAG = 1 << 3,
@@ -166,7 +166,7 @@ typedef enum gmc_flags {
#define Gmc_PMC_body_flag_CLEAR(flag, pmc_body)
Gmc_PMC_hdr_flag_CLEAR(flag, Gmc_PMC_body_get_hdr(pmc_body))
/* Macros for access from PMC*. */
-#define Gmc_PMC_get_HDR(pmc)
Gmc_PMC_body_get_hdr(PMC_body(pmc))
+#define Gmc_PMC_get_HDR(pmc)
Gmc_PMC_body_get_HDR(PMC_body(pmc))
#define Gmc_PMC_get_FLAGS(pmc)
Gmc_PMC_hdr_get_FLAGS(Gmc_PMC_get_HDR(pmc))
#define Gmc_PMC_flag_TEST(flag, pmc) Gmc_PMC_hdr_flag_TEST(flag,
Gmc_PMC_get_HDR(pmc))
#define Gmc_PMC_flag_SET(flag, pmc) Gmc_PMC_hdr_flag_SET(flag,
Gmc_PMC_get_HDR(pmc))
@@ -193,9 +193,9 @@ typedef struct _gc_gmc_hdr_list {
typedef struct _gc_gmc_gen {
struct _gc_gmc_gen *next; /* Next generation in the linked list. */
struct _gc_gmc_gen *prev; /* Previous generation. */
- Gc_gmc_hdr *first; /* Array of objects. */
- Gc_gmc_hdr *fst_free; /* First free place. */
- Gc_gmc_hdr *last; /* Last allocated object */
+ void *first; /* Array of objects. */
+ void *fst_free; /* First free place. */
+ size_t remaining; /* Remaining size. */
Gc_gmc_hdr_list *IGP; /* Inter Generational pointers set. */
} Gc_gmc_gen;
@@ -205,10 +205,10 @@ typedef struct _gc_gmc {
UINTVAL nb_gen; /* Total number of generations. */
UINTVAL nb_empty_gen; /* Number of empty generations. */
UINTVAL alloc_obj; /* Number of allocated objects. */
- Gc_gmc_gen *first; /* First generation (aggregate, young objects). */
- Gc_gmc_gen *fst_free; /* End of aggregate objects. */
- Gc_gmc_gen *lst_free; /* Beginning of non-aggregate, old objects. */
- Gc_gmc_gen *last; /* Very last generation. */
+ Gc_gmc_gen *yng_fst; /* First generation (aggregate, young objects). */
+ Gc_gmc_gen *yng_lst; /* End of aggregate objects. */
+ Gc_gmc_gen *old_fst; /* Beginning of non-aggregate, old objects. */
+ Gc_gmc_gen *old_lst; /* Very last generation. */
Gc_gmc_gen *timely; /* Objects needing timely destruction. */
Gc_gmc_gen *constant; /* Objects that will never be collected. */
} Gc_gmc;
Modified: branches/gmc/src/gc_gmc.c
==============================================================================
--- branches/gmc/src/gc_gmc.c (original)
+++ branches/gmc/src/gc_gmc.c Wed Aug 10 16:47:48 2005
@@ -34,7 +34,7 @@ gc_gmc_gen_init(Interp *interpreter)
/* And fill the blanks. */
gen->fst_free = gen->first;
- gen->last = NULL;
+ gen->remaining = GMC_GEN_SIZE;
/* We have an IGP basis : only one store. */
IGP_store = mem_sys_allocate(sizeof(Gc_gmc_hdr_store));
@@ -56,7 +56,7 @@ gc_gmc_insert_gen(Interp *interpreter, s
Gc_gmc_gen *cur_gen;
void *ptr;
- cur_gen = pool->gc->last;
+ cur_gen = pool->gc->old_lst;
if (cur_gen)
ptr = (void*)cur_gen->first;
else
@@ -80,14 +80,15 @@ gc_gmc_insert_gen(Interp *interpreter, s
gen->next = cur_gen->next;
} else {
gen->next = NULL;
- pool->gc->first = gen;
- pool->gc->last = gen;
+ pool->gc->yng_fst = gen;
+ pool->gc->old_lst = gen;
}
gen->prev = cur_gen;
- if (pool->gc->last == cur_gen)
- pool->gc->last = gen;
+ if (pool->gc->old_lst == cur_gen)
+ pool->gc->old_lst = gen;
}
+static void gc_gmc_pool_deinit(Interp *, struct Small_Object_Pool *);
static void
gc_gmc_pool_init(Interp *interpreter, struct Small_Object_Pool *pool)
@@ -108,10 +109,10 @@ gc_gmc_pool_init(Interp *interpreter, st
gc->nb_gen = GMC_GEN_INIT_NUMBER;
gc->nb_empty_gen = GMC_GEN_INIT_NUMBER;
gc->alloc_obj = 0;
- gc->first = NULL;
- gc->fst_free = NULL;
- gc->lst_free = NULL;
- gc->last = NULL;
+ gc->yng_fst = NULL;
+ gc->yng_lst = NULL;
+ gc->old_fst = NULL;
+ gc->old_lst = NULL;
gc->timely = gc_gmc_gen_init(interpreter);
gc->constant = gc_gmc_gen_init(interpreter);
pool->gc = gc;
@@ -121,11 +122,51 @@ gc_gmc_pool_init(Interp *interpreter, st
gen = gc_gmc_gen_init(interpreter);
gc_gmc_insert_gen(interpreter, pool, gen);
}
+
+ /* Separate the generations in two halves : one is young (= aggregate
+ * objects), the other is old (non-aggregate objects). */
+ for (i = 0, gen = gc->yng_fst; i < (GMC_GEN_INIT_NUMBER/2); i++, gen =
gen->next);
+ gc->old_fst = gen;
+ gc->old_lst = gen;
+ /* Now cut the bridges between these two parts. */
+ gen->prev->next = NULL;
+ gen->prev = NULL;
+ gc->yng_lst = gc->yng_fst;
+}
+
+static void
+gc_gmc_pool_deinit(Interp *interpreter, struct Small_Object_Pool *pool)
+{
+ Gc_gmc *gc;
+ Gc_gmc_gen *gen;
+ Gc_gmc_hdr_store *store, *st2;
+
+ gc = pool->gc;
+ for (gen = gc->yng_fst; gen; gen = gen->next)
+ {
+ if (gen->prev)
+ mem_sys_free(gen->prev);
+ mem_sys_free(gen->first);
+ for (store = gen->IGP->first; store; st2 =
store->next,mem_sys_free(store),
+ store = st2);
+ }
+
+ for (gen = gc->old_fst; gen; gen = gen->next)
+ {
+ if (gen->prev)
+ mem_sys_free(gen->prev);
+ mem_sys_free(gen->first);
+ for (store = gen->IGP->first; store; st2 =
store->next,mem_sys_free(store),
+ store = st2);
+ }
}
void gc_gmc_deinit(Interp *interpreter)
{
+ struct Arenas *arena_base = interpreter->arena_base;
+
+ gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);
}
@@ -151,7 +192,7 @@ void Parrot_gc_gmc_init(Interp *interpre
/******************************* FAKE THINGS ********************************/
void *
-gc_gmc_get_free_object(Interp *interpreter,
+gc_gmc_fake_get_free_object(Interp *interpreter,
struct Small_Object_Pool *pool)
{
return NULL;
@@ -200,20 +241,33 @@ gc_gmc_more_objects(Interp *interpreter,
/* The real thing, but not plugged yet */
+/* Here we allocate a PMC with NULL pmc_body, as it is non-typed. */
+/* This function should not be called anywhere if possible. */
void *
-gc_gmc_real_get_free_object(Interp *interpreter,
+gc_gmc_get_free_object(Interp *interpreter,
struct Small_Object_Pool *pool)
{
void *ptr;
Gc_gmc *gc = pool->gc;
- /* Is this the real test we want ? */
- if (gc->fst_free == gc->lst_free)
+ /* This is a non-aggregate object. */
+ Gc_gmc_gen *gen = gc->old_lst;
+ size_t size = sizeof(Gc_gmc_hdr);
+
+ /* Should we use the next generation ? */
+ if (size > gen->remaining)
+ gen = gen->next;
+
+ /* Do we need more generations ? */
+ if (!gen)
(*pool->more_objects) (interpreter, pool);
- /* TODO: find a way to know if we want an aggregate allocation or not.
- * For now, let's say that everything is non-aggregate. */
-
+ gc->old_lst = gen;
+
+ ptr = gen->fst_free;
+ gen->fst_free = (INTVAL)ptr + size;
+ gen->remaining -= size;
+
return ptr;
}
@@ -221,9 +275,18 @@ void
gc_gmc_real_add_free_object(Interp *interpreter,
struct Small_Object_Pool *pool, void *to_add)
{
- Gc_gmc *gc = pool->gc;
+ Gmc_PMC_flag_SET(marking,(PMC*)to_add);
}
+void *
+gc_gmc_real_get_free_typed_object(Interp *interpreter,
+ struct Small_Object_Pool *pool, INTVAL base_type)
+{
+ return NULL;
+}
+
+
+
#endif /* PARROT_GC_GMC */