Author: Whiteknight
Date: Mon Aug 18 16:36:57 2008
New Revision: 30315

Modified:
   trunk/docs/pdds/pdd09_gc.pod

Log:
[PDD] a few clarifications to PDD09, some better wording, spelling fixes. 
Expand on some topics that didn't have great coverage before.

Modified: trunk/docs/pdds/pdd09_gc.pod
==============================================================================
--- trunk/docs/pdds/pdd09_gc.pod        (original)
+++ trunk/docs/pdds/pdd09_gc.pod        Mon Aug 18 16:36:57 2008
@@ -377,7 +377,7 @@
 Trigger or perform a GC run. With an incremental GC core, this may only
 start/continue a partial mark phase or sweep phase, rather than performing an
 entire run from start to finish. It may take several calls to C<do_gc_mark> in
-order to complete an entire incremental run.
+order to complete an entire run of an incremental collector.
 
 For a concurrent collector, calls to this function may activate a concurrent
 collection thread or, if such a thread is already running, do nothing at all.
@@ -432,17 +432,20 @@
 =item C<void (*finalize_gc_system) (Interp *)>
 
 Called during interpreter destruction. Free used resources and memory pools.
+All PMCs must be swept, and PMCs with custom destroy VTABLE methods must have
+those called.
 
 =item C<void (*init_pool) (Interp *, Small_Object_Pool *)>
 
-Initialize the given pool. This function should set the following function
-pointers for use with the pool.
+Initialize the given pool. Populates the C<Small_Object_Pool> structure with
+initial values, and sets a series of function pointers for working with the
+pool. The function pointers used with the pool are discussed next.
 
 =back
 
 =head3 Small_Object_Pool function pointers
 
-Each GC core defines 4 function pointers stored in the Small_Object_Pool
+Each GC core defines 4 function pointers stored in the C<Small_Object_Pool>
 structures. These function pointers are used throughout Parrot to implement
 basic behaviors for the pool.
 
@@ -458,7 +461,10 @@
 
 =item C<void (*add_free_object) (Interp *, Small_Object_Pool *, PObj *);>
 
-Add a freed object to the pool's free list.
+Add a freed object to the pool's free list. This function is most often called
+internally to the GC itself to add items to the free list after a sweep, or
+when a new arena is created to add the new items to the free list. It does
+not need to be used in this way, however.
 
 =item C<void (*alloc_objects) (Interp *, Small_Object_Pool *);>
 
@@ -471,93 +477,104 @@
 Reallocation for additional objects. It has the same signature as
 C<alloc_objects>, and in some GC cores the same function pointer is used for
 both. In some GC cores, C<more_objects> may do a GC run in an attempt to free
-existing objects without having to allocate new ones.
+existing objects without having to allocate new ones. This function may also
+call C<pool->alloc_objects> internally, to allocate objects if a GC run fails
+to free any old objects.
 
 =back
 
 =head3 Write Barrier
 
-Each GC core has to provide these (possibly empty) macros:
+Each GC core has to provide the following macros. All of these might be
+defined empty, for GC cores which do not use them.
 
 =over 4
 
 =item C<GC_WRITE_BARRIER(Interp *, PMC *agg, PMC *old, PMC *new)>
 
 This macro is invoked when in aggregate C<agg> the element C<old> is getting
-overritten by C<new>. Both C<old> and C<new> may be NULL.
+overwritten by C<new>. Either C<old>, C<new>, or both may be NULL.
 
 =item C<GC_WRITE_BARRIER_KEY(Interp *, PMC *agg, PMC *old, PObj
 *old_key, PMC *new, PObj *new_key)>
 
-Like above. Invoked when a hash key is inserted, possibly replacing an old
-key.
+Similar to C<GC_WRITE_BARRIER>. Invoked when a hash key C<new_key> is
+inserted into hash C<agg> with value C<new>, possibly replacing a key/value
+pair C<old_key> and C<old>, respectively. Any of C<old>, C<old_key>, C<new>
+or C<new_key> might be C<NULL>.
 
 =back
 
 =head2 Blocking GC
 
 Being able to block GC is important, so newly allocated Buffers or PMCs won't
-be collected before they're attached to the live tree. The following
-routines control GC:
+be collected before they're attached to the live tree. Parrot provides locking
+mechanisms to prevent the GC from taking certain actions, such as marking
+or sweeping. GC block functions are nesting, and multiple calls to a lock
+function requires the same number of calls to the corresponding unlock
+function in order to operate the GC normally again. The following functions
+are used to block the GC from performing certain actions:
 
 =over 4
 
 =item Parrot_block_GC_mark(Interp *interpreter)
 
-Block the GC mark phase for the passed interpreter. (But not the sweep phase)
+Block the GC mark phase for the passed interpreter, but do not block the sweep
+phase. In a stop-the-world collector, this will prevent the entire collection
+run, but in an incremental collector this will only block if the GC is in the
+trace state.
 
 =item Parrot_block_GC_sweep(Interp *interpreter)
 
-Block the GC sweep phase for the passed interpreter. (But not the mark phase)
+Block the GC sweep phase for the passed interpreter, but do not block the
+trace phase.
 
 =item Parrot_unblock_GC_mark(Interp *interpreter)
 
-Unblock the GC mark phase for the passed interpreter. (But not the sweep
-phase)
+Unblock the GC mark phase for the passed interpreter, but do not unblock a
+blocked sweep phase, if it is blocked using C<Parrot_block_GC_sweep>.
 
 =item Parrot_unblock_GC_sweep(Interp *interpreter)
 
-Unblock the GC sweep phase for the passed interpreter. (But not the mark
-phase)
+Unblock the GC sweep phase for the passed interpreter, but do not unblock the
+mark phase if it has been blocked by C<Parrot_block_GC_mark>.
 
 =item Parrot_is_blocked_GC_mark(Interp *interpreter)
 
-Test whether the mark phase has been blocked.
+Test whether the mark phase has been blocked. Notice that the sweep phase can
+be locked independently and cannot be determined using this function.
 
 =item Parrot_is_blocked_GC_sweep(Interp *interpreter)
 
-Test whether the sweep phase has been blocked.
+Test whether the sweep phase has been blocked. Notice that the mark phase can
+be locked independently and cannot be determined using this function.
 
 =back
 
-Note that the blocking is recursive--if you call Parrot_block_GC_sweep() three
-times in succession, you need to call Parrot_unblock_GC_sweep() three times to
-re-enable the GC sweep phase.
-
 =head2 PMC/Buffer API
 
 =head3 Flags
 
 For PMCs and Buffers to be collected properly, you must set the appropriate
-flags on them.
-
-Directly manipulating these flags is not recommended. Always use the macros
-defined in F<include/parrot/pobj.h>.
+flags on them. Directly manipulating these flags is not recommended because
+the exact values can be changed over time. A series of macros have been created
+in F<include/parrot/pobject.h> that set and check for these flags. Always use
+these provided macros when you need to test or set these flags.
 
 =over 4
 
 =item PObj_active_destroy_FLAG
 
 The PMC has some sort of active destructor, and will have that destructor
-called when the PMC is destroyed.
+called when the PMC is destroyed. The destructor is typically called from
+within C<src/gc/dod.c:Parrot_dod_free_pmc>.
 
 =item PObj_custom_mark_FLAG
 
 The C<mark> vtable slot will be called during the GC mark phase. The mark
 function must call C<pobject_lives> for all non-NULL objects (Buffers and
-PMCs) that PMC refers to.
-
-Please note that C<pobject_lives> may be a macro.
+PMCs) that PMC refers to. This flag is typically tested and the custom mark
+VTABLE method called from C<src/gc/dod.c:mark_special>.
 
 =item PObj_data_is_PMC_array_FLAG
 
@@ -587,7 +604,9 @@
 
 =item PObj_live_FLAG
 
-The system considers the object to be alive for collection purposes.
+The system considers the object to be alive for collection purposes. Objects
+with this flag set should never be collected, freed, destroyed, or put on the
+free list.
 
 =item PObj_on_free_list_FLAG
 

Reply via email to