I submitted a patch to implement the initial parts of Dan's method some time ago, which has never been applied. (Although Dan recently agreed that it needed to be done, and I will be updating it shortly in line with changes to the memory management system) However, thinking about it some more, there may be a way to avoid the overhead of the separate cleanup phase, if we enforce the rule that any objects created during a single opcode must be rooted at the end of the opcode or be disposable, and apply a variation of Melvin's generations:
Add a counter to the interpreter structure, which is incremented every opcode (field size would not be particularly important) Store this counter value in every new object created, and set the 'new object' flag (by doing this on every object, we remove the requirement for the creating function to be aware of what is happening) If an object is encountered during DOD that claims to be new, but was not created during the current opcode, dispute the claim. If the counter has exactly wrapped in the meantime, an object might survive longer than it should. Advantages Totally transparent outside of resources.c No additional passes required Objects will be reclaimed during the first DOD run after the creating opcode Disadvantages Additional field in PMC and Buffer headers Per-opcode counter required therefore fixed performance degradation Slightly more expensive logic to detect dead objects during DOD run Comments, anyone? I agree that something needs to be done quite urgently. As an example, Steve's current fix to string_concat (disable DOD) causes performance problems: Disabling DOD during string_concat: 5000 generations in 101.397038 seconds. 49.311105 generations/sec A total of 360896 bytes were allocated A total of 1501 DOD runs were made A total of 1474 collection runs were made Copying a total of 28677296 bytes There are 4770 active Buffer structs There are 14464 total Buffer structs With this change removed (life doesn't trigger the bug): 5000 generations in 97.344093 seconds. 51.364185 generations/sec A total of 57344 bytes were allocated A total of 101397 DOD runs were made A total of 5418 collection runs were made Copying a total of 7957080 bytes There are 102 active Buffer structs There are 512 total Buffer structs This highlights something that needs to be fixed anyway - blocked DOD runs are effectively cancelled, whereas they should just be postponed. -- Peter Gibbs EmKel Systems