[svn:parrot] r41046 - in branches/gc-refactor: docs/pdds include/parrot src src/gc
jrtayloriv at svn.parrot.org
jrtayloriv at svn.parrot.org
Sun Sep 6 07:01:54 UTC 2009
Author: jrtayloriv
Date: Sun Sep 6 07:01:54 2009
New Revision: 41046
URL: https://trac.parrot.org/parrot/changeset/41046
Log:
Moved structs out of gc_api.h and into gc_private.h, replaced some #if with if, minor updates to GC docs, reorganized for clarity
Modified:
branches/gc-refactor/docs/pdds/pdd09_gc.pod
branches/gc-refactor/include/parrot/gc_api.h
branches/gc-refactor/src/gc/alloc_resources.c
branches/gc-refactor/src/gc/api.c
branches/gc-refactor/src/gc/gc_private.h
branches/gc-refactor/src/hash.c
branches/gc-refactor/src/list.c
Modified: branches/gc-refactor/docs/pdds/pdd09_gc.pod
==============================================================================
--- branches/gc-refactor/docs/pdds/pdd09_gc.pod Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/docs/pdds/pdd09_gc.pod Sun Sep 6 07:01:54 2009 (r41046)
@@ -49,18 +49,6 @@
In this GC scheme, after all reachable objects are marked as live, a sweep
through the object arenas collects all unmarked objects.
-=head3 Mark-and-don't-sweep
-
-In this scheme, all objects are marked black (live) when created. White
-objects are free memory available for allocation. When no white objects remain
-(out of memory), the black objects are all changed to white, and a marking
-process runs to mark all reachable objects as live. Any unreachable objects
-are left white, and available for allocation.
-
-In some implementations, the change from black to white is made by simply
-changing the interpretation of the mark bit, for example, from 1 == black to 1
-== white.
-
=head3 Copying collection
In this scheme, live objects are copied into a new memory region. The entire
@@ -162,11 +150,11 @@
=head3 Terminology
A GC run is composed of two distinct operations: Finding objects which are
-dead (the "trace" phase) and freeing dead objects for later reuse (the
-"sweep" phase). The sweep phase is also known as the collection phase. The
-trace phase is also known as the "mark phase" and less frequently as the
-"dead object detection" phase. The use of the term "dead object detection"
-and its acronym DOD has been deprecated.
+dead (the "trace" or "mark" phase) and freeing dead objects for later reuse
+(the "sweep" phase). The sweep phase is also known as the collection phase.
+The trace phase is less frequently known as the "dead object detection" phase.
+The use of the term "dead object detection" and its acronym DOD has been
+deprecated.
=head3 Initial Marking
@@ -314,18 +302,20 @@
=head4 The Var_Size_Obj_Pool structure
-The Var_Size_Obj_Pool structure is a simple memory pool. It contains a pointer to
-the top block of the allocated pool, the total allocated size of the pool, the
-block size, and some details on the reclamation characteristics of the pool.
+The Var_Size_Obj_Pool structure is a simple memory pool. It contains a pointer
+to the top block of the allocated pool, the total allocated size of the pool,
+the block size, and some details on the reclamation characteristics of the
+pool.
=head4 The Fixed_Size_Obj_Pool structure
-The Fixed_Size_Obj_Pool structure is a richer memory pool for object allocation.
-It tracks details like the number of allocated and free objects in the pool, a
-list of free objects, and for the generational GC implementation maintains
-linked lists of white, black, and gray PMCs. It contains a pointer to a simple
-Var_Size_Obj_Pool (the base storage of the pool). It holds function pointers for
-adding and retrieving free objects in the pool, and for allocating objects.
+The Fixed_Size_Obj_Pool structure is a richer memory pool for object
+allocation. It tracks details like the number of allocated and free objects
+in the pool, a list of free objects, and for the generational GC
+implementation maintains linked lists of white, black, and gray PMCs. It
+contains a pointer to a simple Var_Size_Obj_Pool (the base storage of the
+pool). It holds function pointers for adding and retrieving free objects in
+the pool, and for allocating objects.
=head3 Internal API
Modified: branches/gc-refactor/include/parrot/gc_api.h
==============================================================================
--- branches/gc-refactor/include/parrot/gc_api.h Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/include/parrot/gc_api.h Sun Sep 6 07:01:54 2009 (r41046)
@@ -52,38 +52,19 @@
POOL_ALL = 0x07
} pool_iter_enum;
+struct Memory_Block;
+struct Var_Size_Obj_Pool;
struct Fixed_Size_Obj_Pool;
struct Fixed_Size_Obj_Arena;
struct Arenas;
-typedef int (*pool_iter_fn)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *, int, void*);
-
-typedef struct Memory_Block {
- size_t free;
- size_t size;
- struct Memory_Block *prev;
- struct Memory_Block *next;
- char *start;
- char *top;
-} Memory_Block;
-
-typedef struct Var_Size_Obj_Pool {
- Memory_Block *top_block;
- void (*compact)(PARROT_INTERP, struct Var_Size_Obj_Pool *);
- size_t minimum_block_size;
- size_t total_allocated; /* total bytes allocated to this pool */
- size_t guaranteed_reclaimable; /* bytes that can definitely be reclaimed*/
- size_t possibly_reclaimable; /* bytes that can possibly be reclaimed
- * (above plus COW-freed bytes) */
- FLOATVAL reclaim_factor; /* minimum percentage we will reclaim */
-} Var_Size_Obj_Pool;
-
typedef enum {
GC_TRACE_FULL = 1,
GC_TRACE_ROOT_ONLY = 2,
GC_TRACE_SYSTEM_ONLY = 3
} Parrot_gc_trace_type;
+typedef int (*pool_iter_fn)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *, int, void*);
typedef void (*add_free_object_fn_type)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *, void *);
typedef void * (*get_free_object_fn_type)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *);
typedef void (*alloc_objects_fn_type)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *);
Modified: branches/gc-refactor/src/gc/alloc_resources.c
==============================================================================
--- branches/gc-refactor/src/gc/alloc_resources.c Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/src/gc/alloc_resources.c Sun Sep 6 07:01:54 2009 (r41046)
@@ -216,17 +216,18 @@
if (!interp->arena_base->gc_mark_block_level
&& interp->arena_base->mem_allocs_since_last_collect) {
Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
-#if !PARROT_GC_IMS && !PARROT_GC_INF
- /* Compact the pool if allowed and worthwhile */
- if (pool->compact) {
- /* don't bother reclaiming if it's just chicken feed */
- if ((pool->possibly_reclaimable * pool->reclaim_factor +
- pool->guaranteed_reclaimable) > size) {
- (*pool->compact) (interp, pool);
- }
+ if ((interp->gc_sys->sys_type != IMS) &&
+ (interp->gc_sys->sys_type != INF)) {
+ /* Compact the pool if allowed and worthwhile */
+ if (pool->compact) {
+ /* don't bother reclaiming if it's only a small amount */
+ if ((pool->possibly_reclaimable * pool->reclaim_factor +
+ pool->guaranteed_reclaimable) > size) {
+ (*pool->compact) (interp, pool);
+ }
+ }
}
-#endif
}
if (pool->top_block->free < size) {
if (pool->minimum_block_size < 65536 * 16)
@@ -417,16 +418,16 @@
for (cur_buffer_arena = header_pool->last_Arena;
cur_buffer_arena;
cur_buffer_arena = cur_buffer_arena->prev) {
- /*JT: Something like this is what we really want ...
+ /*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 *)
+ 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
+ /*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;
Modified: branches/gc-refactor/src/gc/api.c
==============================================================================
--- branches/gc-refactor/src/gc/api.c Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/src/gc/api.c Sun Sep 6 07:01:54 2009 (r41046)
@@ -202,9 +202,9 @@
if (interp->gc_sys->sys_type == GMS) {
/*
do {
- if (!PObj_live_TEST(obj) &&
+ if (!PObj_live_TEST(obj) &&
PObj_to_GMSH(obj)->gen->gen_no >=
- interp->gc_sys->gc_sys_data.gms_data->gc_generation)
+ interp->gc_sys->gc_sys_data.gms_data->gc_generation)
parrot_gc_gms_Parrot_gc_mark_PObj_alive(interp, obj);
} while (0);
break;
@@ -214,26 +214,26 @@
/* 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);
-
+
# 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));
}
@@ -275,19 +275,19 @@
interp->gc_sys = mem_allocate_zeroed_typed(GC_Subsystem);
- /*JT: This is set at compile time ... what we need to do next is
+ /*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 */
+ * 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()
+ * ... 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) {
+ switch (interp->gc_sys->sys_type) {
case MS:
Parrot_gc_ms_init(interp);
break;
@@ -300,7 +300,7 @@
break;
case INF:
Parrot_gc_inf_init(interp);
- break;
+ break;
*/
default:
break; /*What SHOULD we be doing if we get here?*/
@@ -1621,7 +1621,7 @@
*/
-void
+void
Parrot_gc_write_barrier(PARROT_INTERP, PMC *agg, PMC *old, PMC *new){
interp->gc_sys->write_barrier(interp, agg, old, new);
}
@@ -1636,7 +1636,7 @@
*/
-void
+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);
}
Modified: branches/gc-refactor/src/gc/gc_private.h
==============================================================================
--- branches/gc-refactor/src/gc/gc_private.h Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/src/gc/gc_private.h Sun Sep 6 07:01:54 2009 (r41046)
@@ -104,10 +104,11 @@
void (*finalize_gc_system) (PARROT_INTERP);
void (*init_pool)(PARROT_INTERP, struct Fixed_Size_Obj_Pool *);
- /*Function hooks that GC systems can CHOOSE to provide
+ /*Function hooks that GC systems can CHOOSE to provide if they need them
*These will be called from the GC API function Parrot_gc_func_name */
void (*write_barrier)(PARROT_INTERP, PMC *, PMC *, PMC *);
void (*write_barrier_key)(PARROT_INTERP, PMC *, PMC *, PObj *, PMC *, PObj *);
+ /*read_barrier hooks can go here later*/
/* functions used in arena scan code to convert from object pointers
* to arena pointers ... GMS only I think ...*/
@@ -118,6 +119,26 @@
size_t header_size;
} GC_Subsystem;
+typedef struct Memory_Block {
+ size_t free;
+ size_t size;
+ struct Memory_Block *prev;
+ struct Memory_Block *next;
+ char *start;
+ char *top;
+} Memory_Block;
+
+typedef struct Var_Size_Obj_Pool {
+ Memory_Block *top_block;
+ void (*compact)(PARROT_INTERP, struct Var_Size_Obj_Pool *);
+ size_t minimum_block_size;
+ size_t total_allocated; /* total bytes allocated to this pool */
+ size_t guaranteed_reclaimable; /* bytes that can definitely be reclaimed*/
+ size_t possibly_reclaimable; /* bytes that can possibly be reclaimed
+ * (above plus COW-freed bytes) */
+ FLOATVAL reclaim_factor; /* minimum percentage we will reclaim */
+} Var_Size_Obj_Pool;
+
typedef struct Fixed_Size_Obj_Arena {
size_t used;
size_t total_objects;
@@ -150,20 +171,27 @@
/* Tracked resource pool */
typedef struct Fixed_Size_Obj_Pool {
+
+ struct Var_Size_Obj_Pool *mem_pool;
+ /* Size in bytes of an individual pool item. This size may include
+ * a GC-system specific GC header. (e.g. GMS headers) */
+ size_t object_size;
+
+ size_t start_arena_memory;
+ size_t end_arena_memory;
+
Fixed_Size_Obj_Arena *last_Arena;
- /* Size in bytes of an individual pool item. This size may include
- * a GC-system specific GC header.
- * See the macros below.
- */
- size_t object_size;
- size_t objects_per_alloc;
- size_t total_objects;
+ GC_MS_PObj_Wrapper * free_list;
size_t num_free_objects; /* number of resources in the free pool */
+ size_t total_objects;
+
+ PARROT_OBSERVER const char *name;
+
+ size_t objects_per_alloc;
+
int skip;
size_t replenish_level;
- GC_MS_PObj_Wrapper * free_list;
-
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
@@ -173,13 +201,6 @@
alloc_objects_fn_type more_objects;
gc_object_fn_type gc_object;
-
-
- struct Var_Size_Obj_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*/
Modified: branches/gc-refactor/src/hash.c
==============================================================================
--- branches/gc-refactor/src/hash.c Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/src/hash.c Sun Sep 6 07:01:54 2009 (r41046)
@@ -1304,14 +1304,14 @@
if (bucket) {
if (hash->entry_type == enum_type_PMC && hash->container) {
-
+
/*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,
+ (PMC *)bucket->value,
+ bucket->key,
+ (PMC *)value,
key);
}
*/
@@ -1323,11 +1323,11 @@
/*JT: can't get this to work right now ...
if (interp->gc_sys->write_barrier_key){
- Parrot_gc_write_barrier_key(interp,
+ Parrot_gc_write_barrier_key(interp,
hash->container,
- NULL,
- NULL,
- (PMC *)value,
+ NULL,
+ NULL,
+ (PMC *)value,
key);
}
*/
Modified: branches/gc-refactor/src/list.c
==============================================================================
--- branches/gc-refactor/src/list.c Sun Sep 6 06:54:55 2009 (r41045)
+++ branches/gc-refactor/src/list.c Sun Sep 6 07:01:54 2009 (r41046)
@@ -399,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,
@@ -1273,8 +1273,8 @@
if (list->container) {
/*JT: not working now ... GMS only anyway
if (interp->gc_sys->write_barrier){
- Parrot_gc_write_barrier(interp,
- list->container,
+ Parrot_gc_write_barrier(interp,
+ list->container,
((PMC **) Buffer_bufstart(&chunk->data))[idx],
(PMC *)item);
}
More information about the parrot-commits
mailing list