1 | //
|
---|
2 | // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
|
---|
3 | //
|
---|
4 | // The contents of this file are covered under the licence agreement in the
|
---|
5 | // file "LICENCE" distributed with Cforall.
|
---|
6 | //
|
---|
7 | // GC.h --
|
---|
8 | //
|
---|
9 | // Author : Aaron B. Moss
|
---|
10 | // Created On : Thu Mar 15 14:47:00 2018
|
---|
11 | // Last Modified By : Aaron B. Moss
|
---|
12 | // Last Modified On : Thu Mar 15 14:47:00 2018
|
---|
13 | // Update Count : 1
|
---|
14 | //
|
---|
15 |
|
---|
16 | #pragma once
|
---|
17 |
|
---|
18 | #include <vector>
|
---|
19 |
|
---|
20 | class GC_Traceable;
|
---|
21 | class GC_Object;
|
---|
22 |
|
---|
23 | /// Manually traced and called garbage collector
|
---|
24 | class GC {
|
---|
25 | friend class GcTracer;
|
---|
26 | public:
|
---|
27 | /// Gets singleton GC instance
|
---|
28 | static GC& get();
|
---|
29 |
|
---|
30 | /// Traces a traceable object
|
---|
31 | const GC& operator<< (const GC_Traceable*) const;
|
---|
32 |
|
---|
33 | /// Adds a new object to garbage collection
|
---|
34 | void register_object(GC_Object*);
|
---|
35 |
|
---|
36 | /// Use young generation for subsequent new objects
|
---|
37 | void new_generation();
|
---|
38 |
|
---|
39 | /// Collects the young generation, placing survivors in old generation.
|
---|
40 | /// Old generation is used for subsequent new objects.
|
---|
41 | void collect_young();
|
---|
42 |
|
---|
43 | /// Collects all memory; use old generation afterward.
|
---|
44 | void collect();
|
---|
45 |
|
---|
46 | /// Collects all contained objects
|
---|
47 | ~GC();
|
---|
48 |
|
---|
49 | private:
|
---|
50 | GC();
|
---|
51 |
|
---|
52 | /// The current collection's mark bit
|
---|
53 | bool mark;
|
---|
54 |
|
---|
55 | typedef std::vector<class GC_Object*> Generation;
|
---|
56 | Generation old;
|
---|
57 | Generation young;
|
---|
58 | bool using_young;
|
---|
59 | };
|
---|
60 |
|
---|
61 | /// Use young generation until next collection
|
---|
62 | inline void new_generation() { GC::get().new_generation(); }
|
---|
63 |
|
---|
64 | /// no-op default trace
|
---|
65 | template<typename T>
|
---|
66 | inline const GC& operator<< (const GC& gc, const T& x) { return gc; }
|
---|
67 |
|
---|
68 | inline void traceAll(const GC& gc) {}
|
---|
69 |
|
---|
70 | /// Marks all arguments as live in current generation
|
---|
71 | template<typename T, typename... Args>
|
---|
72 | inline void traceAll(const GC& gc, T& x, Args&... xs) {
|
---|
73 | gc << x;
|
---|
74 | traceAll(gc, xs...);
|
---|
75 | }
|
---|
76 |
|
---|
77 | /// Traces young-generation roots and does a young collection
|
---|
78 | template<typename... Args>
|
---|
79 | inline void collect_young(Args&... roots) {
|
---|
80 | GC& gc = GC::get();
|
---|
81 | traceAll(gc, roots...);
|
---|
82 | gc.collect_young();
|
---|
83 | }
|
---|
84 |
|
---|
85 | /// Traces roots and collects other elements
|
---|
86 | template<typename... Args>
|
---|
87 | inline void collect(Args&... roots) {
|
---|
88 | GC& gc = GC::get();
|
---|
89 | traceAll(gc, roots...);
|
---|
90 | gc.collect();
|
---|
91 | }
|
---|
92 |
|
---|
93 | /// Class that is traced by the GC, but not managed by it
|
---|
94 | class GC_Traceable {
|
---|
95 | friend class GC;
|
---|
96 | friend class GcTracer;
|
---|
97 |
|
---|
98 | mutable bool mark;
|
---|
99 | protected:
|
---|
100 | /// override to trace any child objects
|
---|
101 | virtual void trace(const GC& gc) const {}
|
---|
102 | };
|
---|
103 |
|
---|
104 | /// Class that is managed by the GC
|
---|
105 | class GC_Object : public GC_Traceable {
|
---|
106 | friend class GC;
|
---|
107 | protected:
|
---|
108 | virtual ~GC_Object() {}
|
---|
109 | public:
|
---|
110 | GC_Object();
|
---|
111 | };
|
---|
112 |
|
---|
113 | // Local Variables: //
|
---|
114 | // tab-width: 4 //
|
---|
115 | // mode: c++ //
|
---|
116 | // compile-command: "make install" //
|
---|
117 | // End: //
|
---|