[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