Prevent use of unsaved thread context registers in incremental GC (Windows)
(fix of commits
449eda034,
190e18c75)
During incremental collection GC_push_all_stacks() may be called when
the world is not stopped. If the context registers and sp value are
saved during thread suspension then GC_push_all_stacks() gets these
values of the previous GC cycle or, even, gets all zeros instead the
context registers and sp on the first GC after the thread creation.
This commit fixes this by calling GetThreadContext in GC_push_stack_for
if thread is not suspended.
* win32_threads.c (first_thread): Refine the comment.
* win32_threads.c [!GC_NO_THREADS_DISCOVERY && RETRY_GET_THREAD_CONTEXT]
(GC_delete_gc_thread_no_free): Reset context_sp if GC_win32_dll_threads.
* win32_threads.c (GC_push_stack_for): Change the assertion expression
from thread->suspended to thread->suspended||!GC_world_stopped (the
assertion is off unless THREAD_LOCAL_ALLOC).
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_push_stack_for): If
thread is not suspended then call GetThreadContext(), if it fails then
use sp value and the context registers saved during the latest
stop-the-world; add comments.
* win32_threads.c (GC_push_all_stacks): Add the title comment (copied
from pthread_stop_world.c).