- /*
- * Concurrent mark never follows references into the nursery. In the start and
- * finish pauses we must scan live nursery objects, though.
- *
- * In the finish pause we do this conservatively by scanning all nursery objects.
- * Previously we would only scan pinned objects here. We assumed that all objects
- * that were pinned during the nursery collection immediately preceding this finish
- * mark would be pinned again here. Due to the way we get the stack end for the GC
- * thread, however, that's not necessarily the case: we scan part of the stack used
- * by the GC itself, which changes constantly, so pinning isn't entirely
- * deterministic.
- *
- * The split nursery also complicates things because non-pinned objects can survive
- * in the nursery. That's why we need to do a full scan of the nursery for it, too.
- *
- * In the future we shouldn't do a preceding nursery collection at all and instead
- * do the finish pause with promotion from the nursery.
- *
- * A further complication arises when we have late-pinned objects from the preceding
- * nursery collection. Those are the result of being out of memory when trying to
- * evacuate objects. They won't be found from the roots, so we just scan the whole
- * nursery.
- *
- * Non-concurrent mark evacuates from the nursery, so it's
- * sufficient to just scan pinned nursery objects.
- */
- if (scan_whole_nursery || mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT || (concurrent && sgen_minor_collector.is_split)) {
- scan_nursery_objects (ctx);
- } else {
- pin_objects_in_nursery (concurrent, ctx);
- if (check_nursery_objects_pinned && !sgen_minor_collector.is_split)
- sgen_check_nursery_objects_pinned (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
- }