Skip to content

First stab at having the GC scan the shadow stack.#5

Merged
ltratt merged 1 commit intoykjit:masterfrom
vext01:shadowgc
Mar 13, 2026
Merged

First stab at having the GC scan the shadow stack.#5
ltratt merged 1 commit intoykjit:masterfrom
vext01:shadowgc

Conversation

@vext01
Copy link

@vext01 vext01 commented Mar 13, 2026

This comes with the caveat that each thread scans all other threads shadow stacks, which may not be completely safe(?)

With this, and recent ykllvm/yk changes, this mandelbrot benchmark now runs:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/fannkuchredux-python3-6.html

(If you run with YKD_SERIALISE_COMPILATION=1 however, I get an unimplemented ptrtoint constant expression -- this isn't hard to implement)

This comes with the caveat that each thread scans all other threads
shadow stacks, which may not be completely safe(?).

With this, and recent ykllvm/yk changes, this mandelbrot benchmark now
runs:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/fannkuchredux-python3-6.html

(If you run with YKD_SERIALISE_COMPILATION=1 however, I get an
unimplemented ptrtoint constant expression -- this isn't hard to
implement)
@vext01
Copy link
Author

vext01 commented Mar 13, 2026

There's a part of the code where micropython signals another thread (literally a UNIX signal) to scan it's own stack, so we might take that as a cue to do this properly? Not sure.

@ltratt
Copy link

ltratt commented Mar 13, 2026

Scanning other threads' stacks isn't safe in general, but it's fine for now. I think we should undraft this and get it in.

@vext01
Copy link
Author

vext01 commented Mar 13, 2026

FWIW, here's the code I was referencing:

// This function scans all pointers that are external to the current thread.
// It does this by signalling all other threads and getting them to scan their
// own registers and stack. Note that there may still be some edge cases left
// with race conditions and root-pointer scanning: a given thread may manipulate
// the global root pointers (in mp_state_ctx) while another thread is doing a
// garbage collection and tracing these pointers.
void mp_thread_gc_others(void) {
mp_thread_unix_begin_atomic_section();
for (mp_thread_t *th = thread; th != NULL; th = th->next) {
gc_collect_root(&th->arg, 1);
if (th->id == pthread_self()) {
continue;
}
if (!th->ready) {
continue;
}
pthread_kill(th->id, MP_THREAD_GC_SIGNAL);
#if defined(__APPLE__)
sem_wait(thread_signal_done_p);
#else
sem_wait(&thread_signal_done);
#endif
}
mp_thread_unix_end_atomic_section();
}

@vext01 vext01 marked this pull request as ready for review March 13, 2026 12:13
@ltratt
Copy link

ltratt commented Mar 13, 2026

I'm assuming this is probably a stop-the-world GC, so this should be simple, especially given that code segment. But we can finesse this next week.

@vext01
Copy link
Author

vext01 commented Mar 13, 2026

I think we just need a yk API to get the current thread's shadow stack memory range.

At the moment we can only get all threads shadow stacks.

But I'm not a GC guy :)

@vext01
Copy link
Author

vext01 commented Mar 13, 2026

Anyway, undrafted

@ltratt ltratt added this pull request to the merge queue Mar 13, 2026
Merged via the queue into ykjit:master with commit a33b9d6 Mar 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants