-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
26
Currently, forwarding in Shenandoah is done by writing the pointer to the forwardee into the first word of the original object. While this allows for easy and fast lookup, it comes with several disadvantages:
- We need to retain the from-space regions until the end of update-refs phase, because we need the forwarding information in the from-space region.
- We can not do in-region compaction, because this would overwrite forwarding information.
- Chasing the forwarding pointer is putting pressure on CPU caches: the forwarding information in a region is very sparse, and loading a forwarding pointer usually means loading a whole cache-line just for this word.
We want to experiment with a new approach:
- During evacuation, each GC worker first evacuates a region normally, and store forwarding pointer in the first word of the original object.
- When a region has been evacuated, the same GC worker builds a forwarding table. That table would be a simple hash-table that is anchored at the end of the region. Care must be taken to not overwrite object headers (this is simple: check marking bitmap and use next hash entry if marked). We don't need to worry about any concurrency, because building the table is done by a single GC worker.
- After that is done, all forwarding for that region is switched to use the forwarding table.
- We can now reclaim the region and use it for allocations. We need to ensure that allocations don't use the tail end where the forwarding table is located.
- After update-refs is done, we can free up the tails and re-enter the cset regions into the free-set.
- We need to retain the from-space regions until the end of update-refs phase, because we need the forwarding information in the from-space region.
- We can not do in-region compaction, because this would overwrite forwarding information.
- Chasing the forwarding pointer is putting pressure on CPU caches: the forwarding information in a region is very sparse, and loading a forwarding pointer usually means loading a whole cache-line just for this word.
We want to experiment with a new approach:
- During evacuation, each GC worker first evacuates a region normally, and store forwarding pointer in the first word of the original object.
- When a region has been evacuated, the same GC worker builds a forwarding table. That table would be a simple hash-table that is anchored at the end of the region. Care must be taken to not overwrite object headers (this is simple: check marking bitmap and use next hash entry if marked). We don't need to worry about any concurrency, because building the table is done by a single GC worker.
- After that is done, all forwarding for that region is switched to use the forwarding table.
- We can now reclaim the region and use it for allocations. We need to ensure that allocations don't use the tail end where the forwarding table is located.
- After update-refs is done, we can free up the tails and re-enter the cset regions into the free-set.