]> www.ginac.de Git - cln.git/blob - include/cl_object.h
Initial revision
[cln.git] / include / cl_object.h
1 // General object definitions: pointers, reference counting, garbage collection.
2
3 #ifndef _CL_OBJECT_H
4 #define _CL_OBJECT_H
5
6 #include "cl_types.h"
7 #include "cl_modules.h"
8 #include <stdlib.h>
9
10 // We don't have to deal with circular structures, so normal reference counting
11 // is sufficient. Is also has the advantage of being mostly non-interrupting.
12
13
14 // An object is either a pointer to heap allocated data
15 //              or immediate data.
16
17 // It is possible to distinguish these because pointers are aligned.
18 // cl_uint_alignment is the guaranteed alignment of a `void*' or `long'
19 // in memory. Must be > 1.
20 #if defined(__m68k__)
21   #define cl_word_alignment  2
22 #endif
23 #if defined(__i386__) || defined(__mips__) || defined(__sparc__) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__)
24   #define cl_word_alignment  4
25 #endif
26 #if defined(__alpha__) || defined(__mips64__) || defined(__sparc64__)
27   #define cl_word_alignment  8
28 #endif
29 #if !defined(cl_word_alignment)
30   #error "Define cl_word_alignment for your CPU!"
31 #endif
32
33
34 // Four basic classes are introduced:
35 //
36 //   gcobject      rcobject
37 //
38 //   gcpointer     rcpointer
39 //
40 // `gcobject' = garbage collectible object (pointer or immediate),
41 // `gcpointer' = garbage collectible pointer,
42 // `rcobject' = reference counted object (pointer or immediate),
43 // `rcpointer' = reference counted pointer.
44 //
45 // "garbage collectible" means that a reference count is maintained, and
46 // when the reference count drops to 0, the object is freed. This is useful
47 // for all kind of short- or long-lived objects.
48 // "reference counted" means that a reference count is maintained, which
49 // cannot drop to 0. This is useful for objects which are registered in a
50 // global cache table, in order to know which objects can be thrown away
51 // when the cache is cleaned. (If the cache were never cleaned, its objects
52 // would never be freed, and we could get away with normal C pointers.)
53 //
54 // It is permissible to treat a `rcobject' as a `gcobject', and a `rcpointer'
55 // as a `gcpointer', but this just increases the destructor and copy-constructor
56 // overhead.
57 // It is also permissible to treat a `gcpointer' as a `gcobject', and a
58 // `rcpointer' as a `rcobject', but this just increases the destructor and
59 // copy-constructor overhead.
60
61
62 // Immediate data is a word, as wide as a pointer.
63 typedef sintP  cl_sint;
64 typedef uintP  cl_uint;  // This ought to be called `cl_word'.
65 #define cl_word_size intPsize
66 // NB: (cl_word_size==64) implies defined(HAVE_FAST_LONGLONG)
67 #if (cl_word_size==64)
68   #define CL_WIDE_POINTERS
69 #endif
70
71 // Distinguish immediate data from pointers.
72 inline cl_boolean cl_pointer_p (cl_uint word)
73 {
74         return (cl_boolean)((word & (cl_word_alignment-1)) == 0);
75 }
76 inline cl_boolean cl_immediate_p (cl_uint word)
77 {
78         return (cl_boolean)((word & (cl_word_alignment-1)) != 0);
79 }
80
81 // Immediate data: Fixnum, Short Float, maybe Single Float.
82 // They have type tags.
83 //   |...............................|......|
84 //               cl_value             cl_tag
85
86 // Number of bits reserved for tagging information:
87 #if (cl_word_alignment <= 4)
88   #define cl_tag_len    2
89 #else
90   #define cl_tag_len    3
91 #endif
92 #define cl_tag_shift    0
93 #if (cl_word_size == 64)
94   #define cl_value_shift  32
95 #else
96   #define cl_value_shift  (cl_tag_len+cl_tag_shift)
97 #endif
98 #define cl_value_len    (cl_word_size - cl_value_shift)
99 #define cl_tag_mask     (((1UL << cl_tag_len) - 1) << cl_tag_shift)
100 #define cl_value_mask   (((1UL << cl_value_len) - 1) << cl_value_shift)
101
102 // Return the tag of a word.
103 inline cl_uint cl_tag (cl_uint word)
104 {
105         return (word & cl_tag_mask) >> cl_tag_shift;
106 }
107
108 // Return the value (unsigned) of a word.
109 inline cl_uint cl_value (cl_uint word)
110 {
111         // This assumes cl_value_shift + cl_value_len == cl_word_size.
112         return word >> cl_value_shift;
113 }
114
115 // Return a word, combining a value and a tag.
116 inline cl_uint cl_combine (cl_uint tag, cl_uint value)
117 {
118         return (value << cl_value_shift) + (tag << cl_tag_shift);
119 }
120 inline cl_uint cl_combine (cl_uint tag, cl_sint value)
121 {
122         // This assumes cl_value_shift + cl_value_len == cl_word_size.
123         return (value << cl_value_shift) + (tag << cl_tag_shift);
124 }
125 // Keep the compiler happy.
126 inline cl_uint cl_combine (cl_uint tag, unsigned int value)
127 { return cl_combine(tag,(cl_uint)value); }
128 inline cl_uint cl_combine (cl_uint tag, int value)
129 { return cl_combine(tag,(cl_sint)value); }
130
131 // Definition of the tags.
132 #if !defined(CL_WIDE_POINTERS)
133   #if (cl_word_alignment == 2)
134     #define cl_FN_tag   1
135     #define cl_SF_tag   3       // must satisfy the cl_immediate_p predicate!
136   #endif
137   #if (cl_word_alignment == 4)
138     #define cl_FN_tag   1
139     #define cl_SF_tag   2
140   #endif
141 #else // CL_WIDE_POINTERS
142   // Single Floats are immediate as well.
143   #define cl_FN_tag     1
144   #define cl_SF_tag     2
145   #define cl_FF_tag     3
146 #endif
147
148 // Corresponding classes.
149 extern const struct cl_class * cl_immediate_classes [1<<cl_tag_len];
150
151
152 // Heap allocated data contains a header, for two purposes:
153 // - dynamic typing,
154 // - reference count (a portable alternative to garbage collection,
155 //   or the basis for a portable and interoperable garbage collection).
156 struct cl_heap {
157         int refcount;                   // reference count
158         const struct cl_class * type;   // type tag
159 };
160
161 // Function to destroy the contents of a heap object.
162 typedef void (*cl_heap_destructor_function) (cl_heap* pointer);
163 // Flags, to be ORed together.
164 #define cl_class_flags_subclass_complex   1  // all instances belong to cl_N
165 #define cl_class_flags_subclass_real      2  // all instances belong to cl_R
166 #define cl_class_flags_subclass_float     4  // all instances belong to cl_F
167 #define cl_class_flags_subclass_rational  8  // all instances belong to cl_RA
168 #define cl_class_flags_number_ring       16  // all instances are rings whose
169                                              // elements belong to cl_number
170 // Function to print an object for debugging, to cl_stderr.
171 typedef void (*cl_heap_dprint_function) (cl_heap* pointer);
172
173 struct cl_class {
174         cl_heap_destructor_function destruct;
175         int flags;
176         cl_heap_dprint_function dprint;
177 };
178
179 // Free an object on heap.
180 extern void cl_free_heap_object (cl_heap* pointer);
181
182 // Debugging support for dynamic typing: Register a debugging print function.
183 #define cl_register_type_printer(type,printer)  \
184   { extern cl_class type; type.dprint = (printer); }
185
186
187 // cl_private_thing: An immediate value or a pointer into the heap.
188 // This must be as wide as a `cl_uint'.
189 // (Actually, this ought to be a  union { void*; cl_uint; }, but using
190 // a pointer type generates better code.)
191 // Never throw away a cl_private_thing, or reference counts will be wrong!
192 typedef struct cl_anything * cl_private_thing;
193
194 // Increment the reference count.
195 inline void cl_inc_pointer_refcount (cl_heap* pointer)
196 {
197         pointer->refcount++;
198 }
199
200 // Decrement the reference count of a garbage collected pointer.
201 inline void cl_gc_dec_pointer_refcount (cl_heap* pointer)
202 {
203         if (--pointer->refcount == 0)
204                 cl_free_heap_object(pointer);
205 }
206 // Decrement the reference count of a reference counted pointer.
207 inline void cl_rc_dec_pointer_refcount (cl_heap* pointer)
208 {
209         --pointer->refcount;
210 }
211
212 // Increment the reference count.
213 // This must be a macro, not an inline function, because pointer_p() and
214 // inc_pointer_refcount() are non-virtual member functions, so that the
215 // compiler can optimize it.
216 #define cl_inc_refcount(x)  \
217         if ((x).pointer_p())                                    \
218                 (x).inc_pointer_refcount();                     \
219
220 // Decrement the reference count.
221 // This must be a macro, not an inline function, because pointer_p() and
222 // dec_pointer_refcount() are non-virtual member functions, so that the
223 // compiler can optimize it.
224 #define cl_dec_refcount(x)  \
225         if ((x).pointer_p())                                    \
226                 (x).dec_pointer_refcount();                     \
227
228 // The declaration of a copy constructor.
229 // Restriction: The base class's default constructor must do nothing or
230 // initialize `pointer' to a constant expression.
231 #define CL_DEFINE_COPY_CONSTRUCTOR1(_class_)                    \
232         _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_class_)
233 #define _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_classname_)       \
234 inline _class_::_classname_ (const _class_& x)                  \
235 {                                                               \
236         cl_uint x_word = x.word;                                \
237         cl_inc_refcount(x);                                     \
238         word = x_word;                                          \
239 }
240
241 // The declaration of a copy constructor.
242 // Restriction: The base class must have the usual `cl_private_thing'
243 // constructor. Drawback: The base class must be known here.
244 #define CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_baseclass_)                \
245         _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_class_,_baseclass_)
246 #define _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_classname_,_baseclass_) \
247 inline _class_::_classname_ (const _class_& x)                  \
248         : _baseclass_ (as_cl_private_thing(x)) {}
249
250 // The declaration of an assignment operator.
251 #define CL_DEFINE_ASSIGNMENT_OPERATOR(dest_class,src_class)     \
252 inline dest_class& dest_class::operator= (const src_class& x)   \
253 {                                                               \
254         /* Be careful, we might be assigning x to itself. */    \
255         cl_uint x_word = x.word;                                \
256         cl_inc_refcount(x);                                     \
257         cl_dec_refcount(*this);                                 \
258         word = x_word;                                          \
259         return *this;                                           \
260 }
261
262 // We have a small problem with destructors: The specialized destructor
263 // of a leaf class such as `cl_SF' should be more efficient than the
264 // general destructor for `cl_N'. Since (by C++ specs) destructing a cl_SF
265 // would run the destructors for cl_SF, cl_F, cl_R, cl_N (in that order),
266 // and in the last step the compiler does not know any more that the object
267 // actually is a cl_SF, there is no way to optimize the destructor!
268 // ("progn-reversed" method combination is evil.)
269 // And if we define "mirror"/"shadow" classes with no destructors (such
270 // that `cl_F' inherits from `cl_F_no_destructor' buts adds a destructor)
271 // then we need to add explicit conversion operators cl_SF -> cl_F -> cl_R ...,
272 // with the effect that calling an overloaded function like `as_cl_F'
273 // (which has two signatures `as_cl_F(cl_number)' and `as_cl_F(cl_F)')
274 // with a cl_SF argument gives an "call of overloaded function is ambiguous"
275 // error.
276 // There is no help: If we want overloaded functions to be callable in a way
277 // that makes sense, `cl_SF' has to be a subclass of `cl_F', and then the
278 // destructor of `cl_SF' will do at least as much computation as the `cl_F'
279 // destructor. Praise C++ ! :-((
280 // (Even making `pointer_p()' a virtual function would not help.)
281
282
283 // This is obnoxious.
284 template <class key1_type, class value_type> struct cl_htentry1;
285
286 // The four concrete classes of all objects.
287
288 class cl_gcobject {
289 public: /* ugh */
290         union {
291                 void*   pointer;
292                 cl_heap* heappointer;
293                 cl_uint word;
294         };
295 public:
296 // Default constructor. (Used for objects with no initializer.)
297         cl_gcobject ();
298 // Destructor. (Used when a variable goes out of scope.)
299         ~cl_gcobject ();
300 // Copy constructor.
301         cl_gcobject (const cl_gcobject&);
302 // Assignment operator.
303         cl_gcobject& operator= (const cl_gcobject&);
304 // Distinguish immediate data from pointer.
305         cl_boolean pointer_p() const
306                 { return cl_pointer_p(word); }
307 // Reference counting.
308         void inc_pointer_refcount () const
309                 { cl_inc_pointer_refcount(heappointer); }
310         void dec_pointer_refcount () const
311                 { cl_gc_dec_pointer_refcount(heappointer); }
312 // Return the type tag of an immediate number.
313         cl_uint nonpointer_tag () const
314                 { return cl_tag(word); }
315 // Return the type tag of a heap-allocated number.
316         const cl_class * pointer_type () const
317                 { return heappointer->type; }
318 // Private pointer manipulations.
319         cl_private_thing _as_cl_private_thing () const;
320 // Private constructor.
321         cl_gcobject (cl_private_thing p)
322                 #if !(defined(__alpha__) && !defined(__GNUC__))
323                 : pointer (p) {}
324                 #else
325                 { pointer = p; }
326                 #endif
327 // Debugging output.
328         void debug_print () const;
329 // Ability to place an object at a given address.
330         void* operator new (size_t size, cl_gcobject* ptr) { (void)size; return ptr; }
331         void* operator new (size_t size) { return ::operator new (size); }
332 };
333 inline cl_gcobject::cl_gcobject () {}
334 inline cl_gcobject::~cl_gcobject () { cl_dec_refcount(*this); }
335 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcobject)
336 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcobject,cl_gcobject)
337
338 class cl_gcpointer {
339 public: /* ugh */
340         union {
341                 void*   pointer;
342                 cl_heap* heappointer;
343                 cl_uint word;
344         };
345 public:
346 // Default constructor. (Used for objects with no initializer.)
347         cl_gcpointer ();
348 // Destructor. (Used when a variable goes out of scope.)
349         ~cl_gcpointer ();
350 // Copy constructor.
351         cl_gcpointer (const cl_gcpointer&);
352 // Assignment operator.
353         cl_gcpointer& operator= (const cl_gcpointer&);
354 // Distinguish immediate data from pointer.
355         cl_boolean pointer_p() const
356                 { return cl_true; }
357 // Reference counting.
358         void inc_pointer_refcount () const
359                 { cl_inc_pointer_refcount(heappointer); }
360         void dec_pointer_refcount () const
361                 { cl_gc_dec_pointer_refcount(heappointer); }
362 // Return the type tag of an immediate number.
363         cl_uint nonpointer_tag () const
364                 { return cl_tag(word); }
365 // Return the type tag of a heap-allocated number.
366         const cl_class * pointer_type () const
367                 { return heappointer->type; }
368 // Private pointer manipulations.
369         cl_private_thing _as_cl_private_thing () const;
370 // Private constructor.
371         cl_gcpointer (cl_private_thing p)
372                 #if !(defined(__alpha__) && !defined(__GNUC__))
373                 : pointer (p) {}
374                 #else
375                 { pointer = p; }
376                 #endif
377 // Debugging output.
378         void debug_print () const;
379 // Ability to place an object at a given address.
380         void* operator new (size_t size, cl_gcpointer* ptr) { (void)size; return ptr; }
381         void* operator new (size_t size) { return ::operator new (size); }
382 };
383 inline cl_gcpointer::cl_gcpointer () {}
384 inline cl_gcpointer::~cl_gcpointer () { cl_dec_refcount(*this); }
385 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcpointer)
386 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcpointer,cl_gcpointer)
387
388 class cl_rcobject {
389 public: /* ugh */
390         union {
391                 void*   pointer;
392                 cl_heap* heappointer;
393                 cl_uint word;
394         };
395 public:
396 // Default constructor. (Used for objects with no initializer.)
397         cl_rcobject ();
398 // Destructor. (Used when a variable goes out of scope.)
399         ~cl_rcobject ();
400 // Copy constructor.
401         cl_rcobject (const cl_rcobject&);
402 // Assignment operator.
403         cl_rcobject& operator= (const cl_rcobject&);
404 // Distinguish immediate data from pointer.
405         cl_boolean pointer_p() const
406                 { return cl_pointer_p(word); }
407 // Reference counting.
408         void inc_pointer_refcount () const
409                 { cl_inc_pointer_refcount(heappointer); }
410         void dec_pointer_refcount () const
411                 { cl_rc_dec_pointer_refcount(heappointer); }
412 // Return the type tag of an immediate number.
413         cl_uint nonpointer_tag () const
414                 { return cl_tag(word); }
415 // Return the type tag of a heap-allocated number.
416         const cl_class * pointer_type () const
417                 { return heappointer->type; }
418 // Private pointer manipulations.
419         cl_private_thing _as_cl_private_thing () const;
420 // Private constructor.
421         cl_rcobject (cl_private_thing p)
422                 #if !(defined(__alpha__) && !defined(__GNUC__))
423                 : pointer (p) {}
424                 #else
425                 { pointer = p; }
426                 #endif
427 // Debugging output.
428         void debug_print () const;
429 // Ability to place an object at a given address.
430         void* operator new (size_t size, cl_rcobject* ptr) { (void)size; return ptr; }
431         void* operator new (size_t size) { return ::operator new (size); }
432 };
433 inline cl_rcobject::cl_rcobject () {}
434 inline cl_rcobject::~cl_rcobject () { cl_dec_refcount(*this); }
435 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcobject)
436 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcobject,cl_rcobject)
437
438 class cl_rcpointer {
439 public: /* ugh */
440         union {
441                 void*   pointer;
442                 cl_heap* heappointer;
443                 cl_uint word;
444         };
445 public:
446 // Default constructor. (Used for objects with no initializer.)
447         cl_rcpointer ();
448 // Destructor. (Used when a variable goes out of scope.)
449         ~cl_rcpointer ();
450 // Copy constructor.
451         cl_rcpointer (const cl_rcpointer&);
452 // Assignment operator.
453         cl_rcpointer& operator= (const cl_rcpointer&);
454 // Distinguish immediate data from pointer.
455         cl_boolean pointer_p() const
456                 { return cl_true; }
457 // Reference counting.
458         void inc_pointer_refcount () const
459                 { cl_inc_pointer_refcount(heappointer); }
460         void dec_pointer_refcount () const
461                 { cl_rc_dec_pointer_refcount(heappointer); }
462 // Return the type tag of an immediate number.
463         cl_uint nonpointer_tag () const
464                 { return cl_tag(word); }
465 // Return the type tag of a heap-allocated number.
466         const cl_class * pointer_type () const
467                 { return heappointer->type; }
468 // Private pointer manipulations.
469         cl_private_thing _as_cl_private_thing () const;
470 // Private constructor.
471         cl_rcpointer (cl_private_thing p)
472                 #if !(defined(__alpha__) && !defined(__GNUC__))
473                 : pointer (p) {}
474                 #else
475                 { pointer = p; }
476                 #endif
477 // Debugging output.
478         void debug_print () const;
479 // Ability to place an object at a given address.
480         void* operator new (size_t size, cl_rcpointer* ptr) { (void)size; return ptr; }
481         void* operator new (size_t size) { return ::operator new (size); }
482 };
483 inline cl_rcpointer::cl_rcpointer () {}
484 inline cl_rcpointer::~cl_rcpointer () { cl_dec_refcount(*this); }
485 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcpointer)
486 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcpointer,cl_rcpointer)
487
488 // Private pointer manipulations.
489
490 inline cl_private_thing cl_gcobject::_as_cl_private_thing () const
491 {
492         cl_private_thing p = (cl_private_thing) pointer;
493         cl_inc_refcount(*this);
494         return p;
495 }
496 inline cl_private_thing as_cl_private_thing (const cl_gcobject& x)
497 {
498         return x._as_cl_private_thing();
499 }
500
501 inline cl_private_thing cl_gcpointer::_as_cl_private_thing () const
502 {
503         cl_private_thing p = (cl_private_thing) pointer;
504         cl_inc_refcount(*this);
505         return p;
506 }
507 inline cl_private_thing as_cl_private_thing (const cl_gcpointer& x)
508 {
509         return x._as_cl_private_thing();
510 }
511
512 inline cl_private_thing cl_rcobject::_as_cl_private_thing () const
513 {
514         cl_private_thing p = (cl_private_thing) pointer;
515         cl_inc_refcount(*this);
516         return p;
517 }
518 inline cl_private_thing as_cl_private_thing (const cl_rcobject& x)
519 {
520         return x._as_cl_private_thing();
521 }
522
523 inline cl_private_thing cl_rcpointer::_as_cl_private_thing () const
524 {
525         cl_private_thing p = (cl_private_thing) pointer;
526         cl_inc_refcount(*this);
527         return p;
528 }
529 inline cl_private_thing as_cl_private_thing (const cl_rcpointer& x)
530 {
531         return x._as_cl_private_thing();
532 }
533
534 // Note: When we define a function that returns a class object by value,
535 // we normally return it as const value. The declarations
536 //            T func (...);                    (A)
537 // and
538 //            const T func (...);              (B)
539 // behave identically and generate identical code, except that the code
540 //            func(...) = foo;
541 // compiles fine with (A) but is an error (and yields a warning) with (B).
542 // We want this warning.
543
544 // Define a conversion operator from one object to another object of the
545 // same size.
546 #if (defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ <= 7)) // workaround g++ bug
547   #define CL_DEFINE_CONVERTER(target_class)  \
548     operator target_class () const                                      \
549     {                                                                   \
550       if (sizeof(*this) != sizeof(target_class)) cl_abort();            \
551       return * (const target_class *) (void*) this;                     \
552     }
553 #else
554   #define CL_DEFINE_CONVERTER(target_class)  \
555     operator const target_class & () const                              \
556     {                                                                   \
557       if (sizeof(*this) != sizeof(target_class)) cl_abort();            \
558       return * (const target_class *) (void*) this;                     \
559     }
560 #endif
561
562 #endif /* _CL_OBJECT_H */