[svn:parrot] r41011 - in branches/gc-refactor: include/parrot src src/gc src/pmc

dukeleto at svn.parrot.org dukeleto at svn.parrot.org
Sat Sep 5 18:39:03 UTC 2009


Author: dukeleto
Date: Sat Sep  5 18:39:01 2009
New Revision: 41011
URL: https://trac.parrot.org/parrot/changeset/41011

Log:
[TT #980] Apply patches attached to ticket

Added:
   branches/gc-refactor/src/gc/generational_ms.h
Modified:
   branches/gc-refactor/include/parrot/gc_api.h
   branches/gc-refactor/include/parrot/interpreter.h
   branches/gc-refactor/include/parrot/oo.h
   branches/gc-refactor/include/parrot/settings.h
   branches/gc-refactor/src/gc/alloc_resources.c
   branches/gc-refactor/src/gc/api.c
   branches/gc-refactor/src/gc/gc_ms.c
   branches/gc-refactor/src/gc/gc_private.h
   branches/gc-refactor/src/gc/mark_sweep.c
   branches/gc-refactor/src/gc/system.c
   branches/gc-refactor/src/hash.c
   branches/gc-refactor/src/list.c
   branches/gc-refactor/src/pmc/default.pmc
   branches/gc-refactor/src/pmc/fixedpmcarray.pmc
   branches/gc-refactor/src/pmc/fixedstringarray.pmc
   branches/gc-refactor/src/pmc/resizablepmcarray.pmc
   branches/gc-refactor/src/pmc/resizablestringarray.pmc
   branches/gc-refactor/src/pmc_freeze.c

Modified: branches/gc-refactor/include/parrot/gc_api.h
==============================================================================
--- branches/gc-refactor/include/parrot/gc_api.h	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/include/parrot/gc_api.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -89,20 +89,6 @@
 typedef void (*alloc_objects_fn_type)(PARROT_INTERP, struct Small_Object_Pool *);
 typedef void (*gc_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *, PObj *);
 
-/*
- * macros used in arena scan code to convert from object pointers
- * to arena pointers ...
- */
-
-#if PARROT_GC_GMS
-#  define GC_HEADER_SIZE (sizeof (Gc_gms_hdr))
-#  define PObj_to_ARENA(o) PObj_to_GMSH(o)
-#  define ARENA_to_PObj(p) GMSH_to_PObj((Gc_gms_hdr*)(p))
-#else
-#  define GC_HEADER_SIZE 0
-#  define PObj_to_ARENA(o) (o)
-#  define ARENA_to_PObj(p) (p)
-#endif
 
 /* &gen_from_enum(interpinfo.pasm) prefix(INTERPINFO_) */
 
@@ -357,6 +343,17 @@
 int Parrot_gc_total_sized_buffers(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+void  Parrot_gc_write_barrier(PARROT_INTERP, PMC *agg, PMC *old, PMC *new)
+        __attribute__nonnull__(1);
+
+void  Parrot_gc_write_barrier_key(PARROT_INTERP,
+    PMC *agg,
+    PMC *old,
+    PObj *old_key,
+    PMC *_new,
+    PObj *new_key)
+        __attribute__nonnull__(1);
+
 #define ASSERT_ARGS_Parrot_block_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_block_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -489,46 +486,15 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_gc_total_sized_buffers __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_write_barrier __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_write_barrier_key __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/gc/api.c */
 
 void Parrot_gc_inf_init(PARROT_INTERP);
 
-/* write barrier */
-#if PARROT_GC_MS
-#  define GC_WRITE_BARRIER(interp, agg, old, _new) do { } while (0)
-#  define GC_WRITE_BARRIER_KEY(interp, agg, old, old_key, _new, new_key) do { } while (0)
-#endif
-
-#if PARROT_GC_GMS
-#  define GC_WRITE_BARRIER(interp, agg, old, _new) do { \
-    UINTVAL gen_agg, gen_new; \
-    if (!(_new) || PMC_IS_NULL(_new)) \
-        break; \
-    gen_agg = PObj_to_GMSH(agg)->gen->gen_no; \
-    gen_new = PObj_to_GMSH(_new)->gen->gen_no; \
-    if (gen_agg < gen_new) \
-        parrot_gc_gms_wb((interp), (agg), (old), (_new)); \
-} while (0)
-
-#  define GC_WRITE_BARRIER_KEY(interp, agg, old, old_key, _new, new_key) do { \
-    UINTVAL gen_agg, gen_new, gen_key; \
-    if (!(_new) || PMC_IS_NULL(_new)) \
-        break; \
-    gen_agg = PObj_to_GMSH(agg)->gen->gen_no; \
-    gen_new = PObj_to_GMSH(_new)->gen->gen_no; \
-    gen_key = PObj_to_GMSH(new_key)->gen->gen_no; \
-    if (gen_agg < gen_new || gen_agg < gen_key) \
-        parrot_gc_gms_wb_key((interp), (agg), (old), (old_key), (_new), (new_key)); \
-} while (0)
-
-#endif
-
-#if PARROT_GC_INF
-#  define GC_WRITE_BARRIER(interp, agg, old, _new) do { } while (0)
-#  define GC_WRITE_BARRIER_KEY(interp, agg, old, old_key, _new, new_key) do { } while (0)
-#endif
-
 #endif /* PARROT_GC_API_H_GUARD */
 
 /*

Modified: branches/gc-refactor/include/parrot/interpreter.h
==============================================================================
--- branches/gc-refactor/include/parrot/interpreter.h	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/include/parrot/interpreter.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -212,7 +212,6 @@
     int n_free_slots;               /* amount of allocated */
 } context_mem;
 
-
 struct _handler_node_t; /* forward def - exit.h */
 
 /* The actual interpreter structure */
@@ -222,6 +221,11 @@
     struct Arenas *arena_base;                /* Pointer to this interpreter's
                                                * arena */
 
+    struct GC_Subsystem *gc_sys;              /*functions and data specific 
+                                                  to current GC subsystem*/
+
+    PMC *gc_registry;                         /* root set of registered PMCs */
+
     PMC     *class_hash;                      /* Hash of classes */
     VTABLE **vtables;                         /* array of vtable ptrs */
     int      n_vtable_max;                    /* highest used type */
@@ -293,7 +297,6 @@
     /* 8:   PMC *PBC_Libs                Hash of load_bytecode cde */
     /* 9:   PMC *Executable              String PMC with name from argv[0]. */
 
-    PMC *gc_registry;                         /* root set of registered PMCs */
 
     PMC *HLL_info;                            /* HLL names and types */
     PMC *HLL_namespace;                       /* cache of HLL toplevel ns */
@@ -324,7 +327,6 @@
 
     UINTVAL recursion_limit;                  /* Sub call resursion limit */
 
-    UINTVAL gc_generation;                    /* GC generation number */
 
     opcode_t *current_args;                   /* ptr into code w/ set_args op */
     opcode_t *current_params;                 /* ... w/ get_params op */

Modified: branches/gc-refactor/include/parrot/oo.h
==============================================================================
--- branches/gc-refactor/include/parrot/oo.h	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/include/parrot/oo.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -32,7 +32,7 @@
 #define get_attrib_num(x, y)    ((PMC **)(x))[(y)]
 #define set_attrib_num(o, x, y, z) \
     do { \
-        GC_WRITE_BARRIER(interp, (o), ((PMC **)(x))[y], (z)); \
+        Parrot_gc_write_barrier(interp, (o), ((PMC **)(x))[y], (z)); \
         ((PMC **)(x))[(y)] = (z); \
     } while (0)
 

Modified: branches/gc-refactor/include/parrot/settings.h
==============================================================================
--- branches/gc-refactor/include/parrot/settings.h	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/include/parrot/settings.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -44,7 +44,7 @@
  * Please note that only 0 and 3 currently work (and INF doesn't really
  * "work").
  */
-
+#define PARROT_GC_DEFAULT_TYPE MS
 #define PARROT_GC_SUBSYSTEM 0
 
 #if PARROT_GC_SUBSYSTEM == 0

Modified: branches/gc-refactor/src/gc/alloc_resources.c
==============================================================================
--- branches/gc-refactor/src/gc/alloc_resources.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/alloc_resources.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -417,7 +417,18 @@
         for (cur_buffer_arena = header_pool->last_Arena;
                 cur_buffer_arena;
                 cur_buffer_arena = cur_buffer_arena->prev) {
-            Buffer *b = (Buffer *)ARENA_to_PObj(cur_buffer_arena->start_objects);
+            /*JT: Something like this is what we really want ... 
+             *JT: if only I knew how to program C ...
+            if (interp->gc_sys->Arena_to_PObj){
+                Buffer *b = 
+                    (Buffer *) 
+                    interp->gc_sys->Arena_to_PObj(cur_buffer_arena->start_objects);
+            }
+            */
+
+            /*JT: but for now, we'll just cheat, since it's only GMS 
+                  that needs that stuff anyway*/
+            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
             UINTVAL i;
             const size_t objects_end = cur_buffer_arena->used;
 

Modified: branches/gc-refactor/src/gc/api.c
==============================================================================
--- branches/gc-refactor/src/gc/api.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/api.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -198,47 +198,52 @@
     /* TODO: Have each core register a ->pobject_lives function pointer in the
        Arenas struct, and call that pointer directly instead of having a messy
        set of #if preparser conditions. */
-#if PARROT_GC_GMS
-    do {
-        if (!PObj_live_TEST(obj) && \
-                PObj_to_GMSH(obj)->gen->gen_no >= interp->gc_generation) \
-            parrot_gc_gms_Parrot_gc_mark_PObj_alive(interp, obj); \
-    } while (0);
-#else /* not PARROT_GC_GMS */
-
-    /* if object is live or on free list return */
-    if (PObj_is_live_or_free_TESTALL(obj))
-        return;
 
+    if (interp->gc_sys->sys_type == GMS) {
+        /*
+        do {
+            if (!PObj_live_TEST(obj) &&  
+                 PObj_to_GMSH(obj)->gen->gen_no >=
+                 interp->gc_sys->gc_sys_data.gms_data->gc_generation) 
+                parrot_gc_gms_Parrot_gc_mark_PObj_alive(interp, obj);
+        } while (0);
+        break;
+        */
+    }
+    else {
+        /* if object is live or on free list return */
+        if (PObj_is_live_or_free_TESTALL(obj))
+            return;
+        
 #  if ! DISABLE_GC_DEBUG
 #    if GC_VERBOSE
-    if (CONSERVATIVE_POINTER_CHASING)
-        fprintf(stderr, "GC Warning! Unanchored %s %p found in system areas \n",
-                PObj_is_PMC_TEST(obj) ? "PMC" : "Buffer", obj);
-
+        if (CONSERVATIVE_POINTER_CHASING)
+            fprintf(stderr, "GC Warning! Unanchored %s %p found in system areas \n",
+                    PObj_is_PMC_TEST(obj) ? "PMC" : "Buffer", obj);
+        
 #    endif
 #  endif
-    /* mark it live */
-    PObj_live_SET(obj);
-
-    /* if object is a PMC and contains buffers or PMCs, then attach the PMC
-     * to the chained mark list. */
-    if (PObj_is_PMC_TEST(obj)) {
-        PMC * const p = (PMC *)obj;
-
-        if (PObj_is_special_PMC_TEST(obj))
-            mark_special(interp, p);
-
-        else if (PMC_metadata(p))
-            Parrot_gc_mark_PObj_alive(interp, (PObj*)PMC_metadata(p));
-    }
+        /* mark it live */
+        PObj_live_SET(obj);
+        
+        /* if object is a PMC and contains buffers or PMCs, then attach the PMC
+         * to the chained mark list. */
+        if (PObj_is_PMC_TEST(obj)) {
+            PMC * const p = (PMC *)obj;
+            
+            if (PObj_is_special_PMC_TEST(obj))
+                mark_special(interp, p);
+            
+            else if (PMC_metadata(p))
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)PMC_metadata(p));
+        }
 #  if GC_VERBOSE
-    /* buffer GC_DEBUG stuff */
-    if (GC_DEBUG(interp) && PObj_report_TEST(obj))
-        fprintf(stderr, "GC: buffer %p pointing to %p marked live\n",
-                obj, Buffer_bufstart((Buffer *)obj));
+        /* buffer GC_DEBUG stuff */
+        if (GC_DEBUG(interp) && PObj_report_TEST(obj))
+            fprintf(stderr, "GC: buffer %p pointing to %p marked live\n",
+                    obj, Buffer_bufstart((Buffer *)obj));
 #  endif
-#endif  /* PARROT_GC_GMS */
+    }
 }
 
 /*
@@ -268,18 +273,38 @@
 
     interp->lo_var_ptr = stacktop;
 
-#if PARROT_GC_MS
-    Parrot_gc_ms_init(interp);
-#endif
-#if PARROT_GC_IMS
-    Parrot_gc_ims_init(interp);
-#endif
-#if PARROT_GC_GMS
-    Parrot_gc_gms_init(interp);
-#endif
-#if PARROT_GC_INF
-    Parrot_gc_inf_init(interp);
-#endif
+    interp->gc_sys = mem_allocate_zeroed_typed(GC_Subsystem);
+
+    /*JT: This is set at compile time ... what we need to do next is 
+     *    add a command-line switch --gc that will enable us to choose
+     *    a different one ... if --gc is set, we use it, otherwise use
+     *    the default  */  
+    interp->gc_sys->sys_type = PARROT_GC_DEFAULT_TYPE;
+
+    /* Set the sys_type here if we got a --gc command line switch
+     * ... we need some sort of set_gc_sys_type_from_command_line_switch() 
+     * function ...
+     */
+
+    /*Call appropriate initialization function for GC subsystem*/
+    switch(interp->gc_sys->sys_type) {
+      case MS:
+        Parrot_gc_ms_init(interp);
+        break;
+      /* These currently don't work
+      case IMS:
+        Parrot_gc_ims_init(interp);
+        break;
+      case GMS:
+        Parrot_gc_gms_init(interp);
+        break;
+      case INF:
+        Parrot_gc_inf_init(interp);
+        break;  
+       */
+      default:
+        break;  /*What SHOULD we be doing if we get here?*/
+    }
 
     initialize_memory_pools(interp);
     initialize_header_pools(interp);
@@ -525,9 +550,9 @@
     Buffer_bufstart(buffer) = NULL;
     Buffer_buflen(buffer)   = 0;
 
-    if (pool->object_size - GC_HEADER_SIZE > sizeof (Buffer))
+    if (pool->object_size - interp->gc_sys->header_size > sizeof (Buffer))
         memset(buffer + 1, 0,
-                pool->object_size - sizeof (Buffer) - GC_HEADER_SIZE);
+                pool->object_size - sizeof (Buffer) - interp->gc_sys->header_size);
 
     return buffer;
 }
@@ -954,7 +979,7 @@
     const UINTVAL       object_size = pool->object_size;
 
     for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {
-        PMC   *p = (PMC *)((char*)cur_arena->start_objects + GC_HEADER_SIZE);
+        PMC   *p = (PMC *)((char*)cur_arena->start_objects + dest_interp->gc_sys->header_size);
         size_t i;
 
         for (i = 0; i < cur_arena->used; i++) {
@@ -1185,8 +1210,8 @@
 Parrot_gc_ptr_is_pmc(PARROT_INTERP, ARGIN(void *ptr))
 {
     ASSERT_ARGS(Parrot_gc_ptr_is_pmc)
-    return contained_in_pool(interp->arena_base->pmc_pool, ptr) ||
-           contained_in_pool(interp->arena_base->constant_pmc_pool, ptr);
+        return contained_in_pool(interp, interp->arena_base->pmc_pool, ptr) ||
+        contained_in_pool(interp, interp->arena_base->constant_pmc_pool, ptr);
 }
 
 /*
@@ -1208,7 +1233,9 @@
     Small_Object_Arena *arena;
     Small_Object_Pool *pool;
 
-    pmc = (PMC*)PObj_to_ARENA(pmc);
+    if (interp->gc_sys->PObj_to_Arena){
+        pmc = (PMC*) interp->gc_sys->PObj_to_Arena(pmc);
+    }
     pool = interp->arena_base->pmc_pool;
     for (arena = pool->last_Arena; arena; arena = arena->prev) {
         const ptrdiff_t ptr_diff = (ptrdiff_t)pmc - (ptrdiff_t)arena->start_objects;
@@ -1585,6 +1612,37 @@
 }
 
 /*
+=item C<void Parrot_gc_write_barrier(PARROT_INTERP, PMC *agg, PMC *old, PMC
+*new)>
+
+Wrapper around write_barrier hook for currently active GC system ...
+
+=cut
+
+*/
+
+void 
+Parrot_gc_write_barrier(PARROT_INTERP, PMC *agg, PMC *old, PMC *new){
+    interp->gc_sys->write_barrier(interp, agg, old, new);
+}
+
+/*
+=item C<void Parrot_gc_write_barrier_key(PARROT_INTERP, PMC *agg, PMC *old, PObj
+*old_key, PMC *_new, PObj *new_key)>
+
+Wrapper around write_barrier_key hook for currently active GC system ...
+
+=cut
+
+*/
+
+void 
+Parrot_gc_write_barrier_key(PARROT_INTERP, PMC *agg, PMC *old, PObj *old_key, PMC *_new, PObj *new_key){
+    interp->gc_sys->write_barrier_key(interp, agg, old, old_key, _new, new_key);
+}
+
+
+/*
 
 =item C<void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, PMC *pmc, size_t
 size)>

Modified: branches/gc-refactor/src/gc/gc_ms.c
==============================================================================
--- branches/gc-refactor/src/gc/gc_ms.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/gc_ms.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -128,6 +128,7 @@
     arena_base->do_gc_mark         = gc_ms_mark_and_sweep;
     arena_base->finalize_gc_system = NULL;
     arena_base->init_pool          = gc_ms_pool_init;
+
 }
 
 /*

Modified: branches/gc-refactor/src/gc/gc_private.h
==============================================================================
--- branches/gc-refactor/src/gc/gc_private.h	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/gc_private.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -17,6 +17,8 @@
 #define PARROT_GC_PRIVATE_H_GUARD
 
 #include "parrot/settings.h"
+#include "generational_ms.h"
+
 
 #if ! DISABLE_GC_DEBUG
 /* Set when walking the system stack. Defined in src/gc/system.c */
@@ -82,6 +84,36 @@
     struct GC_MS_PObj_Wrapper * next_ptr;
 } GC_MS_PObj_Wrapper;
 
+
+typedef enum _gc_sys_type_enum {
+    MS,  /*mark and sweep*/
+    IMS, /*incremental mark and sweep*/
+    GMS, /*generational mark and sweep*/
+    INF /*infinite memory core*/
+} gc_sys_type_enum;
+
+typedef struct GC_Subsystem {
+    gc_sys_type_enum sys_type;  /* Which GC subsystem are we using? */
+
+    union {                     /* Holds system-specific data structures*/
+        struct gc_gms_sys_data gms_data;
+    } gc_sys_data;
+
+    /*Function hooks that GC systems can choose if they want
+     *These will be called from the GC API function  */
+    void (*write_barrier)(PARROT_INTERP, PMC *, PMC *, PMC *);
+    void (*write_barrier_key)(PARROT_INTERP, PMC *, PMC *, PObj *, PMC *, PObj *);
+
+    /* functions used in arena scan code to convert from object pointers
+     * to arena pointers ... GMS only I think ...*/
+
+    void * (*PObj_to_Arena)(const void *);
+    PObj * (*Arena_to_PObj)(void *);
+
+    /*JT: this is only used by GMS afaict, but we'll keep it here for now ...*/
+    size_t header_size;
+} GC_Subsystem;
+
 typedef struct Small_Object_Arena {
     size_t                     used;
     size_t                     total_objects;
@@ -99,61 +131,6 @@
     struct PMC_Attribute_Arena * prev;
 } PMC_Attribute_Arena;
 
-#if PARROT_GC_GMS
-/*
- * all objects have this header in front of the actual
- * object pointer. The prev/next pointers chain all existing
- * objects for one pool (sizeclass) together.
- *
- * XXX this could lead to unaligned FLOATVALs in the adjacent PMC
- *     if that's true either insert a dummy or reorder PMC members
- *     ??? How is that possible?
- */
-typedef struct _gc_gms_hdr {
-    struct _gc_gms_hdr *prev;
-    struct _gc_gms_hdr *next;
-    struct _gc_gms_gen *gen;
-    void *gc_dummy_align;       /* see above */
-} Gc_gms_hdr;
-
-#  define PObj_to_GMSH(o) (((Gc_gms_hdr*)(o))-1)
-#  define GMSH_to_PObj(p) ((PObj*) ((p)+1))
-
-/* the structure uses 2 ptrs itself */
-#  define GC_GMS_STORE_SIZE (64-2)
-
-typedef struct _gc_gms_hdr_store {
-    struct _gc_gms_hdr_store *next;
-    Gc_gms_hdr **ptr;                           /* insert location */
-    Gc_gms_hdr * (store[GC_GMS_STORE_SIZE]);    /* array of hdr pointers */
-} Gc_gms_hdr_store;
-
-typedef struct _gc_gms_hdr_list {
-    Gc_gms_hdr_store *first;
-    Gc_gms_hdr_store *last;
-} Gc_gms_hdr_list;
-
-
-/*
- * all objects belong to one generation
- */
-typedef struct _gc_gms_gen {
-    UINTVAL gen_no;                     /* generation number */
-    UINTVAL timely_destruct_obj_sofar;  /* sum up to this generation */
-    UINTVAL black_color;                /* live color of this generation */
-    struct _gc_gms_hdr *first;          /* first header in this generation */
-    struct _gc_gms_hdr *last;           /* last header in this generation */
-    struct _gc_gms_hdr *fin;            /* need destruction/finalization */
-    struct Small_Object_Pool *pool;     /* where this generation belongs to */
-    Gc_gms_hdr_list igp;                /* IGPs for this generation */
-    UINTVAL n_possibly_dead;            /* overwritten count */
-    UINTVAL n_objects;                  /* live objects count */
-    struct _gc_gms_gen *prev;
-    struct _gc_gms_gen *next;
-} Gc_gms_gen;
-
-#endif /* PARROT_GC_GMS */
-
 typedef struct PMC_Attribute_Pool {
     size_t attr_size;
     size_t total_objects;
@@ -181,34 +158,34 @@
     int skip;
     size_t replenish_level;
     GC_MS_PObj_Wrapper * free_list;
-    /* adds a free object to the pool's free list  */
-    add_free_object_fn_type     add_free_object;
-    get_free_object_fn_type     get_free_object;
-    alloc_objects_fn_type       alloc_objects;
+
+    
+    add_free_object_fn_type     add_free_object; /* adds a free object to 
+                                                    the pool's free list  */
+    get_free_object_fn_type     get_free_object; /* gets and removes a free 
+                                                    object from the pool's 
+                                                    free list */
+    alloc_objects_fn_type       alloc_objects;  /* allocates more objects */
     alloc_objects_fn_type       more_objects;
     gc_object_fn_type           gc_object;
-    /* gets and removes a free object from the pool's free list */
-    /* allocates more objects */
+
+
+    
     struct Memory_Pool *mem_pool;
     size_t start_arena_memory;
     size_t end_arena_memory;
     PARROT_OBSERVER const char *name;
+
+    /*Contains GC system-specific data structures*/
+    union {
+        struct gc_gms_smallobjpool_data *gms; /*generational mark and sweep*/
+    } gc_sys_priv_data;
+
 #if GC_USE_LAZY_ALLOCATOR
     void *newfree;
     void *newlast;
 #endif
-#if PARROT_GC_GMS
-    struct _gc_gms_hdr marker;          /* limit of list */
-    struct _gc_gms_hdr *black;          /* alive */
-    struct _gc_gms_hdr *black_fin;      /* alive, needs destruction */
-    struct _gc_gms_hdr *gray;           /* to be scanned */
-    struct _gc_gms_hdr *white;          /* unprocessed */
-    struct _gc_gms_hdr *white_fin;      /* unprocesse, needs destruction */
-
-    struct _gc_gms_gen *first_gen;      /* linked list of generations */
-    struct _gc_gms_gen *last_gen;
 
-#endif
 } Small_Object_Pool;
 
 typedef struct Arenas {
@@ -368,11 +345,12 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_WARN_UNUSED_RESULT
-INTVAL contained_in_pool(
+INTVAL contained_in_pool(PARROT_INTERP,
     ARGIN(const Small_Object_Pool *pool),
     ARGIN(const void *ptr))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
@@ -461,7 +439,8 @@
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_contained_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool) \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool) \
     || PARROT_ASSERT_ARG(ptr)
 #define ASSERT_ARGS_get_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)

Added: branches/gc-refactor/src/gc/generational_ms.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gc-refactor/src/gc/generational_ms.h	Sat Sep  5 18:39:01 2009	(r41011)
@@ -0,0 +1,82 @@
+#ifndef PARROT_GC_GMS_H_GUARD
+#define PARROT_GC_GMS_H_GUARD
+
+/*
+ * all objects have this header in front of the actual
+ * object pointer. The prev/next pointers chain all existing
+ * objects for one pool (sizeclass) together.
+ *
+ * XXX this could lead to unaligned FLOATVALs in the adjacent PMC
+ *     if that's true either insert a dummy or reorder PMC members
+ *     ??? How is that possible?
+ */
+typedef struct _gc_gms_hdr {
+    struct _gc_gms_hdr *prev;
+    struct _gc_gms_hdr *next;
+    struct _gc_gms_gen *gen;
+    void *gc_dummy_align;       /* see above */
+} Gc_gms_hdr;
+
+#  define PObj_to_GMSH(o) (((Gc_gms_hdr*)(o))-1)
+#  define GMSH_to_PObj(p) ((PObj*) ((p)+1))
+
+/* the structure uses 2 ptrs itself */
+#  define GC_GMS_STORE_SIZE (64-2)
+
+typedef struct _gc_gms_hdr_store {
+    struct _gc_gms_hdr_store *next;
+    Gc_gms_hdr **ptr;                           /* insert location */
+    Gc_gms_hdr * (store[GC_GMS_STORE_SIZE]);    /* array of hdr pointers */
+} Gc_gms_hdr_store;
+
+typedef struct _gc_gms_hdr_list {
+    Gc_gms_hdr_store *first;
+    Gc_gms_hdr_store *last;
+} Gc_gms_hdr_list;
+
+
+/*
+ * all objects belong to one generation
+ */
+typedef struct _gc_gms_gen {
+    UINTVAL gen_no;                     /* generation number */
+    UINTVAL timely_destruct_obj_sofar;  /* sum up to this generation */
+    UINTVAL black_color;                /* live color of this generation */
+    struct _gc_gms_hdr *first;          /* first header in this generation */
+    struct _gc_gms_hdr *last;           /* last header in this generation */
+    struct _gc_gms_hdr *fin;            /* need destruction/finalization */
+    struct Small_Object_Pool *pool;     /* where this generation belongs to */
+    Gc_gms_hdr_list igp;                /* IGPs for this generation */
+    UINTVAL n_possibly_dead;            /* overwritten count */
+    UINTVAL n_objects;                  /* live objects count */
+    struct _gc_gms_gen *prev;
+    struct _gc_gms_gen *next;
+} Gc_gms_gen;
+
+/* System-specific data for the Small_Object_Pool struct's gc_sys_private_data field. */
+struct gc_gms_smallobjpool_data {
+    Gc_gms_hdr marker;          /* limit of list ... also the anchor of the "header chain"
+				   -- see gc_gms_chain_objects() */
+    Gc_gms_hdr *black;          /* alive */
+    Gc_gms_hdr *black_fin;      /* alive, needs destruction */
+    Gc_gms_hdr *gray;           /* to be scanned */
+    Gc_gms_hdr *white;          /* unprocessed */
+    Gc_gms_hdr *white_fin;      /* unprocesse, needs destruction */
+
+    Gc_gms_gen *first_gen;      /* linked list of generations */
+    Gc_gms_gen *last_gen;
+};
+
+
+/*For arenas->gc_private*/
+typedef struct Gc_gms_private {
+    UINTVAL current_gen_no;             /* the nursery generation number */
+} Gc_gms_private;
+
+
+/*For gc_sys_priv_data in interp*/
+struct gc_gms_sys_data {
+  UINTVAL gc_generation;        /* GC generation number */
+} gc_gms_sys_data;
+
+#endif /*PARROT_GC_GMS_H_GUARD*/

Modified: branches/gc-refactor/src/gc/mark_sweep.c
==============================================================================
--- branches/gc-refactor/src/gc/mark_sweep.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/mark_sweep.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -352,8 +352,8 @@
 
 /*
 
-=item C<INTVAL contained_in_pool(const Small_Object_Pool *pool, const void
-*ptr)>
+=item C<INTVAL contained_in_pool(PARROT_INTERP, const Small_Object_Pool *pool,
+const void *ptr)>
 
 Returns whether the given C<*ptr> points to a location in C<pool>.
 
@@ -363,13 +363,14 @@
 
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-contained_in_pool(ARGIN(const Small_Object_Pool *pool), ARGIN(const void *ptr))
+contained_in_pool(PARROT_INTERP, ARGIN(const Small_Object_Pool *pool), ARGIN(const void *ptr))
 {
     ASSERT_ARGS(contained_in_pool)
     const Small_Object_Arena *arena;
 
-    ptr = PObj_to_ARENA(ptr);
-
+    if (interp->gc_sys->PObj_to_Arena){
+        ptr = interp->gc_sys->PObj_to_Arena(ptr);
+    }
     for (arena = pool->last_Arena; arena; arena = arena->prev) {
         const ptrdiff_t ptr_diff =
             (ptrdiff_t)ptr - (ptrdiff_t)arena->start_objects;

Modified: branches/gc-refactor/src/gc/system.c
==============================================================================
--- branches/gc-refactor/src/gc/system.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/gc/system.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -489,7 +489,7 @@
 
     for (i = 0; i < arena_base->num_sized; i++) {
         if (arena_base->sized_header_pools[i]
-        &&  contained_in_pool(arena_base->sized_header_pools[i], ptr))
+            &&  contained_in_pool(interp, arena_base->sized_header_pools[i], ptr))
             return 1;
     }
 
@@ -512,7 +512,7 @@
 is_pmc_ptr(PARROT_INTERP, ARGIN(const void *ptr))
 {
     ASSERT_ARGS(is_pmc_ptr)
-    return contained_in_pool(interp->arena_base->pmc_pool, ptr);
+        return contained_in_pool(interp, interp->arena_base->pmc_pool, ptr);
 }
 
 

Modified: branches/gc-refactor/src/hash.c
==============================================================================
--- branches/gc-refactor/src/hash.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/hash.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -1304,18 +1304,34 @@
 
     if (bucket) {
         if (hash->entry_type == enum_type_PMC && hash->container) {
-            GC_WRITE_BARRIER_KEY(interp, hash->container,
-                    (PMC *)bucket->value, bucket->key, (PMC *)value, key);
+        
+        /*JT: can't get this to work right now ...
+        if (interp->gc_sys->write_barrier_key) {
+            Parrot_gc_write_barrier_key(interp,
+                                              hash->container,
+                                              (PMC *)bucket->value, 
+                                              bucket->key, 
+                                              (PMC *)value, 
+                                              key);
+        }
+        */
         }
-
         bucket->value = value;
     }
     else {
         if (hash->entry_type == enum_type_PMC && hash->container) {
-            GC_WRITE_BARRIER_KEY(interp, hash->container,
-                    NULL, NULL, (PMC *)value, key);
-        }
 
+        /*JT: can't get this to work right now ...
+        if (interp->gc_sys->write_barrier_key){
+            Parrot_gc_write_barrier_key(interp, 
+                                              hash->container,
+                                              NULL, 
+                                              NULL, 
+                                              (PMC *)value, 
+                                              key);
+        }
+        */
+        }
         bucket = hash->free_list;
 
         if (!bucket) {
@@ -1422,8 +1438,9 @@
                     "hash corruption: type = %d\n", hash->entry_type);
         };
 
-        if (key)
+        if (key){
             parrot_hash_put(interp, dest, key, valtmp);
+        }
     }
 }
 

Modified: branches/gc-refactor/src/list.c
==============================================================================
--- branches/gc-refactor/src/list.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/list.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -384,9 +384,13 @@
     memset(Buffer_bufstart((Buffer*)chunk), 0, size);
 
     /* see also src/hash.c */
-    if (list->container)
-        GC_WRITE_BARRIER(interp, list->container, 0, chunk);
-
+    if (list->container) {
+        /*JT: not working now ... GMS only anyway
+        if (interp->gc_sys->write_barrier){
+            Parrot_gc_write_barrier(interp, list->container, 0, chunk);
+        }
+        */
+    }
     Parrot_unblock_GC_mark(interp);
 
     /* Parrot_unblock_GC_sweep(interp); */
@@ -395,7 +399,7 @@
 
 
 /*
-
+  
 =item C<static void rebuild_chunk_ptrs(List *list, int cut)>
 
 Rebuilds C<list> and updates/optimizes chunk usage. Deletes empty chunks,
@@ -516,7 +520,11 @@
                         MAX_ITEMS * list->item_size);
 
                 if (list->container) {
-                    GC_WRITE_BARRIER(interp, list->container, 0, prev);
+                    /*JT: not working now ... GMS only anyway
+                    if (interp->gc_sys->write_barrier){
+                        Parrot_gc_write_barrier(interp, list->container, 0, prev);
+                    }
+                    */
                 }
 
                 mem_sys_memmove(
@@ -537,7 +545,11 @@
                 Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)prev,
                         (prev->items + chunk->items) * list->item_size);
                 if (list->container) {
-                    GC_WRITE_BARRIER(interp, list->container, 0, prev);
+                    /*JT: not working now ... GMS only anyway
+                    if (interp->gc_sys->write_barrier){
+                        Parrot_gc_write_barrier(interp, list->container, 0, prev);
+                    }
+                    */
                 }
                 mem_sys_memmove(
                         (char *) Buffer_bufstart(&prev->data) +
@@ -637,7 +649,11 @@
                 len * sizeof (List_chunk *));
 
         if (list->container) {
-            GC_WRITE_BARRIER(interp, list->container, 0, list);
+            /*JT: not working now ... GMS only anyway
+            if (interp->gc_sys->write_barrier){
+                Parrot_gc_write_barrier(interp, list->container, 0, list);
+            }
+            */
         }
 
         list->collect_runs = Parrot_gc_count_collect_runs(interp);
@@ -1136,7 +1152,11 @@
                 chunk->items * list->item_size);
 
         if (list->container) {
-            GC_WRITE_BARRIER(interp, list->container, 0, chunk);
+            /*JT: not working now ... GMS only anyway
+            if (interp->gc_sys->write_barrier){
+                Parrot_gc_write_barrier(interp, list->container, 0, chunk);
+            }
+            */
         }
 
         chunk->flags |= no_power_2;
@@ -1156,7 +1176,11 @@
                 chunk->items * list->item_size);
 
         if (list->container) {
-            GC_WRITE_BARRIER(interp, list->container, 0, chunk);
+            /*JT: not working now ... GMS only anyway
+            if (interp->gc_sys->write_barrier){
+                Parrot_gc_write_barrier(interp, list->container, 0, chunk);
+            }
+            */
         }
 
         chunk->flags &= ~sparse;
@@ -1247,9 +1271,14 @@
         break;
     case enum_type_PMC:
         if (list->container) {
-            GC_WRITE_BARRIER(interp, list->container,
-                    ((PMC **) Buffer_bufstart(&chunk->data))[idx],
-                    (PMC *)item);
+            /*JT: not working now ... GMS only anyway
+            if (interp->gc_sys->write_barrier){
+                Parrot_gc_write_barrier(interp, 
+                                              list->container, 
+                                              ((PMC **) Buffer_bufstart(&chunk->data))[idx],
+                                              (PMC *)item);
+            }
+            */
         }
         ((PMC **) Buffer_bufstart(&chunk->data))[idx] = (PMC *)item;
         break;
@@ -1333,9 +1362,9 @@
 {
     ASSERT_ARGS(list_append)
     /* initially, list may be empty, also used by assign */
-    while (idx >= list->cap)
+    while (idx >= list->cap){
         add_chunk_at_end(interp, list, idx);
-
+    }
     list_set(interp, list, item, type, idx);
 
     /* invariant: prepare for next push */

Modified: branches/gc-refactor/src/pmc/default.pmc
==============================================================================
--- branches/gc-refactor/src/pmc/default.pmc	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc/default.pmc	Sat Sep  5 18:39:01 2009	(r41011)
@@ -231,7 +231,11 @@
     PMC *prop;
 
     PMC_metadata(self) = prop = pmc_new(interp, enum_class_Hash);
-    GC_WRITE_BARRIER(interp, self, NULL, prop);
+    /*JT: not working now ... GMS only anyway
+    if (interp->gc_sys->write_barrier){
+        Parrot_gc_write_barrier(interp, self, NULL, prop);
+    }
+    */
     propagate_std_props(interp, self, prop);
     return prop;
 }

Modified: branches/gc-refactor/src/pmc/fixedpmcarray.pmc
==============================================================================
--- branches/gc-refactor/src/pmc/fixedpmcarray.pmc	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc/fixedpmcarray.pmc	Sat Sep  5 18:39:01 2009	(r41011)
@@ -543,7 +543,11 @@
                 _("FixedPMCArray: index out of bounds!"));
 
         data      = PMC_array(SELF);
-        GC_WRITE_BARRIER(INTERP, SELF, data[key], src);
+        /*JT: not working now ... GMS only anyway
+        if (interp->gc_sys->write_barrier){
+            Parrot_gc_write_barrier(INTERP, SELF, data[key], src);
+        }
+        */
         data[key] = src;
     }
 

Modified: branches/gc-refactor/src/pmc/fixedstringarray.pmc
==============================================================================
--- branches/gc-refactor/src/pmc/fixedstringarray.pmc	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc/fixedstringarray.pmc	Sat Sep  5 18:39:01 2009	(r41011)
@@ -436,7 +436,11 @@
                 "FixedStringArray: index out of bounds!");
 
         GET_ATTR_str_array(INTERP, SELF, str_array);
-        GC_WRITE_BARRIER(INTERP, SELF, str_array[key], value);
+        /*JT: not working now ... GMS only anyway
+        if (interp->gc_sys->write_barrier){
+            Parrot_gc_write_barrier(INTERP, SELF, str_array[key], value);
+        }
+        */
         str_array[key] = value;
     }
 

Modified: branches/gc-refactor/src/pmc/resizablepmcarray.pmc
==============================================================================
--- branches/gc-refactor/src/pmc/resizablepmcarray.pmc	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc/resizablepmcarray.pmc	Sat Sep  5 18:39:01 2009	(r41011)
@@ -266,7 +266,12 @@
             SELF.set_integer_native(key+1);
 
         data      = PMC_array(SELF);
-        GC_WRITE_BARRIER(INTERP, SELF, data[key], src);
+        /*JT: not working now ... GMS only anyway
+        if (interp->gc_sys->write_barrier){
+            Parrot_gc_write_barrier(INTERP, SELF, data[key], src);
+        }
+        */
+
         data[key] = src;
     }
 

Modified: branches/gc-refactor/src/pmc/resizablestringarray.pmc
==============================================================================
--- branches/gc-refactor/src/pmc/resizablestringarray.pmc	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc/resizablestringarray.pmc	Sat Sep  5 18:39:01 2009	(r41011)
@@ -86,7 +86,11 @@
             SELF.set_integer_native(key+1);
 
         GET_ATTR_str_array(INTERP, SELF, str_array);
-        GC_WRITE_BARRIER(INTERP, SELF, str_array[key], value);
+        /*JT: not working now ... GMS only anyway
+        if (interp->gc_sys->write_barrier){
+            Parrot_gc_write_barrier(INTERP, SELF, str_array[key], value);
+        }
+        */
         str_array[key] = value;
     }
 

Modified: branches/gc-refactor/src/pmc_freeze.c
==============================================================================
--- branches/gc-refactor/src/pmc_freeze.c	Sat Sep  5 18:35:08 2009	(r41010)
+++ branches/gc-refactor/src/pmc_freeze.c	Sat Sep  5 18:39:01 2009	(r41011)
@@ -1337,8 +1337,11 @@
 #endif
         /*
          * that's a duplicate
-         if (info->container)
-         GC_WRITE_BARRIER(interp, info->container, NULL, pmc);
+         if (info->container){
+           if (interp->gc_sys->write_barrier){
+             Parrot_gc_write_barrier(interp, info->container, NULL, pmc);
+           }
+         }
          */
         *info->thaw_ptr = pmc;
         return;
@@ -1357,16 +1360,20 @@
         info->thaw_result = pmc;
     else {
         if (info->container) {
-            GC_WRITE_BARRIER(interp, info->container, NULL, pmc);
+            /*JT: not working now ... GMS only anyway            
+            if (interp->gc_sys->write_barrier){
+                Parrot_gc_write_barrier(interp, info->container, NULL, pmc);
+            }
+            */
         }
         *info->thaw_ptr = pmc;
     }
     list_assign(interp, (List *)PMC_data(info->id_list), id, pmc, enum_type_PMC);
+
     /* remember nested aggregates depth first */
     list_unshift(interp, (List *)PMC_data(info->todo), pmc, enum_type_PMC);
 }
 
-
 /*
 
 =item C<static UINTVAL id_from_pmc(PARROT_INTERP, PMC* pmc)>


More information about the parrot-commits mailing list