1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
4 #ifndef Collector_INCLUDED
5 #define Collector_INCLUDED 1
10 // A garbage collector.
18 friend class Collector;
20 bool readOnly() const { return readOnly_; }
21 bool permanent() const { return color_ == permanentColor; }
23 Object() : readOnly_(0) { }
25 // If we copy an object, don't copy inappropriate info.
26 Object(const Object &obj) { hasSubObjects_ = obj.hasSubObjects_; }
27 // For objects with subobjects, this must be overriden
28 // to call Collector::trace for each direct subobject.
29 virtual void traceSubObjects(Collector &) const { }
36 Object *next() const { return next_; }
37 Object *prev() const { return prev_; }
38 void makeHead() { prev_ = next_ = this; }
39 Color color() const { return Color(color_); }
40 void setColor(Color color) { color_ = color; }
41 void moveAfter(Object *tail);
42 bool hasSubObjects() const { return hasSubObjects_; }
43 void finalize() { this->~Object(); }
56 DynamicRoot(Collector &);
57 virtual ~DynamicRoot();
58 virtual void trace(Collector &) const { }
59 DynamicRoot(const DynamicRoot &);
60 void operator=(const DynamicRoot &);
63 void link(const DynamicRoot *);
68 friend class Collector;
71 class ObjectDynamicRoot : public DynamicRoot {
73 ObjectDynamicRoot(Collector &, Object * = 0);
74 ObjectDynamicRoot &operator=(Object *obj);
75 void trace(Collector &) const;
76 operator Object *() const { return obj_; }
82 Block(Block *, size_t, size_t, Object *);
88 Collector(size_t maxSize);
90 void *allocateObject(bool hasFinalizer);
91 // This is called only when the constructor throws an exception.
92 void unallocateObject(void *);
93 void trace(const Object *obj);
94 // Permanent objects must not be altered in such a way that
95 // they contain pointers to non-permanent objects.
96 void makePermanent(Object *);
97 // Returns the number of live objects.
98 unsigned long collect();
99 void makeReadOnly(Object *);
100 bool objectMaybeLive(Object *);
102 virtual void traceStaticRoots() const { }
104 Collector(const Collector &); // undefined
105 void operator=(const Collector &); // undefined
107 Object allObjectsList_; // doubly-linked circular list of all objects
108 Object permanentFinalizersList_;
110 DynamicRoot dynRootList_; // doubly-linked circular list
111 Object::Color currentColor_;
113 unsigned long totalObjects_;
117 void traceDynamicRoots();
119 void makeReadOnly1(Object *);
120 friend class DynamicRoot;
126 void Collector::Object::moveAfter(Object *tail)
128 // unlink from old position
129 next_->prev_ = prev_;
130 prev_->next_ = next_;
131 // link in following tail
133 tail->next_->prev_ = this;
139 void *Collector::allocateObject(bool hasFinalizer)
141 if (freePtr_ == &allObjectsList_)
143 Object *tem = freePtr_;
144 freePtr_ = freePtr_->next();
145 tem->setColor(currentColor_);
146 tem->hasFinalizer_ = hasFinalizer;
148 tem->moveAfter(&allObjectsList_);
153 void Collector::trace(const Object *obj)
155 if (obj && obj->color() != currentColor_
156 && obj->color() != Object::permanentColor) {
157 ((Object *)obj)->setColor(currentColor_);
158 ((Object *)obj)->moveAfter(lastTraced_);
159 lastTraced_ = (Object *)obj;
164 void Collector::DynamicRoot::link(const DynamicRoot *root)
166 DynamicRoot *list = (DynamicRoot *)root;
167 // link in just after list
170 list->next_->prev_ = this;
175 void Collector::DynamicRoot::unlink()
177 next_->prev_ = prev_;
178 prev_->next_ = next_;
182 Collector::DynamicRoot::DynamicRoot(Collector &c)
184 link(&c.dynRootList_);
188 Collector::DynamicRoot::DynamicRoot()
189 : next_(this), prev_(this)
194 Collector::DynamicRoot::DynamicRoot(const DynamicRoot &root)
200 void Collector::DynamicRoot::operator=(const DynamicRoot &root)
207 Collector::ObjectDynamicRoot::ObjectDynamicRoot(Collector &c, Object *obj)
208 : Collector::DynamicRoot(c), obj_(obj)
213 Collector::ObjectDynamicRoot &
214 Collector::ObjectDynamicRoot::operator=(Object *obj)
221 void Collector::ObjectDynamicRoot::trace(Collector &c) const
227 Collector::Block::~Block()
229 ::operator delete(firstObj);
233 bool Collector::objectMaybeLive(Object *obj)
235 return obj->color() == currentColor_ || obj->color() == Object::permanentColor;
239 void Collector::makeReadOnly(Object *obj)
241 if (!obj->hasSubObjects())
243 else if (!obj->readOnly())
247 #endif /* not Collector_INCLUDED */