// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // GC.cc -- // // Author : Aaron B. Moss // Created On : Thu Mar 15 14:47:00 2018 // Last Modified By : Aaron B. Moss // Last Modified On : Thu Mar 15 14:47:00 2018 // Update Count : 1 // #include "GC.h" #include "Common/PassVisitor.h" #include "SynTree/GcTracer.h" #include #include // #include GC& GC::get() { static GC gc; return gc; } GC::GC() : mark(false), using_young(false), old(), young(), static_roots() { old.reserve(70000); } GC::~GC() { for ( GC_Object* o : young ) { delete o; } for ( GC_Object* o : old ) { delete o; } } const GC& GC::operator<< (const GC_Traceable* obj) const { if( obj ) { bool isMarked = obj->mark == this->mark; if( !isMarked ) { obj->mark = this->mark; obj->trace( *this ); } } return *this; } void GC::register_object(GC_Object* obj) { // if ( obj == (GC_Object*)0x60f00000e410ul ) std::raise( SIGTRAP ); (using_young ? young : old).push_back(obj); obj->mark = ! this->mark; // initialize as un-marked } void GC::register_static_root(BaseSyntaxNode* root) { static_roots.push_back(root); } void GC::new_generation() { using_young = true; } void GC::trace_static_roots() { PassVisitor tracer{ *this }; for ( BaseSyntaxNode* root : static_roots ) { root->accept( tracer ); } } void GC::collect_young() { // check young generation, just reset mark if not using if ( ! using_young ) { mark = !mark; return; } // collect young gen for ( GC_Object*& obj : young ) { if ( obj->mark != mark ) { delete obj; obj = nullptr; } } // move uncollected elements into old gen auto end_live = std::remove( young.begin(), young.end(), nullptr ); old.insert( old.end(), young.begin(), end_live ); // clear young gen using_young = false; young.clear(); // reset mark for next collection mark = !mark; } void GC::collect() { // collect old gen for ( GC_Object*& obj : old ) { if ( obj->mark != mark ) { // if ( obj == (GC_Object*)0x60f00000e410ul ) std::raise( SIGTRAP ); delete obj; obj = nullptr; } } // clear collected elements old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() ); // collect young gen (also resets mark) collect_young(); } GC_Object::GC_Object() { GC::get().register_object( this ); } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //