Author: heimdall
Date: Sat Aug 20 19:09:10 2005
New Revision: 9010

Modified:
   branches/gmc/include/parrot/smallobject.h
   branches/gmc/src/gc_gmc.c
   branches/gmc/src/headers.c
Log:
Header allocation now done using pool->last_Arena. Function 
gc_gmc_alloc_objects complete. Corrects memcpy bug but the PObj_exists flag 
seem to be sometime overwritten, which leads to corruption...

Modified: branches/gmc/include/parrot/smallobject.h
==============================================================================
--- branches/gmc/include/parrot/smallobject.h   (original)
+++ branches/gmc/include/parrot/smallobject.h   Sat Aug 20 19:09:10 2005
@@ -15,6 +15,9 @@ struct Small_Object_Arena {
     struct Small_Object_Arena *prev;
     struct Small_Object_Arena *next;
     void *start_objects;
+#if PARROT_GC_GMC
+    void *start_looking; /* Start looking for free objects from here. */
+#endif
 };
 
 #if ARENA_DOD_FLAGS
@@ -116,6 +119,9 @@ typedef struct _gc_gms_gen {
 /* Number of generations at init time. */
 #define GMC_GEN_INIT_NUMBER 16
 
+/* Number of new object headers added when pool->alloc_objects is called */
+#define GMC_NUM_NEW_OBJ 512
+
 
 /* This header is appended to all gc objects. */
 typedef struct _gc_gmc_hdr {
@@ -188,17 +194,6 @@ typedef struct _gc_gmc_header_area {
     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 {
@@ -274,8 +269,6 @@ struct Small_Object_Pool {
 
 #if PARROT_GC_GMC
     Gc_gmc *gc;
-    Gc_gmc_area_list *areas; /* pointers to the headers areas */
-    void *limit; /* Last object to be allocated in the current area */
 #endif
 };
 

Modified: branches/gmc/src/gc_gmc.c
==============================================================================
--- branches/gmc/src/gc_gmc.c   (original)
+++ branches/gmc/src/gc_gmc.c   Sat Aug 20 19:09:10 2005
@@ -3,6 +3,9 @@
 #if PARROT_GC_GMC
 
 
+#define UNITS_PER_ALLOC_GROWTH_FACTOR 1.75
+#define POOL_MAX_BYTES 65536*128
+
 static void gc_gmc_add_free_object(Interp*, struct Small_Object_Pool*, void*);
 static void *gc_gmc_get_free_typed_object(Interp*, struct Small_Object_Pool*, 
INTVAL);
 static void *gc_gmc_get_free_sized_object(Interp*, struct Small_Object_Pool*, 
size_t);
@@ -13,7 +16,7 @@ static void gc_gmc_more_pmc_bodies(Inter
 
 
 /* Determines the size of a PMC according to its base_type. */
-static size_t
+    static size_t
 gc_gmc_get_PMC_size(Interp *interpreter, INTVAL base_type)
 {
     VTABLE *vtable = Parrot_base_vtables[base_type];
@@ -24,7 +27,7 @@ gc_gmc_get_PMC_size(Interp *interpreter,
 
 
 /* Allocates and initializes a generation, but does not plug it to the pool 
yet. */
-static Gc_gmc_gen *
+    static Gc_gmc_gen *
 gc_gmc_gen_init(Interp *interpreter)
 {
     Gc_gmc_gen *gen;
@@ -33,7 +36,7 @@ gc_gmc_gen_init(Interp *interpreter)
 
     gen = mem_sys_allocate(sizeof(Gc_gmc_gen));
     gen->first = mem_sys_allocate(GMC_GEN_SIZE);
-    
+
     /* And fill the blanks. */
     gen->fst_free = gen->first;
     gen->remaining = GMC_GEN_SIZE;
@@ -51,13 +54,13 @@ gc_gmc_gen_init(Interp *interpreter)
 #ifdef GMC_DEBUG
     fprintf(stderr, "Allocating gen at %p, first at %p, limit at %p\n", gen, 
gen->first, (char*)gen->first + gen->remaining);
 #endif
-    
+
     return gen;
 }
 
 /* Inserts the given generation to the right place, keeping all generation 
  * sorted (by insertion sort). */
-static void
+    static void
 gc_gmc_insert_gen(Interp *interpreter, Gc_gmc *gc, Gc_gmc_gen *gen)
 {
     Gc_gmc_gen *cur_gen;
@@ -72,22 +75,22 @@ gc_gmc_insert_gen(Interp *interpreter, G
     /* Find the right place for the address malloc gave us. */
     while ((UINTVAL)ptr > (UINTVAL)gen->first)
     {
-      cur_gen = cur_gen->prev;
-      if (cur_gen)
-         ptr = cur_gen->first;
-      else
-         ptr = NULL;
+       cur_gen = cur_gen->prev;
+       if (cur_gen)
+           ptr = cur_gen->first;
+       else
+           ptr = NULL;
     }
-    
+
     /* Insert the generation. */
     if (cur_gen)
     {
-      if (cur_gen->next)
-      {
-       cur_gen->next->prev = gen;
-      }
-      gen->next = cur_gen->next;
-      cur_gen->next = gen;
+       if (cur_gen->next)
+       {
+           cur_gen->next->prev = gen;
+       }
+       gen->next = cur_gen->next;
+       cur_gen->next = gen;
     } else {
        if (gc->yng_fst)
        {
@@ -102,10 +105,10 @@ gc_gmc_insert_gen(Interp *interpreter, G
     }
     gen->prev = cur_gen;
     if (gc->old_lst == cur_gen)
-      gc->old_lst = gen;
+       gc->old_lst = gen;
 }
 
-static void
+    static void
 gc_gmc_test_linked_list_gen(Interp *interpreter, Gc_gmc *gc)
 {
     Gc_gmc_gen *gen;
@@ -129,22 +132,14 @@ gc_gmc_test_linked_list_gen(Interp *inte
 
 static void gc_gmc_pool_deinit(Interp *, struct Small_Object_Pool *);
 
-static void 
+    static void 
 gc_gmc_pool_init(Interp *interpreter, struct Small_Object_Pool *pool) 
 {
     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;
     pool->get_free_typed_object = gc_gmc_get_free_typed_object;
@@ -153,7 +148,7 @@ gc_gmc_pool_init(Interp *interpreter, st
     pool->more_objects    = gc_gmc_more_objects;
 
     gc = mem_sys_allocate(sizeof(Gc_gmc));
-    
+
     gc->nb_gen = GMC_GEN_INIT_NUMBER;
     gc->nb_empty_gen = GMC_GEN_INIT_NUMBER;
     gc->alloc_obj = 0;
@@ -164,7 +159,7 @@ gc_gmc_pool_init(Interp *interpreter, st
     gc->timely = gc_gmc_gen_init(interpreter);
     gc->constant = gc_gmc_gen_init(interpreter);
     pool->gc = gc;
-    
+
     for (i = 0; i < GMC_GEN_INIT_NUMBER; i++)
     {
        gen = gc_gmc_gen_init(interpreter);
@@ -184,31 +179,31 @@ gc_gmc_pool_init(Interp *interpreter, st
     gc->yng_lst = gc->yng_fst;
 }
 
-static void
+    static void
 gc_gmc_pool_deinit(Interp *interpreter, struct Small_Object_Pool *pool)
 {
     Gc_gmc *gc;
     Gc_gmc_gen *gen, *gen_nxt;
     Gc_gmc_hdr_store *store, *st2;
-    
+
     gc = pool->gc;
     for (gen = gc->yng_fst; gen;)
     {
        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);
+       mem_sys_free(gen->first);
+       mem_sys_free(gen);
        gen = gen_nxt;
     }
 
     for (gen = gc->old_fst; gen;)
     {
        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);
+       mem_sys_free(gen->first);
+       mem_sys_free(gen);
        gen = gen_nxt;
     }
 }
@@ -217,7 +212,7 @@ gc_gmc_pool_deinit(Interp *interpreter, 
 static void gc_gmc_deinit(Interp *interpreter)
 {
     struct Arenas *arena_base = interpreter->arena_base;
-    
+
     /* This is done in gc_gmc_do_dod_run when given the right flag. */
     /*gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);*/
 
@@ -228,36 +223,33 @@ static int sweep_pmc (Interp *interprete
 {
     struct Arenas *arena_base = interpreter->arena_base;
     PMC *ptr;
-    Gc_gmc_area_store *store;
-    Gc_gmc_header_area **area;
+    struct Small_Object_Arena *arena;
     int sweep = 0;
 
     /* Go through all the headers of the pool. */
-    for (store = pool->areas->first; store; store = store->next)
+    for (arena = pool->last_Arena; arena; arena = arena->prev)
     {
-       for (area = &store->store[0]; (UINTVAL)area < (UINTVAL)store->ptr; 
area++)
+       for (ptr = (PMC*)arena->start_objects; (UINTVAL)ptr < 
+               (UINTVAL)((char*)arena->start_objects + pool->object_size * 
arena->total_objects);
+               ptr = (PMC*)((char*)ptr + pool->object_size))
        {
-           for (ptr = (PMC*)(*area)->fst; (UINTVAL)ptr < (UINTVAL)(*area)->lst;
-                   ptr = (PMC*)((char*)ptr + pool->object_size))
+           if (PObj_exists_TEST(ptr) && !PObj_live_TEST(ptr))
            {
-               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);
-                   }
-                   PObj_exists_CLEAR(ptr);
-                   sweep++;
-                   /* This is the work of the VTABLE_destroy function. */
-                   /*
-                   if ((Gmc_has_PMC_EXT_TEST(ptr) || 
PObj_is_PMC_EXT_TEST(ptr)) && PMC_data(ptr))
-                   {
-                       mem_sys_free(PMC_data(ptr));
-                       PMC_data(ptr) = NULL;
-                   } */
+               /* 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);
                }
+               PObj_exists_CLEAR(ptr);
+               sweep++;
+               /* This is the work of the VTABLE_destroy function. */
+               /*
+                  if ((Gmc_has_PMC_EXT_TEST(ptr) || PObj_is_PMC_EXT_TEST(ptr)) 
&& PMC_data(ptr))
+                  {
+                  mem_sys_free(PMC_data(ptr));
+                  PMC_data(ptr) = NULL;
+                  } */
            }
        }
     }
@@ -273,61 +265,59 @@ static int sweep_buf (Interp *interprete
 {
     struct Arenas *arena_base = interpreter->arena_base;
     PObj *obj;
-    Gc_gmc_area_store *store;
-    Gc_gmc_header_area **area;
+    struct Small_Object_Arena *arena;
+
     /* Go through all the headers of the pool. */
-    for (store = pool->areas->first; store; store = store->next)
+    for (arena = pool->last_Arena; arena; arena = arena->prev)
     {
-       for (area = &store->store[0]; (UINTVAL)area < (UINTVAL)store->ptr; 
area++)
+       for (obj = (PObj*)arena->start_objects; (UINTVAL)obj < 
+               (UINTVAL)((char*)arena->start_objects + pool->object_size * 
arena->total_objects);
+               obj = (PObj*)((char*)obj + pool->object_size))
        {
-           for (obj = (PObj*)(*area)->fst; (UINTVAL)obj < 
(UINTVAL)(*area)->lst;
-                   obj = (PObj*)((char*)obj + pool->object_size))
-           {
 
-               if (PObj_exists_TEST(obj))
-               {
-                   if (PObj_sysmem_TEST(obj) && PObj_bufstart(obj)) {
-                       /* has sysmem allocated, e.g. string_pin */
-                       mem_sys_free(PObj_bufstart(obj));
-                       PObj_bufstart(obj) = NULL;
-                       PObj_buflen(obj) = 0;
-                   }
-                   else {
+           if (PObj_exists_TEST(obj))
+           {
+               if (PObj_sysmem_TEST(obj) && PObj_bufstart(obj)) {
+                   /* has sysmem allocated, e.g. string_pin */
+                   mem_sys_free(PObj_bufstart(obj));
+                   PObj_bufstart(obj) = NULL;
+                   PObj_buflen(obj) = 0;
+               }
+               else {
 #ifdef GC_IS_MALLOC
-                       /* free allocated space at (int*)bufstart - 1,
-                        * but not if it is used COW or external
-                        */
-                       if (PObj_bufstart(obj) &&
-                               !PObj_is_external_or_free_TESTALL(obj)) {
-                           if (PObj_COW_TEST(obj)) {
-                               INTVAL *refcount = ((INTVAL 
*)PObj_bufstart(obj) - 1);
-
-                               if (!--(*refcount))
-                                   free(refcount); /* the actual bufstart */
-                           }
-                           else
-                               free((INTVAL*)PObj_bufstart(obj) - 1);
+                   /* free allocated space at (int*)bufstart - 1,
+                    * but not if it is used COW or external
+                    */
+                   if (PObj_bufstart(obj) &&
+                           !PObj_is_external_or_free_TESTALL(obj)) {
+                       if (PObj_COW_TEST(obj)) {
+                           INTVAL *refcount = ((INTVAL *)PObj_bufstart(obj) - 
1);
+
+                           if (!--(*refcount))
+                               free(refcount); /* the actual bufstart */
                        }
+                       else
+                           free((INTVAL*)PObj_bufstart(obj) - 1);
+                   }
 #else
-                       /*
-                        * XXX Jarkko did report that on irix pool->mem_pool
-                        *     was NULL, which really shouldn't happen
-                        */
-                       if (pool->mem_pool) {
-                           if (!PObj_COW_TEST(obj)) {
-                               ((struct Memory_Pool *)
-                                pool->mem_pool)->guaranteed_reclaimable +=
-                                   PObj_buflen(obj);
-                           }
+                   /*
+                    * XXX Jarkko did report that on irix pool->mem_pool
+                    *     was NULL, which really shouldn't happen
+                    */
+                   if (pool->mem_pool) {
+                       if (!PObj_COW_TEST(obj)) {
                            ((struct Memory_Pool *)
-                            pool->mem_pool)->possibly_reclaimable +=
+                            pool->mem_pool)->guaranteed_reclaimable +=
                                PObj_buflen(obj);
                        }
-#endif
-                       PObj_buflen(obj) = 0;
+                       ((struct Memory_Pool *)
+                        pool->mem_pool)->possibly_reclaimable +=
+                           PObj_buflen(obj);
                    }
-                   PObj_exists_CLEAR(obj);
+#endif
+                   PObj_buflen(obj) = 0;
                }
+               PObj_exists_CLEAR(obj);
            }
        }
     }
@@ -341,42 +331,40 @@ gc_gmc_clear_live(Interp *interpreter, s
        int flags, void *arg)
 {
     PObj *obj;
-    Gc_gmc_area_store *store;
-    Gc_gmc_header_area **area;
+    struct Small_Object_Arena *arena;
 
-    for (store = pool->areas->first; store; store = store->next)
+    for (arena = pool->last_Arena; arena; arena = arena->prev)
     {
-       for (area = &store->store[0]; (UINTVAL)area < (UINTVAL)store->ptr; 
area++)
+       for (obj = (PObj*)arena->start_objects; (UINTVAL)obj < 
+               (UINTVAL)((char*)arena->start_objects + pool->object_size * 
arena->total_objects);
+               obj = (PObj*)((char*)obj + pool->object_size))
        {
-           for (obj = (PObj*)(*area)->fst; (UINTVAL)obj < 
(UINTVAL)(*area)->lst;
-                   obj = (PObj*)((char*)obj + pool->object_size))
-           {
-               if (PObj_exists_TEST(obj))
-                   PObj_live_CLEAR(obj);
-           }
+           if (PObj_exists_TEST(obj))
+               PObj_live_CLEAR(obj);
        }
     }
     return 0;
 }
 
-static void gc_gmc_run(Interp *interpreter, int flags)
+static 
+void gc_gmc_run(Interp *interpreter, int flags)
 {
     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_ALL, 0, gc_gmc_clear_live);
        Parrot_forall_header_pools(interpreter, POOL_PMC, 0, sweep_pmc);
-       Parrot_forall_header_pools(interpreter, POOL_BUFFER, 0, sweep_buf);
+       /*Parrot_forall_header_pools(interpreter, POOL_BUFFER, 0, sweep_buf);*/
 
        /* Then the pmc_bodies. */
        gc_gmc_pool_deinit(interpreter, arena_base->pmc_pool);
-       
+
 #ifdef GMC_DEBUG
        fprintf (stderr, "GMC: Trying to run dod_run for final sweeping\n");
 #endif /* GMC_DEBUG */
@@ -393,13 +381,13 @@ static void gc_gmc_run(Interp *interpret
 
 void Parrot_gc_gmc_init(Interp *interpreter)
 {
-  struct Arenas *arena_base;
+    struct Arenas *arena_base;
 
-  arena_base = interpreter->arena_base;
+    arena_base = interpreter->arena_base;
 
-  arena_base->do_dod_run = gc_gmc_run;
-  arena_base->de_init_gc_system = gc_gmc_deinit;
-  arena_base->init_pool = gc_gmc_pool_init;
+    arena_base->do_dod_run = gc_gmc_run;
+    arena_base->de_init_gc_system = gc_gmc_deinit;
+    arena_base->init_pool = gc_gmc_pool_init;
 }
 
 
@@ -407,90 +395,134 @@ void Parrot_gc_gmc_init(Interp *interpre
 /******************************* REAL THINGS ********************************/
 
 
-static void 
+/* Allocates a new Small_Object_Arena and links it to the current pool. */
+    static void 
 gc_gmc_alloc_objects(Interp *interpreter, struct Small_Object_Pool *pool)
 {
+    struct Small_Object_Arena *new_arena;
+    char *ptr;
+    void *lim;
+    new_arena = mem_sys_allocate(sizeof(struct Small_Object_Arena));
+
+    new_arena->start_objects = mem_sys_allocate_zeroed(pool->objects_per_alloc 
* pool->object_size);
+    new_arena->total_objects = pool->objects_per_alloc;
+    new_arena->used = 0;
+    new_arena->start_looking = new_arena->start_objects;
+    pool->num_free_objects += pool->objects_per_alloc;
+    pool->total_objects += pool->objects_per_alloc;
+    new_arena->next = NULL;
+    new_arena->prev = pool->last_Arena;
+    lim = (void*)((char*)new_arena->start_objects + pool->objects_per_alloc * 
pool->object_size);
+
+    if (pool->last_Arena)
+       pool->last_Arena->next = new_arena;
+    pool->last_Arena = new_arena;
+
+    /* Mark all of its initial content to be inexistant. */
+    for (ptr = new_arena->start_objects; (UINTVAL)ptr < (UINTVAL)lim; ptr += 
pool->object_size)
+       PObj_exists_CLEAR((PObj*)ptr);
+
+    /* Allocate more next time. */
+    pool->objects_per_alloc = (UINTVAL) pool->objects_per_alloc * 
UNITS_PER_ALLOC_GROWTH_FACTOR;
+    if (pool->object_size * pool->objects_per_alloc > POOL_MAX_BYTES)
+       pool->objects_per_alloc = POOL_MAX_BYTES / pool->object_size;
+
+    /* Tell alloc to begin looking in this arena */
+    pool->free_list = new_arena;
+
+#ifdef GMC_DEBUG
+    fprintf(stderr, "Allocated new objects at arena %p, %p\n", new_arena, 
new_arena->start_objects);
+#endif
 }
 
-static void *
+    static void *
 gc_gmc_get_free_object_of_size(Interp *interpreter,
        struct Small_Object_Pool *pool, size_t size, INTVAL aggreg)
 {
-  void *pmc_body;
-  void *pmc;
-  void *ptr;
-  UINTVAL i;
-  Gc_gmc *gc = pool->gc;
-  Gc_gmc_gen *gen, *gen_ref;
-
-  /* Allocate the pmc_body */
-  gen = (aggreg) ? gc->yng_lst : gc->old_lst;
-
-  /* Should we use the next generation ? */
-  if (size >= gen->remaining)
-  {
-      if (aggreg)
-         gc->yng_lst = gen->next;
-      else
-         gc->old_lst = gen->next;
-      gen = gen->next;
-  }
-
-  /* Do we need more generations ? */
-  if (!gen)
-    gc_gmc_more_pmc_bodies (interpreter, pool);
-
-  gen = (aggreg) ? gc->yng_lst : gc->old_lst;
-
-  /* Should we use the next generation ? */
-  if (size >= gen->remaining)
-  {
-      if (aggreg)
-         gc->yng_lst = gen->next;
-      else
-         gc->old_lst = gen->next;
-      gen = gen->next;
-  }
-
-  pmc_body = gen->fst_free;
-  gen->fst_free = (void*)((char*)gen->fst_free + size);
-  gen->remaining -= size;
-  gen->alloc_obj++;
-  memset(pmc_body, 0, size);
-#ifdef GMC_DEBUG
-  fprintf (stderr,"Allocated size %d in gen %p, first: %p, remaining %d, 
next_gen: %p, fst_free: %p, lim: %p\n", size, gen, gen->first, gen->remaining, 
gen->next, gen->fst_free, (char*)gen->fst_free + gen->remaining);
-#endif
+    void *pmc_body;
+    void *pmc;
+    void *ptr;
+    UINTVAL i;
+    Gc_gmc *gc = pool->gc;
+    Gc_gmc_gen *gen, *gen_ref;
+    struct Small_Object_Arena *arena;
 
-#ifdef GMC_DEBUG
-  fprintf (stderr, "Allocating %s PMC of size %d\n", (aggreg) ? "aggregate" : 
"non-aggregate", size);
-#endif
+    /* Allocate the pmc_body */
+    gen = (aggreg) ? gc->yng_lst : gc->old_lst;
 
-  /* Allocate the PMC* */
+    /* Should we use the next generation ? */
+    if (size >= gen->remaining)
+    {
+       if (aggreg)
+           gc->yng_lst = gen->next;
+       else
+           gc->old_lst = gen->next;
+       gen = gen->next;
+    }
 
-  /* if we don't have any objects */
-  if ((UINTVAL)pool->free_list >= (UINTVAL)pool->limit)
-      (*pool->more_objects) (interpreter, pool);
-  
-  pmc = (PMC*)pool->free_list;
-  PObj_exists_SET((PMC*)pmc);
-  pool->free_list = (void*)((char*)pmc + pool->object_size);
-  --pool->num_free_objects;
-  PMC_body((PMC*)pmc) = Gmc_PMC_hdr_get_BODY(pmc_body);
+    /* Do we need more generations ? */
+    if (!gen)
+       gc_gmc_more_pmc_bodies (interpreter, pool);
 
-  Gmc_PMC_hdr_get_PMC((Gc_gmc_hdr*)pmc_body) = pmc;
-  PObj_get_FLAGS((PObj*)pmc) = 0;
+    gen = (aggreg) ? gc->yng_lst : gc->old_lst;
 
+    /* Should we use the next generation ? */
+    if (size >= gen->remaining)
+    {
+       if (aggreg)
+           gc->yng_lst = gen->next;
+       else
+           gc->old_lst = gen->next;
+       gen = gen->next;
+    }
+
+    pmc_body = gen->fst_free;
+    gen->fst_free = (void*)((char*)gen->fst_free + size);
+    gen->remaining -= size;
+    gen->alloc_obj++;
+    memset(pmc_body, 0, size);
+#ifdef GMC_DEBUG
+    fprintf (stderr,"Allocated size %d in gen %p, first: %p, remaining %d, 
next_gen: %p, fst_free: %p, lim: %p\n", size, gen, gen->first, gen->remaining, 
gen->next, gen->fst_free, (char*)gen->fst_free + gen->remaining);
+#endif
+
+    /* Allocate the PMC* */
+
+    /* If we don't have any objects left, find more. */
+    if (!pool->num_free_objects)
+       (*pool->more_objects) (interpreter, pool);
+
+    /* Find an arena with a free object. */
+    for (arena = pool->free_list; arena->total_objects == arena->used;
+           arena = (arena->prev) ? arena->prev : pool->last_Arena);
+
+    /* Now find this object. */
+    for (pmc = arena->start_objects;
+           PObj_exists_TEST((PObj*)pmc);
+           pmc = ((UINTVAL)pmc < (UINTVAL)((char*)arena->start_objects + 
+                   pool->object_size * (arena->total_objects - 1))) ?
+           (PMC*)((char*)pmc + pool->object_size) :
+           arena->start_objects);
+
+    pool->free_list = arena;
+    arena->start_looking = pmc;
+    ++arena->used;
+    --pool->num_free_objects;
+    PMC_body((PMC*)pmc) = Gmc_PMC_hdr_get_BODY(pmc_body);
+
+    Gmc_PMC_hdr_get_PMC((Gc_gmc_hdr*)pmc_body) = pmc;
+    PObj_get_FLAGS((PObj*)pmc) = 0;
+    PObj_exists_SET((PObj*)pmc);
 
-  return pmc;
+    return pmc;
 }
 
 
 
 /* Here we allocate a default PMC, as it is non-typed. */
 /* This function should not be called anywhere if possible. */
-void *
+    void *
 gc_gmc_get_free_object(Interp *interpreter,
-    struct Small_Object_Pool *pool)
+       struct Small_Object_Pool *pool)
 {
     size_t size = sizeof(Gc_gmc_hdr) + sizeof(pobj_body);
     PMC *pmc = gc_gmc_get_free_object_of_size(interpreter, pool, size, 0);
@@ -499,15 +531,15 @@ gc_gmc_get_free_object(Interp *interpret
 }
 
 
-static void
+    static void
 gc_gmc_add_free_object(Interp *interpreter,
        struct Small_Object_Pool *pool, void *to_add)
 {
-   Gmc_PMC_flag_SET(marking,(PMC*)to_add); 
+    Gmc_PMC_flag_SET(marking,(PMC*)to_add); 
 }
 
 
-static void *
+    static void *
 gc_gmc_get_free_typed_object(Interp *interpreter,
        struct Small_Object_Pool *pool, INTVAL base_type)
 {
@@ -520,7 +552,7 @@ gc_gmc_get_free_typed_object(Interp *int
     return pmc;
 }
 
-static void *
+    static void *
 gc_gmc_get_free_sized_object(Interp *interpreter,
        struct Small_Object_Pool *pool, size_t size)
 {
@@ -531,9 +563,9 @@ gc_gmc_get_free_sized_object(Interp *int
        Gmc_PMC_flag_SET(is_pmc, pmc);
     return pmc;
 }
-    
 
-static void
+
+    static void
 gc_gmc_copy_gen (Gc_gmc_gen *from, Gc_gmc_gen *dest)
 {
     INTVAL offset = (char*)from->fst_free - (char*)from->first;
@@ -556,7 +588,7 @@ gc_gmc_copy_gen (Gc_gmc_gen *from, Gc_gm
     }
 }
 
-static void
+    static void
 gc_gmc_gen_free(Gc_gmc_gen *gen)
 {
     mem_sys_free(gen->first);
@@ -566,7 +598,7 @@ gc_gmc_gen_free(Gc_gmc_gen *gen)
 
 /* Allocates twice as much generations as before, copies everything */
 /* TODO: double only the half that needs it. */
-static void
+    static void
 gc_gmc_more_pmc_bodies (Interp *interpreter,
        struct Small_Object_Pool *pool)
 {
@@ -586,7 +618,7 @@ gc_gmc_more_pmc_bodies (Interp *interpre
     dummy_gc->old_fst = NULL;
     dummy_gc->old_lst = NULL;
     dummy_gc->nb_gen = nb_gen;
-    
+
     for (i = 0; i < nb_gen; i++)
     {
        gen = gc_gmc_gen_init (interpreter);
@@ -625,7 +657,7 @@ gc_gmc_more_pmc_bodies (Interp *interpre
     gc->nb_gen = nb_gen;
 
     mem_sys_free(dummy_gc);
-    
+
 #ifdef GMC_DEBUG
     fprintf(stderr, "Done with allocation\n");
 #endif
@@ -634,42 +666,12 @@ gc_gmc_more_pmc_bodies (Interp *interpre
 
 /* Quick and dirty for now, no GC run at all. */
 /* XXX: structures must change, because no free is possible with what's here */
-static void
+    static void
 gc_gmc_more_objects(Interp *interpreter,
        struct Small_Object_Pool *pool)
 {
-#define NUM_NEW_OBJ 512
-    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 flags correctly. */
-    for (i = 0, obj = (char*)fst; i < NUM_NEW_OBJ; i++, obj += 
pool->object_size)
-       PObj_exists_CLEAR((PObj*)obj);
-    pool->free_list = fst;
-    pool->limit = (void*)((char*)fst + NUM_NEW_OBJ * pool->object_size);
-    pool->num_free_objects += NUM_NEW_OBJ;
-    pool->total_objects += NUM_NEW_OBJ;
-#ifdef GMC_DEBUG
-    fprintf(stderr, "Allocating %d more objects of size %d beginning at %p\n", 
NUM_NEW_OBJ, pool->object_size, fst);
-#endif
+    /* For now only alloc more objects. There will be a GC run in the future. 
*/
+    (*pool->alloc_objects) (interpreter, pool);
 }
 
 

Modified: branches/gmc/src/headers.c
==============================================================================
--- branches/gmc/src/headers.c  (original)
+++ branches/gmc/src/headers.c  Sat Aug 20 19:09:10 2005
@@ -55,7 +55,8 @@ get_free_buffer(Interp *interpreter,
 {
 #if PARROT_GC_GMC
     PObj *buffer = pool->get_free_sized_object(interpreter, pool, 
sizeof(pobj_body));
-    PObj_get_FLAGS(buffer) = 0;
+    /*PObj_get_FLAGS(buffer) = 0;*/
+    /*PObj_exists_SET(buffer);*/
 #else
     PObj *buffer = pool->get_free_object(interpreter, pool);
 #endif
@@ -317,6 +318,7 @@ new_pmc_alloc_header(Interp *interpreter
 #if ! PMC_DATA_IN_EXT
     PMC_data(pmc) = NULL;
 #endif
+    PObj_exists_SET(pmc);
     return pmc;
 }
 

Reply via email to