source: src/Common/GC.cc @ fb97252f

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

Added GC_TRAP debugging compilation flag

  • Property mode set to 100644
File size: 3.4 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() : gens(1), static_roots(), mark(false), g(0) {
31        gens[0].reserve(70000);
32}
33
34GC::~GC() {
35        for ( unsigned i = 0; i <= g; ++i ) {
36                for ( GC_Object* o : gens[i] ) {
37                        delete o;
38                }
39        }
40}
41
42const GC& GC::operator<< (const GC_Object* obj) const {
43        if( obj )
44        {
45                if( obj->mark != this->mark ) {
46                        obj->mark = this->mark;
47                        obj->trace( *this );
48                }
49        }
50        return *this;
51}
52
53// build with flag GC_TRAP to compile in a breakpoint on register and sweep of a dynamically
54// chosen object. Process to use:
55//     break GC::register_object
56//     run
57//     set variable GC_TRAP_OBJ = <target>
58//     disable <first breakpoint>
59#ifdef GC_TRAP
60#include <csignal>
61
62/// Set to object to check in debugger
63void* GC_TRAP_OBJ = nullptr;
64#endif
65
66void GC::register_object(GC_Object* obj) {
67        #ifdef GC_TRAP
68                if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
69        #endif
70        gens[g].push_back(obj);
71        obj->mark = !this->mark;  // initialize as un-marked
72}
73
74void GC::register_static_root(BaseSyntaxNode* root) {
75        static_roots.push_back(root);
76}
77
78void GC::new_generation() {
79        if ( ++g == gens.size() ) { gens.emplace_back(); }  // ensure new generation available
80        mark = !mark;  // switch mark so aged young objects will still be unmarked in old
81}
82
83void GC::trace_static_roots() {
84        PassVisitor<GcTracer> tracer{ *this };
85        for ( BaseSyntaxNode* root : static_roots ) {
86                root->accept( tracer );
87        }
88}
89
90void GC::collect_young() {
91        // get generations and decrement generation
92        assert(g > 0 && "Cannot collect_young without young generation");
93        Generation& young = gens[g];
94        Generation& old = gens[--g];
95
96        // collect young gen
97        for ( GC_Object*& obj : young ) {
98                if ( obj->mark != mark ) {
99                        #ifdef GC_TRAP
100                                if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
101                        #endif
102                        delete obj;
103                        obj = nullptr;
104                }
105        }
106       
107        // move uncollected elements into old gen
108        auto end_live = std::remove( young.begin(), young.end(), nullptr );
109        old.insert( old.end(), young.begin(), end_live );
110       
111        // clear young gen and reset mark to return to old generation mark
112        young.clear();
113        mark = !mark;
114}
115
116void GC::collect() {
117        // ensure not called when young gen is active
118        assert(g == 0 && "Cannot do old collection when young generation is active");
119        Generation& old = gens[0];
120
121        // collect old gen
122        for ( GC_Object*& obj : old ) {
123                if ( obj->mark != mark ) {
124                        #ifdef GC_TRAP
125                                if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
126                        #endif
127                        delete obj;
128                        obj = nullptr;
129                }
130        }
131
132        // clear collected elements
133        old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
134
135        // reset mark
136        mark = !mark;
137}
138
139GC_Object::GC_Object() {
140        GC::get().register_object( this );
141}
142
143GC_Object::GC_Object( const GC_Object& ) {
144        GC::get().register_object( this );
145}
146
147GC_Object::GC_Object( GC_Object&& ) {
148        GC::get().register_object( this );
149}
150
151// Local Variables: //
152// tab-width: 4 //
153// mode: c++ //
154// compile-command: "make install" //
155// End: //
Note: See TracBrowser for help on using the repository browser.