Ok, this thread has now +45 entries, I'll try to summarize the proposed PMC traversal schemes.
0) As the subject still applies ;-) we want to be able to dump() or pretty_print() a PMC (and possibly aggregate members of that). This turns out to be a special case of a deep traversal over nested PMCs of any kind, which might contain self-references and the like. 1) There are more such traverse-like operations namely DOD, clone(), freeze(). thaw() is different, as we run over the frozen byte-stream and regenerate the PMC structures from that. 2) Proposals for DOD, freeze(), clone(), dump() 2a) Implement clone() & dump() on top of freeze(): clone=freeze+thaw, dump() is generated in the debugger sub-system 2b) A general traverse() vtable that calls freeze/clone/dump-vtables. DOD is a separate traversal (mark).[1] 2c) A more general traverse(), which is our current DOD mark() functionality using next_for_GC.[2] Comparison 2a 2b 2c -------------------------------------------------------------------- clone needs intermediate frozen string[3] yes - - clone involves 2 steps yes - - dump has to know PMCs internals[4] yes - - duplicates recognition overhead Hash Hash - Traversals per aggregate for clone/freeze[5] 1 1 3 Thread-safe[6] yes yes - Increases PMC size[7] - - yes Adds complexity to DOD[8] - - yes Cache friendly[9] - yes - Code duplication[10] - - yes [1] I consider Benjamin's proposal as some generalization of this for now and a mixture of 2a) and 2b) (clone=freeze/thaw). [2] mark() as of Parrot 0.0.6, each PMC gets on the next_for_GC list [3] e.g. for clone(Array[10000]) the intermediate frozen image is first generated in memory, then scanned again during thaw(). [4] what about dynamically loaded PMCs? [5] 2c): 1. mark() per PMC, 2. clone() or freeze(), 3. clear next_for_GC. mark is called inside clone/freeze again, which additonally kills data cache coherency. [6] While all schemes aren't thread-safe from user level (e.g. manually sorting an array containing shared PMCs, while it gets frozen), 2c) isn't thread-safe at low-level, as the next_for_GC pointer inside the PMC is used as a duplicate marker. But if a user changes shared resources its a user problem. We only guarantee atomic updates per PMC (s. P6E p 86f by Dan). [7] next_for_GC (and others like poperties) are in the PMC_EXT structure now. Plain PMC scalars don't contain other PMCs, so the can be marked life directly by setting just their live_flag. [8] Additionally DOD has some shortcuts for marking e.g. a PMC pointing to another or to an array of PMCs. [9] 2a): The intermediate frozen image for clone() 2c): 3 passes over aggregates; each PMC gets pulled in during DOD [10] 2a): mark + freeze 2b): mark + traverse 2c): all traverse functions duplicated This is of course my personal POV. If anything is wrong above please correct me as well as WRT missing issues. My major concerns are regarding footnotes [3], [5], [7], [8], and [9]. These haven't been commented/answered yet at all. Thanks for reading til here ;-) leo leo