Changeset 04570c7


Ignore:
Timestamp:
Apr 13, 2018, 4:39:28 PM (4 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
6f81db3
Parents:
3205495
git-author:
Aaron Moss <a3moss@…> (04/13/18 16:27:11)
git-committer:
Aaron Moss <a3moss@…> (04/13/18 16:39:28)
Message:

First draft of arbitrarily-generational GC

Location:
src/Common
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Common/GC.cc

    r3205495 r04570c7  
    2828}
    2929
    30 GC::GC() : mark(false), using_young(false), old(), young(), static_roots() {
    31         old.reserve(70000);
     30GC::GC() : gens(1), static_roots(), mark(false), g(0) {
     31        gens[0].reserve(70000);
    3232}
    3333
    3434GC::~GC() {
    35         for ( GC_Object* o : young ) {
    36                 delete o;
    37         }
    38 
    39         for ( GC_Object* o : old ) {
    40                 delete o;
     35        for ( unsigned i = 0; i <= g; ++i ) {
     36                for ( GC_Object* o : gens[i] ) {
     37                        delete o;
     38                }
    4139        }
    4240}
     
    5452
    5553void GC::register_object(GC_Object* obj) {
    56         (using_young ? young : old).push_back(obj);
     54        gens[g].push_back(obj);
    5755        obj->mark = !this->mark;  // initialize as un-marked
    5856}
     
    6361
    6462void GC::new_generation() {
    65         assert(!using_young && "Cannot start new generation when young generation already in use");
    66        
    67         using_young = true;  // mark young generation as in-use
    68         mark = !mark;        // switch mark so aged young objects will still be unmarked in old
     63        if ( ++g == gens.size() ) { gens.emplace_back(); }  // ensure new generation available
     64        mark = !mark;  // switch mark so aged young objects will still be unmarked in old
    6965}
    7066
     
    7773
    7874void GC::collect_young() {
     75        // get generations and decrement generation
     76        assert(g > 0 && "Cannot collect_young without young generation");
     77        Generation& young = gens[g];
     78        Generation& old = gens[--g];
     79
    7980        // collect young gen
    8081        for ( GC_Object*& obj : young ) {
     
    8990        old.insert( old.end(), young.begin(), end_live );
    9091       
    91         // clear young gen
    92         using_young = false;
     92        // clear young gen and reset mark to return to old generation mark
    9393        young.clear();
    94 
    95         // reset mark to return to old generation mark
    9694        mark = !mark;
    9795}
     
    9997void GC::collect() {
    10098        // ensure not called when young gen is active
    101         assert(!using_young && "Cannot do old collection when young generation is active");
     99        assert(g == 0 && "Cannot do old collection when young generation is active");
     100        Generation& old = gens[0];
    102101
    103102        // collect old gen
  • src/Common/GC.h

    r3205495 r04570c7  
    3838        void register_static_root(BaseSyntaxNode*);
    3939
    40         /// Use young generation for subsequent new objects
     40        /// Start new generation for subsequent new objects
    4141        void new_generation();
    4242
     
    4444        void trace_static_roots();
    4545
    46         /// Collects the young generation, placing survivors in old generation.
    47         /// Old generation is used for subsequent new objects.
     46        /// Collects the youngest generation, placing survivors in previous generation.
     47        /// Young generation objects cannot be kept alive by pointers from older generation.
     48        /// Older generation is used for subsequent new objects.
    4849        void collect_young();
    4950
    50         /// Collects old generation; use old generation afterward.
    51         /// Error if currently using young generation
     51        /// Collects oldest generation; use oldest generation afterward.
     52        /// Error if currently using younger generation
    5253        void collect();
    5354
     
    5859        GC();
    5960
    60         bool mark;                 ///< The current collection's mark bit
    61         bool using_young;          ///< Is the young generation in use?
    62 
    6361        using Generation = std::vector<GC_Object*>;
    64         Generation old;            ///< Old generation
    65         Generation young;          ///< Young generation
     62        std::vector<Generation> gens;  ///< Set of generations; always at least one
    6663
    6764        using StaticRoots = std::vector<BaseSyntaxNode*>;
    68         StaticRoots static_roots;  ///< Set of static-lifetime roots
     65        StaticRoots static_roots;      ///< Set of static-lifetime roots
     66
     67        bool mark;                     ///< The current collection's mark bit
     68        unsigned g;                    ///< The current number generation in use
    6969};
    7070
Note: See TracChangeset for help on using the changeset viewer.