Okay. I have yet another idea for solving our infant mortality problem, which I think Dan might like. :)
The neonate idea originally was intended to be set on *all* headers returned by the memory system, and they'd be reset by a clear_neonate op. At least, that's how I understood it. A straightforward implementation of the above is about 50% slower than it was before, so I think that rules this option out. The current code (without this patch), adds neonate wherever it discovers that it is needed, and turns it off when it is done. This was quite efficient, but required the user to constantly think about what functions could cause GC, etc. It was rather error-prone. If I understood Dan correctly on IRC yesterday, he was proposing that our current approach of handling infant mortality everywhere it can occur, is the 'correct' approach. It definitely buys us speed, but as mentioned above, it's somewhat error prone. The below is an attempt to try and convince Dan that in lieu of hardcore GC-everywhere programming, there is a middle ground. I believe we need a middle ground because forcing users to learn the quirks of our GC system makes parrot programming less fun, and raises Parrot's barrier to entry. As I was working on my revised GC system, I came up with a relaxation of the above that should be easier on programmers, and yet still be fast. It's not revolutionary by any means, but rather grabbing bits and pieces of different people's solutions. When you call new_*_header, the neonate flag is automatically turned on for you. As a programmer writing a function, you explicitly turn off the neonate flag when you attach it to the root set, or let it die on the stack. If you return it, you don't do anything, as it becomes the caller's job to handle. Neonate guarantees that it won't be collected, avoiding infant mortality. The programmer does not have to explicitly turn it on. Just turn it off. >From a cursory glance over string.c, only string_concat and string_compare create strings which die within the scope of that function, and thus need to be modified. This approach would complicate many of our string .ops, however. Stuff like "$1 = s" needs to turn off the neonate flag. Perhaps we can encode logic into the ops2c converter to turn off the neonate flag for things that it can detect, or perhaps we can require the user to do it because automated converters are guaranteed to fail. Core.ops requires a lot of such modifications, however. Things like err, open, readline, print, read, write, clone, set, set_keyed, the various string ops (substr, pack, etc), and savec, all require modification. I think these guidelines make it easy for non-GC-programmers to writ GC-dafe code, since they do not need to be aware of what allocates memory, and what does not. What do people think of this approach? Mike Lambert