source: src/Common/GC.cc @ f229fc2

new-envwith_gc
Last change on this file since f229fc2 was f229fc2, checked in by Aaron Moss <a3moss@…>, 6 years ago

Modify resolver to use young-generation collection per-top-level expression

  • Property mode set to 100644
File size: 2.6 KB
Line 
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.cc --
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#include "GC.h"
17
18#include "Common/PassVisitor.h"
19
20#include "SynTree/GcTracer.h"
21
22#include <algorithm>
23#include <cassert>
24
25GC& GC::get() {
26        static GC gc;
27        return gc;
28}
29
30GC::GC() : mark(false), using_young(false), old(), young(), static_roots() {
31        old.reserve(70000);
32}
33
34GC::~GC() {
35        for ( GC_Object* o : young ) {
36                delete o;
37        }
38
39        for ( GC_Object* o : old ) {
40                delete o;
41        }
42}
43
44const GC& GC::operator<< (const GC_Traceable* obj) const {
45        if( obj )
46        {
47                if( obj->mark != this->mark ) {
48                        obj->mark = this->mark;
49                        obj->trace( *this );
50                }
51        }
52        return *this;
53}
54
55void GC::register_object(GC_Object* obj) {
56        (using_young ? young : old).push_back(obj);
57        obj->mark = !this->mark;  // initialize as un-marked
58}
59
60void GC::register_static_root(BaseSyntaxNode* root) {
61        static_roots.push_back(root);
62}
63
64void 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
69}
70
71void GC::trace_static_roots() {
72        PassVisitor<GcTracer> tracer{ *this };
73        for ( BaseSyntaxNode* root : static_roots ) {
74                root->accept( tracer );
75        }
76}
77
78void GC::collect_young() {
79        // collect young gen
80        for ( GC_Object*& obj : young ) {
81                if ( obj->mark != mark ) {
82                        delete obj;
83                        obj = nullptr;
84                }
85        }
86       
87        // move uncollected elements into old gen
88        auto end_live = std::remove( young.begin(), young.end(), nullptr );
89        old.insert( old.end(), young.begin(), end_live );
90       
91        // clear young gen
92        using_young = false;
93        young.clear();
94
95        // reset mark to return to old generation mark
96        mark = !mark;
97}
98
99void GC::collect() {
100        // ensure not called when young gen is active
101        assert(!using_young && "Cannot do old collection when young generation is active");
102
103        // collect old gen
104        for ( GC_Object*& obj : old ) {
105                if ( obj->mark != mark ) {
106                        delete obj;
107                        obj = nullptr;
108                }
109        }
110
111        // clear collected elements
112        old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
113
114        // reset mark
115        mark = !mark;
116}
117
118GC_Object::GC_Object() {
119        GC::get().register_object( this );
120}
121
122// Local Variables: //
123// tab-width: 4 //
124// mode: c++ //
125// compile-command: "make install" //
126// End: //
Note: See TracBrowser for help on using the repository browser.