Leopold Toetsch wrote:

>> ... Perhaps you should save your (metaphorical) breath, and I'll
>> wait for a more detailed design.
>
>
> I'm waiting too :-)

Hi,
I believe I found a good workaround for the cycle problems. It is a
little bit slower and worst case (which never occurs, happily) is
|IGP_set| passes, but should really be about 2 passes. But we need of
course not to run it each time. We can have 'classical' gmc most of the
time and once in a while, run NLDC (Night of the Living Dead Collection)
to get rid of evil IGP dead cycles.

Here is how NLDC works :

We do not care at all about generations. First, make a normal marking
pass, but without even considering the IGP set at all. Just see members
of the IGP set (origin and destination of the pointer) as normal objects.
Then, operation "Night of the Living Dead" begins (hence the name) : get
out of their graves objects that shouldn't have been buried first. Run
through the IGP set in reverse order of age of origin pointers. For each
(p0 -> p1) element in the IGP, do the following : if p0 is marked dead,
then do nothing and leave it dead. If it is marked alive, apply a
recursive procedure :

to_process := [p1];
while (to_process != []) {
p = pop (to_process);
if (p is dead) {
mark p alive;
forall (p -> q) in IGP { push (q, to_process) }
push (all childrens of p, to_process);
}
}

And then proceed with compaction as usual. This ensures us that dead
cycles have been destroyed and that every alive object has been marked so.

Here is how it works. Consider a dead cycle :

[A] --> [B] --> [C]
^ |
+--------------------+

In the first run, the C->A link does not exist. Thus, as A, B and C are
not referenced from elsewhere, they are all marked dead. And in NLD
pass, C being dead, no object of the cycle comes back to life and it can
safely go to hell.

If now, for instance B is referenced from the vast outer world, A is
dead but B and C as marked alive after the first pass. Thus C is marked
alive and we apply the recursive function that just rescues A.

Some cases are just a little trickier :

For instance :

|
v
[A] --> [B] --> [C]
^ |
| +---+
| v
| [D] --> [E] --> [F]
| |
+----------------------------------------+


We have C->D and F->A in the IGP set, and B is referenced from the outer
world. Thus, the whole cycle is alive.
After the first pass, only B and C are marked alive. In NLD pass, we
first check F and find it dead, thus do nothing. Next is C, which is
alive. And, thanks to the "forall (p->q) in IGP...", we add D to the
living, and then the whole cycle.

I discussed it with friends and think it can even be proved to work
right (but that would take some time :/).

Does that sound reasonable to you ?

Regards,
Alexandre

Reply via email to