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


Reply via email to