Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Garbage collector for c++ version #14

Open
clinuxrulz opened this issue Feb 20, 2018 · 15 comments
Open

Garbage collector for c++ version #14

clinuxrulz opened this issue Feb 20, 2018 · 15 comments

Comments

@clinuxrulz
Copy link

clinuxrulz commented Feb 20, 2018

@the-real-blackh

I've translated "Gc.rs" from Rust to C++ . It is designed to work exactly the same way as the rust one. It uses the template struct Trace to mimic a Trace trait.

https://github.com/clinuxrulz/gc-cxx

If this is the sort of approach you would like to use, then maybe it could find a home in "SodiumFRP/.." somewhere.

The strategy in mind for use is: WeakGc<> forward references, Gc<> back references. The back references tend to get held in the cleanup/finalizers of the sodium objects.
Trace implementations would need to be provided for Cell/Stream and Listener to use it. (I.E. Anywhere a Gc<> could be held needs to be made reachable by Trace<>::trace(...))

Here is what it looks like when you use it:
https://github.com/clinuxrulz/gc-cxx/blob/master/example.cpp

The example creates a cycle among 3 objects and shows them getting freed at the end of the local scope.

@the-real-blackh
Copy link

Thank you! You have just saved me a whole lot of work! I've really got to find some time to finish this off.

@clinuxrulz
Copy link
Author

clinuxrulz commented Feb 23, 2018

I've switched over std::shared_ptr to Gc<>, and std::weak_ptr to GcWeak<> in a fork of sodium-cxx.

I'm getting Seg Faults at the moment. However the gc.h and gc.cpp files are tiny, so it shouldn't take long to figure out the bugs.

@clinuxrulz
Copy link
Author

I think I have a design mistake:
Say we have Gc<A> which has a cycle with other Gc<> objects. As deconstructor can end up re-rooting a Gc<> that has already been freed, and thus cause a segfault. I'll have to think about it for a while.

@ziriax
Copy link

ziriax commented Feb 24, 2018

In the old days when I was developing games, we solved this by just marking objects to be freed (using a simple double linked list or so), and then in a second phase actually freeing the memory, without any other side effects. Not sure if this applies here, I don't know the details.

@clinuxrulz
Copy link
Author

@ziriax that applies here. I've just realized that it is the purpose of the buffered flag (it checks it in release). I originally translated it from a paper without understanding the code. Thanks.

@clinuxrulz
Copy link
Author

clinuxrulz commented Feb 25, 2018

What I really need to do is a proper test suit for gc-cxx, then use it as a static library for sodium-cxx. There is a multi-threaded version of the gc algorithm in the paper too, that I do not feel like implementing. But someone else might feel like it, so I'll move the project to "SodiumFRP/...", it can be developed independently of sodium-cxx. I should really do the same for Rust too, I've seen another GC library already available for Rust, but it requires "Rust Nightly" instead of "Rust Stable". I'd rather depend on the "Stable" release of Rust rather than the "Unstable" one.

gc-cxx is moved to SodiumFRP as of now.

@the-real-blackh
Copy link

the-real-blackh commented Feb 25, 2018

The existing C++ version of Sodium was one of my earlier efforts and it has a lot of not-so-good attempts at optimization. I'd like to see it re-written in a much simpler way, more along the lines of the Typescript version.

I'd love to see it work with move semantics instead of passing a pointer to the value around. But this isn't the priority. The priority it getting it working!

@clinuxrulz
Copy link
Author

clinuxrulz commented Feb 26, 2018

The TypeScript version is really tidy, and I now find it easy to understand. I think people can wait for a TypeScript to C++ translation if that is where we will end up going.

We should have the sodium objects lazyly construction like in the TypeScript version, but remove the requirement for all sodium object to be listened to in order to work correctly. I believe we can achieve this in C++ because we have automatic reference counting (a stack).

@grahamreeds
Copy link

grahamreeds commented Feb 26, 2018 via email

@clinuxrulz
Copy link
Author

@grahamreeds the canonical version is the latest version in https://github.com/SodiumFRP/sodium-cxx/releases at the moment.

@the-real-blackh We need to implement finalizers to avoid that seg fault I had before. Why? Because the deconstructor executes methods on objects being referenced by the deconstructing object.

@clinuxrulz
Copy link
Author

clinuxrulz commented Feb 28, 2018

Finalizers are now supported in gc-cxx (see tests/test_gc.cpp for usage). It won't be as simple as string replacing std::shared_ptr / std::weak_ptr. Some destructor code will need shuffling too.

@clinuxrulz
Copy link
Author

Something has just occurred to me. In order to support lazy construction of the sodium object graph, you would be forced to listen to all sodium objects for them to be updated correctly (accum, collect). Unless we could lazyly construct on fire of event rather than listen. This seems like an unnecessary requirement to impose on the end-user, I think we can do better in C++.

I completely understand why we are forced to listen to all sodium objects in TypeScript. Because we really have no choice, its our only means of reference counting. In C++ & Rust we have automatic reference counting, we can do better.

Lets just try and get the current C++ version working as is first. And refactor in the move semantics as we go.

@the-real-blackh
Copy link

the-real-blackh commented Mar 4, 2018

Great! I didn't know there was a way to do it with GC. I agree - If we can use that, then it would definitely be better.

@clinuxrulz
Copy link
Author

I've made a bit of a start of at integrating Gc<>. It looks like a lot of work, so no promises: https://github.com/clinuxrulz/sodium-cxx/tree/gc/sodium . (it uses gc-cxx as a git sub-module)
What remains to make it work, is to do Trace and Finalize trait implementations for all types that contain reachable Gc<>s. Which will lead us implementing lambda1, lambda2 like typescript does so we can trace our closures/lambdas.

I also just saw magic_ref.h. I had no idea that was there. Maybe I should of used it instead. Or use its code to improve Gc<>, like its memory foot print.

@the-real-blackh
Copy link

magic_ref.h was an experimental attempt to do something along these lines - I can't remember exactly what.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants