Pype.Clicker wrote:
and here's where things get nasty for kernel level:
- what if your object is actually a buffer for which you grabbed the physical frames and wrote them in a DMA list ?
- what if a pointer is actually being "cached" into a register in another thread -- even if the thread is halted... or maybe a pointer derivated from the "base type" to an indexed element, etc.
That is actually no problem at all.
(Now remember I'm answering this all on how .NET works, just to give anyone an idea on an implementation that works *user-level*)
1) you can pin objects, while these are pinned their memory will not be moved (or collected, since you have a reference). Of course you wan't to minimize this pinning since it fragments your heap
2) during the .NET GC all threads are paused. The GC assumes all objects are available for collecting and starts walking registers, stacks etc. to see which objects still have references. Those are set to "active" and not collected. So yes, it will check registers (how this exactly works I don't know, but since the system generated the x86 code you can assume it knows at which EIP which registers are in use for what)
Again, this may not work nicely in the kernel, but there are different solutions to that.
For example, all memory that is send from one process to another in Singularity is allocated on a seperate heap called the exchange heap. This is not garbage collected (so classes are not moved in memory!) but reference counted.
I think any DMA is done through there as well (I know it can, just not sure if that is always the case) since such buffers will need to passed to other processes (than the driver) which can only be done through that mechanism [in Singularity]. Otherwise I assume they'll pin that memory block.
bluecode: yeah, we got a bit sidetracked there
I think GC / reference counting in native code is a very tricky thing to do. But since you own the kernel it might be quite possible to do in a good and reliable way. You won't know until you try it (and design it on paper first)
bluecode wrote:
Well, that pretty much smells like ****
Why does a garbage collector would want to save pointer to all pointer that are using one object and modify them when neccessary? Why not modify only one pointer?
Perhaps I (we) did a poor job explaining it. It is, of course, a difficult subject to discuss without writing a paper on it with pictures and such.
But I've looked quite extensively into how .NET creates its x86 code and how it handles all of this, including the GC.
For example, it is interesting to see the difference in code generated to get to a class in .NET 1.1 versus 2.0. The latter is more optimized than the former.
I can tell you that they (Microsoft) has done a lot of work on making this work and perform well (again, in *user-land* and with non-native [processor] languages). I've read numerous papers on the subject and a lot of thought and performance measurements went into that design.