Fixed some C/C++ compiler errors due to stricter checks.
[rubinius.git] / machine / memory / root.hpp
blob4bfe221f0c4fa2f610f9957d97f19cb9ba612f36
1 #ifndef RBX_GC_ROOT_HPP
2 #define RBX_GC_ROOT_HPP
5 #include <stdexcept>
7 #include "memory/header.hpp"
9 #include "linkedlist.hpp"
10 #include "defines.hpp"
12 namespace rubinius {
13 namespace memory {
14 class Root;
16 /**
17 * Roots is a structure comprising of Root objects.
19 * @todo Add more information about class. --rue
20 * @todo Document methods. --rue
22 class Roots : public LinkedList {
23 std::mutex lock_;
25 public: /* Ctors */
26 Roots()
27 : LinkedList()
28 , lock_()
31 public: /* Interface */
32 Root* front();
34 typedef LinkedList::Iterator<Roots, Root> Iterator;
36 void add(Root*);
37 void remove(Root*);
40 /**
41 * A Root envelops an Object.
43 * Each Root is also associated with a certain Roots structure
44 * and could be used to access its other members. The Root can
45 * be associated with (or "migrated to") a different Roots.
47 * @todo Document remaining methods. --rue
49 class Root : public LinkedList::Node {
50 /** The Roots structure this Root belongs to. */
51 Roots* roots_;
53 protected:
54 /** Enveloped Object. */
55 Object* object_;
57 public: /** Constructors */
59 Root()
60 : LinkedList::Node()
61 , roots_(NULL)
62 , object_(cUndef)
65 Root(Roots* roots)
66 : LinkedList::Node()
67 , roots_(roots)
68 , object_(cUndef)
71 Root(Roots* roots, Object* obj)
72 : LinkedList::Node()
73 , roots_(roots)
74 , object_(obj)
76 roots_->add(this);
79 Root(STATE);
80 Root(STATE, Object* obj);
82 /** Copy construction uses set() semantics. */
83 Root(const Root& other)
84 : LinkedList::Node()
85 , roots_(NULL)
86 , object_(cUndef)
88 set(other.object_, other.roots_);
91 ~Root() {
92 if(roots_ && object_ && object_ != cUndef) roots_->remove(this);
95 public: /** Methods */
97 /** Assignment uses set() semantics. */
98 Root& operator=(Root& other) {
99 set(other.object_, other.roots_);
100 return *this;
103 /** Obtain the enveloped Object. */
104 Object* get() const {
105 return object_;
108 /** Envelope the given Object. Must have roots already. */
109 void set(Object* obj) {
110 assert(roots_ && "invalid Root usage. Cannot set object before roots");
111 set(obj, roots_);
114 /** Envelope the given Object, migrating to given Roots if it is new. */
115 void set(Object* obj, Roots* r);
117 // Used in the JIT to allow for loading of Roots directly.
118 Object** object_address() {
119 return &object_;
124 * TypedRoot is a Root that knows the type of its Object.
126 * @todo Use base type of object rather than pointer type
127 * as ObjType and change usage accordingly? This
128 * allows, among other things, using `as()` rather
129 * than a direct C++ cast. --rue
131 template <typename ObjType>
132 class TypedRoot : public Root {
133 public:
134 TypedRoot()
135 : Root()
138 /** As Root::Root(roots), but retains object's type. */
139 TypedRoot(Roots* roots)
140 : Root(roots)
143 /** As Root::Root(STATE), but retains object's type. */
144 TypedRoot(STATE)
145 : Root(state)
148 /** As Root::Root(STATE, Object*), but retains object's type. */
149 TypedRoot(STATE, ObjType obj)
150 : Root(state, reinterpret_cast<Object*>(obj))
153 /** Transparently delegate dereferencing to enveloped object. */
154 /** @todo Use as<ObjType>() when using base type instead of pointer. --rue */
155 ObjType operator->() const {
156 // assert(object_ && "Using an unassigned root!");
157 return reinterpret_cast<ObjType>(object_);
160 /** Return the enveloped object as the real ObjType. */
161 /** @todo Use as<ObjType>() when using base type instead of pointer. --rue */
162 ObjType get() const {
163 // assert(object_ && "Using an unassigned root!");
164 return reinterpret_cast<ObjType>(object_);
170 #endif