Uploading this now to get some early feedback on the approach and maybe find some better tests.
Pointers in the VM are implemented through the Pointer class. Each Pointer points to a Block, which represent memory. However, each Block also knows all the Pointers pointing at it. I've used this to find simply replace a Block representing an array with a larger one and update all pointers pointing to said block (Block::transferPointers()). This is the core of it all, but it requires quite a few smaller changes that could be broken out of this patch of course. Like enabling pointer tracking for static Blocks.
The additional asserts I inserted here could be in another patch. However, I added them because I ran into a peculiar problem: when creating a Pointer, it calls Pointee->addPointer(this). It will only remove itself from the pointee again in its destructor. But the destructor is not (necessarily) being called at all because the Pointer is constructed in the stack (or otherwise placement-new'ed into a larger memory region).