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