CXXR (C++ R)
Classes | Public Member Functions | Static Public Member Functions | Protected Member Functions | Friends
CXXR::GCNode Class Reference

Base class for objects managed by the garbage collector. More...

#include <GCNode.hpp>

Inheritance diagram for CXXR::GCNode:
Inheritance graph
[legend]
Collaboration diagram for CXXR::GCNode:
Collaboration graph
[legend]

List of all members.

Classes

struct  const_visitor
 Abstract base class for the Visitor design pattern. More...
struct  GCInhibitor
 Not for general use. More...
class  PtrS11n
 Serialization/deserialization of pointers to GCNode objects. More...

Public Member Functions

virtual void detachReferents ()
 Null out all references from this node to other nodes.
void expose () const
 Record that construction of a node is complete.
bool isExposed () const
 Has this node been exposed to garbage collection?
virtual void visitReferents (const_visitor *v) const
 Conduct a visitor to the nodes referred to by this one.

Static Public Member Functions

static void * operator new (size_t bytes)
 Allocate memory.
static void * operator new (size_t, void *where)
 Placement new for GCNode.
static void operator delete (void *p, size_t bytes)
 Deallocate memory.
static bool check ()
 Integrity check.
template<class T >
static T * expose (T *node)
 Record that construction of a node is complete.
static void gc ()
 Initiate a garbage collection.
static void gclite ()
 Lightweight garbage collection.
static void maybeCheckExposed (const GCNode *node)
 Subject to configuration, check that a GCNode is exposed.
static size_t numNodes ()
 Number of GCNode objects in existence.

Protected Member Functions

virtual ~GCNode ()

Friends

class boost::serialization::access
class GCRootBase
class GCStackRootBase
class NodeStack
class WeakRef
class GCEdgeBase
class SchwarzCounter< GCNode >

Detailed Description

Base class for objects managed by the garbage collector.

Abstract base class for all objects managed by the garbage collector.

Derived class checklist:
Classes derived directly or indirectly from GCNode should do the following to ensure the integrity of the garbage collection scheme:
  1. Explicitly declare a destructor (even if it does nothing) as either protected or (if no further derivation from the class is envisaged) private. This ensures that objects of classes derived from GCNode can be created only using 'new'.

  2. If the derived class contains any pointers or references to other objects derived from GCNode, these should be encapsulated within an object of the templated class GCEdge, and the class should reimplement the methods detachReferents() and visitReferents() appropriately. (This does not necessarily apply to pointers where other logic ensures that the pointer does not outlive the thing pointed to.)
Infant immunity:
Mark-sweep garbage collection is disabled while any GCNode or object of a class derived from GCNode is under construction. This greatly simplifies the coding of the constructors. Such an object is considered to be under construction from the moment the constructor is invoked until the node is exposed by calling the member function expose() (in one of its two forms), or until the node is deleted, whichever is sooner. It is the responsibility of any code that creates an object of a class derived from GCNode to ensure that the object is exposed as soon as possible, e.g. before a pointer to the node is returned as the value of a function. In particular, a node must be exposed before it is designated as the target of a GCEdge, a GCStackRoot or a GCRoot, or protected with PROTECT() or REPROTECT(): if the preprocessor variable CHECK_EXPOSURE is defined, runtime checks for this are inserted into the code.

The simplest way of ensuring timely exposure is always to wrap the new call in a call to expose(): e.g. GCNode::expose(new FooNode(args). This can be further simplified using the CXXR_NEW macro to CXXR_NEW(FooNode).

Note:
Because this base class is used purely for housekeeping by the garbage collector, and does not contribute to the 'meaning' of an object of a derived class, its data members are mutable.
Todo:
The (private) cleanup() method needs to address the possibility that derived classes may have destructors that release some external resource (e.g. a lock). Maybe a garbage collection without a 'mark' phase would do the trick.

Constructor & Destructor Documentation

virtual CXXR::GCNode::~GCNode ( )
inlineprotectedvirtual
Note:
The destructor is protected to ensure that GCNode objects are allocated using 'new'. (See Meyers 'More Effective C++' Item 27.) Derived classes should likewise declare their destructors private or protected.

Member Function Documentation

bool GCNode::check ( )
static

Integrity check.

Aborts the program with an error message if the class is found to be internally inconsistent.

Returns:
true, if it returns at all. The return value is to facilitate use with assert.

Reimplemented in CXXR::WeakRef.

virtual void CXXR::GCNode::detachReferents ( )
inlinevirtual

Null out all references from this node to other nodes.

The referents of this node are those objects (derived from GCNode) designated by a GCEdge within this object. This function changes all GCEdges within this object to encapsulate a null pointer. It is used during the sweep phase of a mark-sweep garbage collection to break up unreachable subgraphs, and in particular to remove reference loops from them. After the application of this method, the GCNode should be regarded as a 'zombie', kept in existence only so other nodes can detach their references to it cleanly (using decRefCount()).

Note:
If this method is reimplemented in a derived class, the reimplemented version must remember to invoke detachReferents() for the immediate base class of the derived class, to ensure that all referents of the object get detached.

Reimplemented in CXXR::Frame, CXXR::RObject, CXXR::Environment, CXXR::ConsCell, CXXR::Provenance, CXXR::ArgMatcher, CXXR::Symbol, CXXR::S3Launcher, CXXR::FixedVector< T, ST, Initializer >, CXXR::Closure, CXXR::WeakRef, CXXR::ExternalPointer, CXXR::Promise, CXXR::CommandChronicle, CXXR::ByteCode, CXXR::ReturnBailout, and CXXR::LoopBailout.

void CXXR::GCNode::expose ( ) const
inline

Record that construction of a node is complete.

See the description of the templated form of expose.

template<class T >
static T* CXXR::GCNode::expose ( T *  node)
inlinestatic

Record that construction of a node is complete.

In normal operation (i.e. unless the object's constructor throws an exception), this function - or its non-templated form - should be called for each object derived from GCNode, and this should be done as soon as possible after construction of the object is complete. In particular, a node must be exposed before it is designated as the target of a GCEdge, a GCStackRoot or a GCRoot, or protected with PROTECT() or REPROTECT(): if the preprocessor variable CHECK_EXPOSURE is defined, runtime checks for this are inserted into the code.

The simplest way of ensuring timely exposure is always to wrap the new call in a call to expose(): e.g. GCNode::expose(new FooNode(args). This can be further simplified using the CXXR_NEW macro to CXXR_NEW(FooNode).

It is not permissible for a node to be exposed more than once, and this is checked unless NDEBUG is defined.

Template Parameters:
TGCNode or any class derived from it, possibly qualified by const.
Parameters:
nodePointer to the node whose construction has been completed.
Returns:
the pointer node itself.
Note:
The name of this function reflects an earlier design in which GCNode objects were individually exposed to mark-sweep garbage collection once their construction was complete. In the current design, mark-sweep garbage collection is inhibited entirely whilst any GCNode object is under construction.
void GCNode::gclite ( )
static

Lightweight garbage collection.

This function deletes nodes whose reference counts have fallen to zero: if the deletion of these nodes in turn causes the reference counts of other nodes to fall to zero, those nodes are also deleted, and so on recursively.

Note:
This function does not delete nodes whose reference counts have never have risen above zero.
bool CXXR::GCNode::isExposed ( ) const
inline

Has this node been exposed to garbage collection?

Returns:
true iff this node has been exposed to garbage collection.
static void CXXR::GCNode::maybeCheckExposed ( const GCNode node)
inlinestatic

Subject to configuration, check that a GCNode is exposed.

Normally, this function is an inlined no-op. However, if the preprocessor variable CHECK_EXPOSURE is defined, it checks that a GCNode is exposed to garbage collection, and aborts the program if not. This can be a useful diagnostic aid.

Parameters:
nodePointer to the node to be checked, or a null pointer in which case the check passes.
static size_t CXXR::GCNode::numNodes ( )
inlinestatic

Number of GCNode objects in existence.

Returns:
the number of GCNode objects currently in existence.
static void CXXR::GCNode::operator delete ( void *  p,
size_t  bytes 
)
inlinestatic

Deallocate memory.

Deallocate memory previously allocated by operator new.

Parameters:
pPointer to the allocated memory block.
bytesSize in bytes of the memory block, as requested when the block was allocated.
void * GCNode::operator new ( size_t  bytes)
static

Allocate memory.

Allocates memory for a new object of a class derived from GCNode.

Parameters:
bytesNumber of bytes of memory required.
Returns:
Pointer to the allocated memory block.
Note:
This function will often carry out garbage collection of some kind before allocating memory. However, no mark-sweep collection will be performed if another GCNode object is currently under construction, or if at least one GCInhibitor object is in existence.
virtual void CXXR::GCNode::visitReferents ( const_visitor v) const
inlinevirtual

Conduct a visitor to the nodes referred to by this one.

The referents of this node are those objects (derived from GCNode) designated by a GCEdge within this object.

Parameters:
vPointer to the visitor object.
Note:
If this method is reimplemented in a derived class, the reimplemented version must remember to invoke visitReferents() for the immediate base class of the derived class, to ensure that all referents of the object get visited. It is suggested that implementations set up stack-based pointers to all the referents of a node before visiting any of them; in that case, if the (recursive) visiting pushes the node out of the processor cache, there is no need to fetch it back in.

Reimplemented in CXXR::Frame, CXXR::RObject, CXXR::Environment, CXXR::ConsCell, CXXR::Provenance, CXXR::ArgMatcher, CXXR::Symbol, CXXR::S3Launcher, CXXR::FixedVector< T, ST, Initializer >, CXXR::Closure, CXXR::ExternalPointer, CXXR::Promise, CXXR::CommandChronicle, CXXR::ByteCode, CXXR::ReturnBailout, and CXXR::LoopBailout.


The documentation for this class was generated from the following files: