// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // GC.h -- // // Author : Aaron B. Moss // Created On : Thu Mar 15 14:47:00 2018 // Last Modified By : Aaron B. Moss // Last Modified On : Thu Mar 15 14:47:00 2018 // Update Count : 1 // #pragma once #include class GC_Traceable; class GC_Object; class BaseSyntaxNode; /// Manually traced and called garbage collector class GC { friend class GcTracer; public: /// Gets singleton GC instance static GC& get(); /// Traces a traceable object const GC& operator<< (const GC_Traceable*) const; /// Adds a new object to garbage collection void register_object(GC_Object*); /// Adds an object to the set of static roots void register_static_root(BaseSyntaxNode*); /// Start new generation for subsequent new objects void new_generation(); /// Traces all static roots void trace_static_roots(); /// Collects the youngest generation, placing survivors in previous generation. /// Young generation objects cannot be kept alive by pointers from older generation. /// Older generation is used for subsequent new objects. void collect_young(); /// Collects oldest generation; use oldest generation afterward. /// Error if currently using younger generation void collect(); /// Collects all contained objects ~GC(); private: GC(); using Generation = std::vector; std::vector gens; ///< Set of generations; always at least one using StaticRoots = std::vector; StaticRoots static_roots; ///< Set of static-lifetime roots bool mark; ///< The current collection's mark bit unsigned g; ///< The current number generation in use }; /// Use young generation until next collection inline void new_generation() { GC::get().new_generation(); } // /// no-op default trace // template // inline const GC& operator<< (const GC& gc, const T& x) { return gc; } inline void traceAll(const GC&) {} /// Marks all arguments as live in current generation template inline void traceAll(const GC& gc, T& x, Args&... xs) { gc << x; traceAll(gc, xs...); } /// Traces young-generation roots and does a young collection template inline void collect_young(Args&... roots) { GC& gc = GC::get(); traceAll(gc, roots...); gc.trace_static_roots(); gc.collect_young(); } /// Traces roots and collects other elements template inline void collect(Args&... roots) { GC& gc = GC::get(); traceAll(gc, roots...); gc.trace_static_roots(); gc.collect(); } /// Makes a new expression as a static root template inline T* new_static_root( Args&&... args ) { T* root = new T( std::forward(args)... ); GC::get().register_static_root( root ); return root; } /// Class that is traced by the GC, but not managed by it class GC_Traceable { friend class GC; protected: mutable bool mark; /// override to trace any child objects virtual void trace(const GC&) const {} }; /// Class that is managed by the GC class GC_Object : public GC_Traceable { friend class GC; protected: virtual ~GC_Object() {} public: GC_Object(); }; // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //