#include "garbage-collector.h" #include "utils.h" #include #include namespace effil { GarbageCollector::GarbageCollector() : state_(GCState::Idle) , lastCleanup_(0) , step_(200) {} GCObject* GarbageCollector::get(GCObjectHandle handle) { std::lock_guard g(lock_); auto it = objects_.find(handle); if (it == objects_.end()) { DEBUG << "Null handle " << handle << std::endl; return nullptr; } return it->second.get(); } bool GarbageCollector::has(GCObjectHandle handle) const { std::lock_guard g(lock_); return objects_.find(handle) != objects_.end(); } // Here is the naive tri-color marking // garbage collecting algorithm implementation. void GarbageCollector::cleanup() { std::lock_guard g(lock_); if (state_ == GCState::Stopped) return; assert(state_ != GCState::Running); state_ = GCState::Running; std::vector grey; std::map> black; for (const auto& handleAndObject : objects_) if (handleAndObject.second->instances() > 1) grey.push_back(handleAndObject.first); while (!grey.empty()) { GCObjectHandle handle = grey.back(); grey.pop_back(); auto object = objects_[handle]; black[handle] = object; for (GCObjectHandle refHandle : object->refers()) if (black.find(refHandle) == black.end()) grey.push_back(refHandle); } DEBUG << "Removing " << (objects_.size() - black.size()) << " out of " << objects_.size() << std::endl; // Sweep phase objects_ = std::move(black); state_ = GCState::Idle; lastCleanup_.store(0); } size_t GarbageCollector::size() const { std::lock_guard g(lock_); return objects_.size(); } void GarbageCollector::stop() { std::lock_guard g(lock_); assert(state_ == GCState::Idle || state_ == GCState::Stopped); state_ = GCState::Stopped; } void GarbageCollector::resume() { std::lock_guard g(lock_); assert(state_ == GCState::Idle || state_ == GCState::Stopped); state_ = GCState::Idle; } GarbageCollector& getGC() { static GarbageCollector pool; return pool; } } // effil