How to forward pointers from register in a copying garbage collector?

Viewed 280

In a copying garbage collector, when I copy the objects from the from-space to the to-space, certain objects could be referenced by a pointer stored in a register. When the garbage collection happens, that register needs to be updated to point to the to-space.

The problem is, the garbage collection is executed at specific points during the program (let's say when the user allocates memory) and thus, this will call a function to do the collection. That will, in turn, use registers which might be the ones we actually need to forward. So, that creates multiple problems:

  • The register that we need to forward will not contain the address of the object to be forwarded.
  • The register will be restored when returning from the garbage collection function, so we cannot forward it at this point anyway.

So how can I do the pointer forwarding for an object whose pointer is stored in a pointer? We can assume the garbage collector is written in C, not in assembly (which would make it easy to not overwrite the registers).

2 Answers

Efficient garbage collection for a programming language or virtual machine, designed for garbage collection right from the start, always collaborates with the code generation.

Obviously, the garbage collector has to know the layout of the stack data to be able to analyze it. For efficiency, the generated code doesn’t need to support garbage collection at any point of time but only at certain safepoints where it may suspend itself when need for garbage collection has been flagged or, like in your single-threaded case, will call into the garbage collector directly.

At these points, the code has to bring its data in a form understood by the garbage collector. A simple solution is to push the registers to the stack, using the format known by the garbage collector, before calling the garbage collector and popping them back afterwards. So the mechanism doesn’t need to deal with register saving mechanisms of a different language, used for implementing the garbage collector itself.

So how can I do the pointer forwarding for an object whose pointer is stored in a pointer

You can only do that atomically and making the pointer visible to all other threads when you are done.

This is done differently by different GCs. Usually, GCs employ barriers for such a purpose, some code that is executed at the point when GC is running (like an interceptor to your objects).

So when some thread tries to allocate memory/change some object, while GC is running, it will not alter the pointer/object directly - but go through some code that will do that. Updating the forwarding pointer is usually a single-shot CAS, to re-map this forwarding pointer, making it visible to all threads.

I've explained how this is done here, it is java specific to Shenandoah GC, but the theory is still the same.

Related