Steve Fink wrote:
... So I decided to summarize the various approaches in
hopes that something will jump out at someone.
Great document, thanks for all the work of summarizing this.
(2) point out what's wrong with my "variant 5: generational stack",
I think, it moves the problems just around with a lot of overhead. E.g. cloning a PerlArray of 10^6 entries would need 1000 generations (when 1000 PMCs are allocated in one bunch), which would need a ever growing generation stack (using mem too) and leading to a probably non linear slow down in DOD runs.
The ~1000 DOD runs want give you any resources (except for the first), so it would be cheaper to disable DOD alltogether for e.g. clone - or call do_dod_run explicitly and then disable it.
(3) propose something else that solves the whole problem neatly.
I think, we will need a mixture of:
In this case, the solution is simple: resize the array, if necessary,
before creating the PMC.
i.e. reorder code where possible, and anchor early, and ...
=head2 Variant 3: clear during DOD The neonate flag is cleared during DOD when an object is encountered during the recursive root set traversal. (Leopold Toetsch's trick of setting the live_FLAG during creation is equivalent to this variation, I think.) + Simple + Fast DOD (DOD already manipulates the flags) - If there are multiple DOD runs before the object is anchored or dies, it will be prematurely freed
IMHO it should be possible to guarantee, that there are no consecutive DOD runs for certain operations. The major problem is cloning of aggregates which could take arbitrary resources (though the aggregates normally know how big they are).
A second problem is: a DOD run can be triggered from two different code paths: get_free_object->more_traceable_objects->DOD and (for the copying allocator) by a shortage in the memory_pool from mem_allocate() [1].
By rearraning code and disabling DOD during clone (when needed), it should be possible to avoid walking the processor stack/regs alltogether.
[1] which BTW seems bogus to me: pool_compact() may be called (when there is enough reclaimable space), without having a DOD run immediately before it. So e.g. the on_free_list flag might not reflect current usage of a buffer.
leo