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 */

Reply via email to