and each of a function's ref type variables and parameters are really a pointer to alocation on this stack like this:
One thing I don't understand is what are you going to do about value types that contain pointers and are stored on the stack. Did I miss something?
that might not work because classes that are not reachable will never be called. If those classes are not rooted but they are still performing some sort of operations (maybe in some long running loop or a timer callback), their class variables will not be updated.
That should never happen, if an object is not reachable then it's garbage and it will be collected. If you pass a GC pointer to native code then you know what you need to do: use "fixed" or GCHandle to prevent the GC from moving/collecting the object.
So probably I will need to call UpdatePointer on each class while walking the object heap.
Watch out that moving objects and updating pointers can be extremly tricky. I'm not talking about finding the roots which can be itself a problem, I'm talking about how can you update pointers in an efficient way. One thing is clear: you can't move one object and then call UpdatePointers on all the other objects in the heap, that has quadratic complexity.
And my C++ code suddenly got hugely bloated with all sorts of seemingly unrelated classes like the CultureInfo
Hmm, not sure what CultureInfo has to do with List<>. Maybe the Sort method uses it somehow. Since you wrote that code you should be able to modify it to log some information about why a particular type has been included, right? If I understand correctly now you're including all the methods of an used type, you may consider excluding methods that are never called.
so I think it should be possible to make a VS debugging plugin. Has anyone had experience with this, and how difficult would such a project be?
Absolutely no idea but if you can make all the rest work (compiler, GC etc.) then you should be able to write such a plugin too