void gcProcessStacks()

in libs/core/codal.cpp [275:328]


void gcProcessStacks(int flags) {
    // check scheduler is initialized
    if (!currentFiber) {
        // make sure we allocate something to at least initalize the memory allocator
        void *volatile p = xmalloc(1);
        xfree(p);
        return;
    }

#ifdef MICROBIT_GET_FIBER_LIST_SUPPORTED
    for (Fiber *fib = get_fiber_list(); fib; fib = fib->next) {
        auto ctx = (ThreadContext *)fib->user_data;
        if (!ctx)
            continue;
        for (auto seg = &ctx->stack; seg; seg = seg->next) {
            auto ptr = (TValue *)threadAddressFor(fib, seg->top);
            auto end = (TValue *)threadAddressFor(fib, seg->bottom);
            if (flags & 2)
                DMESG("RS%d:%p/%d", cnt++, ptr, end - ptr);
            // VLOG("mark: %p - %p", ptr, end);
            while (ptr < end) {
                gcProcess(*ptr++);
            }
        }
    }
#else
    int numFibers = list_fibers(NULL);
    Fiber **fibers = (Fiber **)xmalloc(sizeof(Fiber *) * numFibers);
    int num2 = list_fibers(fibers);
    if (numFibers != num2)
        oops(12);
    int cnt = 0;

    for (int i = 0; i < numFibers; ++i) {
        auto fib = fibers[i];
        auto ctx = (ThreadContext *)fib->user_data;
        if (!ctx)
            continue;
        for (auto seg = &ctx->stack; seg; seg = seg->next) {
            auto ptr = (TValue *)threadAddressFor(fib, seg->top);
            auto end = (TValue *)threadAddressFor(fib, seg->bottom);
            if (flags & 2) {
                DMESG("RS%d:%p/%d", cnt, ptr, end - ptr);
                cnt++;
            }
            // VLOG("mark: %p - %p", ptr, end);
            while (ptr < end) {
                gcProcess(*ptr++);
            }
        }
    }
    xfree(fibers);
#endif
}