source: src/Common/GC.h @ 97397a26

new-env
Last change on this file since 97397a26 was 7a37f25, checked in by Aaron Moss <a3moss@…>, 6 years ago

Fix bug with static root traces

  • Property mode set to 100644
File size: 3.9 KB
RevLine 
[68f9c43]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
[2efe4b8]18#include <cassert>
[68f9c43]19#include <vector>
20
21class GC_Object;
[bd06384]22class BaseSyntaxNode;
[2efe4b8]23class GC_Guard;
[68f9c43]24
25/// Manually traced and called garbage collector
26class GC {
27        friend class GcTracer;
[2efe4b8]28        friend class GC_Guard;
29
30        /// Collects the youngest generation, placing survivors in previous generation.
31        /// Young generation objects cannot be kept alive by pointers from older generation.
32        /// Older generation is used for subsequent new objects.
33        void collect_young();
[68f9c43]34public:
35        /// Gets singleton GC instance
36        static GC& get();
37
38        /// Traces a traceable object
[24de7b1]39        const GC& operator<< (const GC_Object*) const;
[68f9c43]40
41        /// Adds a new object to garbage collection
42        void register_object(GC_Object*);
43
[bd06384]44        /// Adds an object to the set of static roots
45        void register_static_root(BaseSyntaxNode*);
46
[04570c7]47        /// Start new generation for subsequent new objects
[2efe4b8]48        GC_Guard new_generation();
[68f9c43]49
[bd06384]50        /// Traces all static roots
51        void trace_static_roots();
52
[04570c7]53        /// Collects oldest generation; use oldest generation afterward.
54        /// Error if currently using younger generation
[68f9c43]55        void collect();
56
57        /// Collects all contained objects
58        ~GC();
59
60private:
61        GC();
62
[bd06384]63        using Generation = std::vector<GC_Object*>;
[04570c7]64        std::vector<Generation> gens;  ///< Set of generations; always at least one
[68f9c43]65
[bd06384]66        using StaticRoots = std::vector<BaseSyntaxNode*>;
[04570c7]67        StaticRoots static_roots;      ///< Set of static-lifetime roots
68
69        bool mark;                     ///< The current collection's mark bit
70        unsigned g;                    ///< The current number generation in use
[68f9c43]71};
72
[2efe4b8]73/// Cleanup object for young generation
74class GC_Guard {
75        friend class GC;
76
77        GC& gc;      ///< GC associated with
78        unsigned g;  ///< Generation constructed for
79
80        GC_Guard( GC& gc, unsigned g ) : gc(gc), g(g) {}
81
82public:
83        ~GC_Guard() {
84                assert( gc.g == g && "collecting current generation" );
85                gc.collect_young();
86        }
87};
88
[68f9c43]89/// Use young generation until next collection
[2efe4b8]90inline GC_Guard new_generation() { return GC::get().new_generation(); }
[68f9c43]91
[bfc7811]92// /// no-op default trace
93// template<typename T>
94// inline const GC& operator<< (const GC& gc, const T& x) { return gc; }
[68f9c43]95
[8d7bef2]96inline void traceAll(const GC&) {}
[68f9c43]97
98/// Marks all arguments as live in current generation
99template<typename T, typename... Args>
100inline void traceAll(const GC& gc, T& x, Args&... xs) {
101        gc << x;
102        traceAll(gc, xs...);
103}
104
[2efe4b8]105/// Traces roots without collecting
[68f9c43]106template<typename... Args>
[2efe4b8]107inline void trace(Args&... roots) {
[68f9c43]108        GC& gc = GC::get();
109        traceAll(gc, roots...);
110}
111
[2efe4b8]112/// Traces roots and collects other elements; should not be any young generations live
[68f9c43]113template<typename... Args>
114inline void collect(Args&... roots) {
115        GC& gc = GC::get();
116        traceAll(gc, roots...);
117        gc.collect();
118}
119
[bd06384]120/// Makes a new expression as a static root
121template<typename T, typename... Args>
122inline T* new_static_root( Args&&... args ) {
123        T* root = new T( std::forward<Args>(args)... );
124        GC::get().register_static_root( root );
125        return root;
126}
127
[24de7b1]128/// Class that is managed by the GC
129class GC_Object {
[68f9c43]130        friend class GC;
131protected:
[8d7bef2]132        mutable bool mark;
133
[24de7b1]134        // Override default constructors to ensure clones are registered and properly marked
135        GC_Object();
[68f9c43]136
[24de7b1]137        GC_Object(const GC_Object&);
138
139        GC_Object(GC_Object&&);
140
141        GC_Object& operator= (const GC_Object&) { /* do not assign mark */ return *this; }
142
143        GC_Object& operator= (GC_Object&&) { /* do not assign mark */ return *this; }
144
145        // Ensure subclasses can be deleted by garbage collector
[68f9c43]146        virtual ~GC_Object() {}
[24de7b1]147
148        /// override to trace any child objects
149        virtual void trace(const GC&) const {}
[68f9c43]150};
151
152// Local Variables: //
153// tab-width: 4 //
154// mode: c++ //
155// compile-command: "make install" //
156// End: //
Note: See TracBrowser for help on using the repository browser.