source: src/Common/GC.cc @ bd06384

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

Add static roots to GC; fix some static GC_Objects

  • Property mode set to 100644
File size: 2.5 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                bool isMarked = obj->mark == this->mark;
48                if( !isMarked ) {
49                        obj->mark = this->mark;
50                        obj->trace( *this );
51                }
52        }
53        return *this;
54}
55
56void GC::register_object(GC_Object* obj) {
57        (using_young ? young : old).push_back(obj);
58        obj->mark = this->mark;
59}
60
61void GC::register_static_root(BaseSyntaxNode* root) {
62        static_roots.push_back(root);
63}
64
65void GC::new_generation() {
66        using_young = true;
67}
68
69void GC::trace_static_roots() {
70        PassVisitor<GcTracer> tracer{ *this };
71        for ( BaseSyntaxNode* root : static_roots ) {
72                root->accept( tracer );
73        }
74}
75
76void GC::collect_young() {
77        // check young generation, just reset mark if not using
78        if ( ! using_young ) {
79                mark = !mark;
80                return;
81        }
82
83        // collect young gen
84        for ( GC_Object*& obj : young ) {
85                if ( obj->mark != mark ) {
86                        delete obj;
87                        obj = nullptr;
88                }
89        }
90       
91        // move uncollected elements into old gen
92        auto end_live = std::remove( young.begin(), young.end(), nullptr );
93        old.insert( old.end(), young.begin(), end_live );
94       
95        // clear young gen
96        using_young = false;
97        young.clear();
98
99        // reset mark for next collection
100        mark = !mark;
101}
102
103void GC::collect() {
104        // collect old gen
105        for ( GC_Object*& obj : old ) {
106                if ( obj->mark != mark ) {
107                        delete obj;
108                        obj = nullptr;
109                }
110        }
111
112        // clear collected elements
113        old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
114
115        // collect young gen (also resets mark)
116        collect_young();
117}
118
119bool stack_check( int* i, GC_Object* o ) {
120        int j;
121        return ( i < &j ) == ( (void*)o < (void*)&j );
122}
123
124GC_Object::GC_Object() {
125        GC::get().register_object( this );
126
127        int i;
128        assert(!stack_check(&i, this));
129}
130
131// Local Variables: //
132// tab-width: 4 //
133// mode: c++ //
134// compile-command: "make install" //
135// End: //
Note: See TracBrowser for help on using the repository browser.