1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are welcomed to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome(read crave for)
19 // any suggestions and help from the users.
21 // Allen Leung (leunga@cs.nyu.edu)
23 //////////////////////////////////////////////////////////////////////////////
25 #ifndef weak_pointer_h
26 #define weak_pointer_h
28 //////////////////////////////////////////////////////////////////////////////
29 // This file defines the interface to weakpointers into garbage collectable
30 // objects. Our implementation is based on John Ellis' proposal in:
31 // ``Safe, Eifficient Garbage Collection for C++''
32 //////////////////////////////////////////////////////////////////////////////
34 #include <AD/gc/gc.h> // Garbage collection base class
35 #include <AD/gc/gcobject.h> // Collectable object base class
37 //////////////////////////////////////////////////////////////////////////////
38 // Forward template declaration
39 //////////////////////////////////////////////////////////////////////////////
40 template <class T
> class WeakPointer
;
42 //////////////////////////////////////////////////////////////////////////////
43 // Class to manage all the weakpointers into the collectable heap.
44 //////////////////////////////////////////////////////////////////////////////
45 class WeakPointerManager
{
47 WeakPointerManager(const WeakPointerManager
&); // no copy constructor
48 void operator = (const WeakPointerManager
&); // no assignment
51 ///////////////////////////////////////////////////////////////////////////
52 // Some type definitions
53 ///////////////////////////////////////////////////////////////////////////
54 typedef long WP_TimeStamp
; // weak pointer timestamp
55 typedef long WP_Index
; // weak pointer index
56 struct WP_Entry
{ // weak pointer entry in table.
57 GCObject
* object
; // actual collectable object
58 WP_TimeStamp timestamp
; // timestamp of this entry
59 WP_Entry
* next
; // next free entry
64 ///////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////
67 static WP_TimeStamp wp_timestamp
; // Next available timestamp
68 static WP_Entry
* wp_table
; // A table of weakpointers
69 static WP_Entry
* wp_next_free
; // Next free entry
70 static void * wp_table_core
; // The actual table
71 static size_t wp_table_capacity
; // Capacity of current table
72 static size_t wp_table_size
; // Number of entries
76 ///////////////////////////////////////////////////////////////////////////
77 // Constructor and destructor
78 ///////////////////////////////////////////////////////////////////////////
80 ~WeakPointerManager();
82 ///////////////////////////////////////////////////////////////////////////
84 ///////////////////////////////////////////////////////////////////////////
85 inline static int size() { return wp_table_size
; }
86 inline static int capacity() { return wp_table_capacity
; }
88 ///////////////////////////////////////////////////////////////////////////
90 // (1) add a new pointer into the weakpointer table,
91 // (2) expand the table, and
92 // (3) scavenge dead entries in the table.
93 ///////////////////////////////////////////////////////////////////////////
94 static WP_Index
add_pointer(GCObject
*,WP_TimeStamp
&);
95 static void grow_wp_table();
96 static void scavenge_wp_table(GC
*);
98 ///////////////////////////////////////////////////////////////////////////
99 // Method to index into the wp table
100 ///////////////////////////////////////////////////////////////////////////
101 inline static WP_Entry
* get(WP_Index i
) { return wp_table
+ i
; }
104 //////////////////////////////////////////////////////////////////////////////
105 // Okay, this is the weakpointer template that the user actual uses.
106 //////////////////////////////////////////////////////////////////////////////
110 ////////////////////////////////////////////////////////////////////////
111 // Import some types from the manager class
112 ////////////////////////////////////////////////////////////////////////
113 typedef WeakPointerManager::WP_TimeStamp WP_TimeStamp
;
114 typedef WeakPointerManager::WP_Index WP_Index
;
115 typedef WeakPointerManager::WP_Entry WP_Entry
;
118 ////////////////////////////////////////////////////////////////////////
119 // A weakpointer is actually stored as an index + a timestamp.
120 ////////////////////////////////////////////////////////////////////////
122 WP_Index _index
; // index into with weakpointer table
123 WP_TimeStamp _timestamp
; // timestamp of object
126 ////////////////////////////////////////////////////////////////////////
127 // Constructor and destructor
128 ////////////////////////////////////////////////////////////////////////
130 : _index(0), _timestamp(0) {}
131 inline WeakPointer(const WeakPointer
<T
>& wp
)
132 : _index(wp
._index
), _timestamp(wp
._timestamp
) {}
133 inline WeakPointer(T
* ptr
)
134 { _index
= WeakPointerManager::add_pointer(ptr
,_timestamp
); }
136 ////////////////////////////////////////////////////////////////////////
137 // Retrieve the pointer.
138 ////////////////////////////////////////////////////////////////////////
139 inline const GCObject
* _get_pointer() const
140 { return (WeakPointerManager::get(_index
)->timestamp
== _timestamp
)
141 ? (WeakPointerManager::get(_index
)->object
) : 0;
144 ////////////////////////////////////////////////////////////////////////
146 ////////////////////////////////////////////////////////////////////////
147 inline WeakPointer
<T
>& operator = (const WeakPointer
<T
>& wp
)
148 { _index
= wp
._index
; _timestamp
= wp
._timestamp
; return *this; }
149 inline WeakPointer
<T
>& operator = (T
* ptr
)
150 { _index
= WeakPointerManager::add_pointer(ptr
,_timestamp
);
154 ////////////////////////////////////////////////////////////////////////
155 // Test whether the weakpointer is dead.
156 ////////////////////////////////////////////////////////////////////////
157 inline Bool
is_null() const { return _get_pointer() == 0; }
159 ////////////////////////////////////////////////////////////////////////
161 ////////////////////////////////////////////////////////////////////////
162 inline operator const T
* () const { return (const T
*)_get_pointer(); }
163 inline operator T
* () { return (T
*)_get_pointer(); }
165 ////////////////////////////////////////////////////////////////////////
166 // Dereferencing with -> and *
167 ////////////////////////////////////////////////////////////////////////
168 inline const T
* operator -> () const { return (const T
*)_get_pointer();}
169 inline T
* operator -> () { return (T
*)_get_pointer(); }
170 inline const T
& operator * () const { return *(const T
*)_get_pointer();}
171 inline T
& operator * () { return *(T
*)_get_pointer(); }