Eliot, i need your help to synthesize tests which test that if stack pages are reachable only from ephemeron(s), then it handled correctly.
I did a following change in #markPhase: (after marking all roots)
... blah blah ...
"Only safe to free stack pages after all roots have been traced." self markAndTraceAndMaybeFreeStackPages: fullGCFlag.
"the above was in original code, and i also added following: "
"Process ephemerons" [ self processEphemeronsQueue ] whileTrue: [ "some stack pages may be reachable only through ephemerons" self markAndTraceAndMaybeFreeStackPages: fullGCFlag. ].
There could be a potential problem, if some stack page are reachable from ephemeron only, because i'm not sure how #markAndTraceAndMaybeFreeStackPages: works.
The situation could be following:
(roots) ->..-> ephemeron 2 (roots) ->..-> ephemeron 1 ephemeron 1 (value) ->..-> ephemeron 2 key ephemeron2 -> (value) ->..-> stack page
so, here is step-by-step explanation, which could lead to problem(s):
1. GC found ephemeron 2. But its key not yet marked, since the only reference to it is visible from ephemeron 1. Therefore ephemeron 2 are put into queue.
2. GC found ephemeron 1, and lets assume that its key already marked, so we don't put it into a queue but continue with tracing its value (strongly). As result of tracing, now ephemeron's 2 key will be marked as reachable.
3. we done with initial mark stage. Now going to call initial #markAndTraceAndMaybeFreeStackPages:
4. we start analyzing the queue. And since at this stage ephemeron's 2 key is already marked, so we proceed with tracing its value, which makes some more stack page marked as reachable.
5. we tracing the left stack pages which possibly discovered once ephemeron's 2 value is traced.
So, my doubts are at step 3. If #markAndTraceAndMaybeFreeStackPages doesn't works as i expecting, it could presume that some stack pages are not accessible and prematurely free them, before processing ephemeron's queue which discovering some extra live stack pages.