GithubHelp home page GithubHelp logo

jonas-schievink / rcgc Goto Github PK

View Code? Open in Web Editor NEW
16.0 3.0 0.0 17 KB

A reference-counting, tracing garbage collector in completely safe Rust

License: Creative Commons Zero v1.0 Universal

Rust 100.00%
gc reference-counting garbage-collector memory-management

rcgc's Introduction

A garbage collector using Rc/Weak

crates.io docs.rs Build Status

This crate implements a pretty simple garbage collector. Its selling point is that it uses no unsafe at all: Instead, it represents references between objects as Weak pointers that are upgraded to Rcs on access.

The GC holds an Rc to every object on its heap and can hand out further Rcs acting as roots. It can then locate rooted objects and perform a tracing garbage collection to free objects with no incoming references (even in the presence of cycles). It also uses the underlying reference counters as a faster way to locate garbage objects: If an object has a weak count of 0 and a strong count of 1, it is only reachable via the GCs own Rc, not via any object reference, and can be freed immediately without having to perform a tracing phase.

If there's a bug in the GC, and an object ends up getting collected while it's still reachable, any access to the object will fail to upgrade the Weak pointer and panic instead of becoming an unsafe use-after-free.

Please refer to the changelog to see what changed in the last releases.

Usage

Start by adding an entry to your Cargo.toml:

[dependencies]
rcgc = "0.1.0"

Then import the crate into your Rust code:

extern crate rcgc;

rcgc's People

Contributors

jonas-schievink avatar mgeisler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rcgc's Issues

Notes about a thread-safe version

Naively replacing Rc with Arc and Weak with sync::Weak isn't going to fly.

Freeing completely abandoned data (ie. stuff not involved in cycles) should still work without having to synchronize all threads, since that decision only depends on the strong and weak count of Handles, however:

  • Accessing Arc::strong_count and then Arc::weak_count is always a race and can not be relied upon to make a decision about destroying objects
    • Arc::is_unique is what we actually want to check (as it synchronizes the read), but is private
    • Arc::get_mut returns Some iff Arc::is_unique returns true right now, so it can be used instead

If this doesn't free sufficient amounts of memory, we need to do a cycle collection. I think the simplest way to do that correctly is by pausing all threads and preventing all strong or weak counts in the entire object graph from changing. Any thread can then perform the cycle collection atomically (theoretically we could even parallelize this).

This will require either:

  • every thread manipulating GC objects to periodically call a synchronization function
  • rcgc to check a synchronization token on every refcount manipulation

The second option looks much better to me. That way, we will simply block all threads when they decide to access GC data, not when they're doing unrelated things. I want to stress that this requires us to check the token (an Acquire load) on every refcount manipulation, though (ie. in Clone and Drop of Rooted and Handle).

I'm sure this idea is still broken in some way, but somehow this has made me feel like this is at least possible.

Add debug-only checks to expose all use-after-frees

With cfg(debug_assertions) or, since this is extremely expensive, only when a Cargo feature is enabled, we should perform a full collection every time a reference to a GC object is dropped.

This means that objects get freed as soon as the GC would be allowed to, which should expose all possible use-after-free bugs caused either by a bug in rcgc, missing roots, or incorrectly broken/moved object references.

Fuzzing

The current test suite is extremely limited. Long-term fuzzing should, if set up correctly, provide a much more confident result regarding GC correctness.

This is pretty difficult to set up, since you basically have to generate random workloads that trigger many edge cases, but also explore real-world loads during that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.