Garbage Collection and Dead Object Detection
Maintainer: Dan Sugalski Class: Internals PDD Number: 9 Version: 1.1 Status: Developing Last Modified: 26 February, 2002 PDD Format: 1 Language: English
26 February 2002
None. First version
Started documenting the internal routines
This PDD describes how the GC and DOD systems work, and what's required of PMC classes.
Doing GC takes a bit of work--we need to make sure that everything is findable from the root set, and that we don't go messing up data shared between interpreters.
For each PMC on the trace list we:
Once we're done, we scan the PMC list twice. In the first scan, dead PMCs (i.e no live bit and no free bit) with a destructor have that destructor called. In the second scan, dead PMCs are put on the free list for later reallocation.
Then we scan the Buffer list. Any dead buffers (no live bit and no free bit) are put on the free buffer list.
These are the steps that the GC takes:
PMCs should only have a custom GC routine if there's really a need for the PMC to keep track of the location of the ultimate buffered data.
For PMCs that need to hand data back to a library when their objects are destroyed, a custom DOD routine is in order, *not* a custom GC routine.
Being able to block GC and DOD is important--you'd hate to have the newly allocated Buffers or PMCs you've got yanked out from underneath you. That'd be no fun. Use the following routines to control GC:
Block DOD for the passed interpreter. (But not GC)
Block GC for the passed interpreter. (But not DOD)
Unblock DOD for the passed interpreter. (But not GC)
Unblock GC for the passed interpreter. (But not DOD)
Note that the blocking is recursive--if you call Parrot_block_DOD() three times in succession, you need to call Parrot_unblock_DOD() three times to re-enable DOD.
For PMCs and Buffers to be collected properly, you must get the flags set on them properly. Otherwise Bad Things Will Happen.
For PMCs:
The PMC has some sort of active destructor, and will have that destructor called when the PMC is destroyed.
Set if the data pointer points to a Buffer struct, or something like it. If you point to a buffer and don't set this flag, it'll end up getting collected.
Set if the data pointer points to a PMC. Set this if it does, or you'll find your PMC collected.
If both PMC_is_PMC_ptr_FLAG and PMC_is_buffer_ptr_FLAG are set, we assume the pointer is to a Buffer holding PMC pointers. (Like, say, the standard array, hash, and list PMC types do) We'll run through the Buffer and mark all the non-NULL pointers as live PMCs.
Set if you've got your own private GC, either for marking or collecting. The collector will call your vtable collection routine, and the DOD sweep will call your vtable mark routine.
Set if the system considers the PMC alive.
Set if the PMC is on the free list.
Set if this is a constant PMC. Constants never die.
For Buffers (and STRINGs)
Set if the buffer is a constant. Constants never die.
Set if the contents of the buffer can't move. Do not ever set this on a buffer pointing to memory allocated with Parrot_allocate. Your memory will be scrozzled all over.
Parrot_allocate
Set if the buffer points to memory that came from outside Parrot's memory system.
Set if the memory came from the system malloc. When the buffer is considered dead, the memory will be freed back to the system.
The buffer's memory is copy on write. Any changes to the buffer must first have the buffer's memory copied. The COW flag should then be removed.
The system considers the buffer to be alive for collection purposes.
The buffer is unused, and on the free list for later allocation.
Scans the Buffer header pools and compacts the used memory. Doesn't check for string liveness or anything of the sort, just does a compaction.
To install Make, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Make
CPAN shell
perl -MCPAN -e shell install Make
For more information on module installation, please visit the detailed CPAN module installation guide.