source: src/Common/GC.cc@ b60f9d9

new-env
Last change on this file since b60f9d9 was 7a37f258, checked in by Aaron Moss <a3moss@…>, 8 years ago

Fix bug with static root traces

  • Property mode set to 100644
File size: 3.5 KB
RevLine 
[68f9c43]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
[bd06384]18#include "Common/PassVisitor.h"
19
20#include "SynTree/GcTracer.h"
21
[68f9c43]22#include <algorithm>
[7e4b44db]23#include <cassert>
[68f9c43]24
25GC& GC::get() {
26 static GC gc;
27 return gc;
28}
29
[04570c7]30GC::GC() : gens(1), static_roots(), mark(false), g(0) {
31 gens[0].reserve(70000);
[68f9c43]32}
33
34GC::~GC() {
[04570c7]35 for ( unsigned i = 0; i <= g; ++i ) {
36 for ( GC_Object* o : gens[i] ) {
37 delete o;
38 }
[68f9c43]39 }
40}
41
[24de7b1]42const GC& GC::operator<< (const GC_Object* obj) const {
[68f9c43]43 if( obj )
44 {
[f229fc2]45 if( obj->mark != this->mark ) {
[68f9c43]46 obj->mark = this->mark;
47 obj->trace( *this );
48 }
49 }
50 return *this;
51}
52
[fb97252f]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>
[5af7306]59// continue
[fb97252f]60#ifdef GC_TRAP
61#include <csignal>
62
63/// Set to object to check in debugger
64void* GC_TRAP_OBJ = nullptr;
65#endif
66
[68f9c43]67void GC::register_object(GC_Object* obj) {
[fb97252f]68 #ifdef GC_TRAP
69 if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
70 #endif
[04570c7]71 gens[g].push_back(obj);
[f229fc2]72 obj->mark = !this->mark; // initialize as un-marked
[68f9c43]73}
74
[bd06384]75void GC::register_static_root(BaseSyntaxNode* root) {
76 static_roots.push_back(root);
77}
78
[2efe4b8]79GC_Guard GC::new_generation() {
[04570c7]80 if ( ++g == gens.size() ) { gens.emplace_back(); } // ensure new generation available
81 mark = !mark; // switch mark so aged young objects will still be unmarked in old
[2efe4b8]82 return { *this, g };
[68f9c43]83}
84
[bd06384]85void GC::trace_static_roots() {
86 PassVisitor<GcTracer> tracer{ *this };
87 for ( BaseSyntaxNode* root : static_roots ) {
88 root->accept( tracer );
89 }
90}
91
[68f9c43]92void GC::collect_young() {
[04570c7]93 // get generations and decrement generation
94 assert(g > 0 && "Cannot collect_young without young generation");
95 Generation& young = gens[g];
96 Generation& old = gens[--g];
97
[7a37f258]98 // ensure static roots traced
99 trace_static_roots();
100
[68f9c43]101 // collect young gen
102 for ( GC_Object*& obj : young ) {
103 if ( obj->mark != mark ) {
[fb97252f]104 #ifdef GC_TRAP
105 if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
106 #endif
[68f9c43]107 delete obj;
108 obj = nullptr;
109 }
110 }
111
112 // move uncollected elements into old gen
113 auto end_live = std::remove( young.begin(), young.end(), nullptr );
114 old.insert( old.end(), young.begin(), end_live );
115
[04570c7]116 // clear young gen and reset mark to return to old generation mark
[68f9c43]117 young.clear();
118 mark = !mark;
119}
120
121void GC::collect() {
[f229fc2]122 // ensure not called when young gen is active
[04570c7]123 assert(g == 0 && "Cannot do old collection when young generation is active");
124 Generation& old = gens[0];
[f229fc2]125
[7a37f258]126 // ensure static roots traced
127 trace_static_roots();
128
[68f9c43]129 // collect old gen
130 for ( GC_Object*& obj : old ) {
131 if ( obj->mark != mark ) {
[fb97252f]132 #ifdef GC_TRAP
133 if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
134 #endif
[68f9c43]135 delete obj;
136 obj = nullptr;
137 }
138 }
139
140 // clear collected elements
141 old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
142
[f229fc2]143 // reset mark
144 mark = !mark;
[68f9c43]145}
146
147GC_Object::GC_Object() {
148 GC::get().register_object( this );
149}
150
[24de7b1]151GC_Object::GC_Object( const GC_Object& ) {
152 GC::get().register_object( this );
153}
154
155GC_Object::GC_Object( GC_Object&& ) {
156 GC::get().register_object( this );
157}
158
[68f9c43]159// Local Variables: //
160// tab-width: 4 //
161// mode: c++ //
162// compile-command: "make install" //
163// End: //
Note: See TracBrowser for help on using the repository browser.