I spent some time today fixing little details in my GC and adding all sorts of function-level documentation. I took some time yesterday and this morning to work on docs/memory_internals.pod, a horribly out-of-date document that described more of what Parrot doesn't do then what it currently does.
With the exception of the tricky question about how to handle PMC_EXT structures in the memory subsystem (and I haven't come up with a good answer for it in two days), I think I'm just about at the point of code completion. Now, we all know from reading The Mythical Man Month that "code complete" means we're about a third of the way through the software development process. With the simple task of writing the initial code out of the way, we can tackle the real beasts: compiling, testing, debugging.
I'm going to spend tonight and tomorrow dealing with those pesky PMC_EXTs, and tying up any other loose ends that I can find. I also want to add a few more methods to my GCAccess PMC. I plan to use and abuse that tool during testing, if I can get it to work. It's my first PMC, so getting that to work might be more trouble then it saves me during testing. Oh well, it's a learning experience.
The last two lines of my SOC application timeline are as follows:
* DOD and collection for objects broken into incremental stages, and implemented. June 20th
* Finishing touches, spit and polish, system integration. June 25th.
So if I get the last details fixed up by tomorrow, I'm perfectly on schedule. This is amazing considering that my schedule was basically an off-the-cuff fabrication based on no prior experience whatsoever.
There are a few things that I haven't implemented yet, optional features that I've been preparing for but haven't wasted time on yet. One thing I really want to get working is threading, and I have a few ideas about how to implement it. I'll talk about threading later, when I actually get down to the messy business of implementing it. This will probably happen after I get the "regular" GC working reasonably.
Another feature I want to implement (and I haven't quite figured it out yet) is something like an "old generation" or "dense prefix": We find long-lived items and mark them as being such. That way, we can streamline the marking process by simply ignoring these items and treating them as if they are always alive. However, if we don't mark a particular long-lived aggregate, we also won't go through to mark any of it's children. I'm not certain however that the GC_WRITE_BARRIER is used with enough discipline throughout Parrot to keep track of items that come and go. If I don't scan an aggregate, and one of it's children is changed (PMC *_metadata, for instance), will the write barrier be invoked? Will it happen every time? If not, we run the risk that some alive items never get marked, and some dead items never get freed. Of course, this may be paranoia on my part, I need to research it more.
Tomorrow it's on to the PMC_EXT mess, and by monday I'm going to try my first "make". I'll be sure to post lots of updates as that happens.