source: src/Common/GC.cc @ 34dcc474

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

Fix one GC tracing bug

  • 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
25// #include <csignal>
26
27GC& GC::get() {
28        static GC gc;
29        return gc;
30}
31
32GC::GC() : mark(false), using_young(false), old(), young(), static_roots() {
33        old.reserve(70000);
34}
35
36GC::~GC() {
37        for ( GC_Object* o : young ) {
38                delete o;
39        }
40
41        for ( GC_Object* o : old ) {
42                delete o;
43        }
44}
45
46const GC& GC::operator<< (const GC_Traceable* obj) const {
47        if( obj )
48        {
49                bool isMarked = obj->mark == this->mark;
50                if( !isMarked ) {
51                        obj->mark = this->mark;
52                        obj->trace( *this );
53                }
54        }
55        return *this;
56}
57
58void GC::register_object(GC_Object* obj) {
59        // if ( obj == (GC_Object*)0x60f00000e410ul ) std::raise( SIGTRAP );
60        (using_young ? young : old).push_back(obj);
61        obj->mark = ! this->mark;  // initialize as un-marked
62}
63
64void GC::register_static_root(BaseSyntaxNode* root) {
65        static_roots.push_back(root);
66}
67
68void GC::new_generation() {
69        using_young = true;
70}
71
72void GC::trace_static_roots() {
73        PassVisitor<GcTracer> tracer{ *this };
74        for ( BaseSyntaxNode* root : static_roots ) {
75                root->accept( tracer );
76        }
77}
78
79void GC::collect_young() {
80        // check young generation, just reset mark if not using
81        if ( ! using_young ) {
82                mark = !mark;
83                return;
84        }
85
86        // collect young gen
87        for ( GC_Object*& obj : young ) {
88                if ( obj->mark != mark ) {
89                        delete obj;
90                        obj = nullptr;
91                }
92        }
93       
94        // move uncollected elements into old gen
95        auto end_live = std::remove( young.begin(), young.end(), nullptr );
96        old.insert( old.end(), young.begin(), end_live );
97       
98        // clear young gen
99        using_young = false;
100        young.clear();
101
102        // reset mark for next collection
103        mark = !mark;
104}
105
106void GC::collect() {
107        // collect old gen
108        for ( GC_Object*& obj : old ) {
109                if ( obj->mark != mark ) {
110                        // if ( obj == (GC_Object*)0x60f00000e410ul ) std::raise( SIGTRAP );
111                        delete obj;
112                        obj = nullptr;
113                }
114        }
115
116        // clear collected elements
117        old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
118
119        // collect young gen (also resets mark)
120        collect_young();
121}
122
123GC_Object::GC_Object() {
124        GC::get().register_object( this );
125}
126
127// Local Variables: //
128// tab-width: 4 //
129// mode: c++ //
130// compile-command: "make install" //
131// End: //
Note: See TracBrowser for help on using the repository browser.