Fix incorrect code generation by MS VC caused by excessive Thread_Rep size
(fix of commit
449eda034)
The gctest crashes were observed in debug builds produced by MS VC.
In addition, this change greatly reduces memory usage by GC_threads[]
and dll_thread_table[] (compared to the solution that stores the full
CONTEXT in GC_Thread_Rep).
* win32_threads.c (copy_ptr_regs): Declare static function.
* win32_threads.c (PUSHED_REGS_COUNT): Define macro.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT]
(GC_Thread_Rep.saved_context): Move down to be the last field; change
type from CONTEXT to word[PUSHED_REGS_COUNT]; rename to context_regs.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT]
(GC_Thread_Rep.context_sp): New field.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_suspend): Declare
context local variable and use it for GetThreadContext() call; if the
latter succeeds then call copy_ptr_regs(); update comment.
* win32_threads.c (copy_ptr_regs): Define static function (move
PUSH-related part of GC_push_stack_for code here); change PUSH1(reg) to
store reg to regs[]; define context as *pcontext; add assertion that
number of stored registers is equal to PUSHED_REGS_COUNT.
* win32_threads.c [WOW64_THREAD_CONTEXT_WORKAROUND] (copy_ptr_regs):
Store ContextFlags and SegFs as the first elements of regs[].
* win32_threads.c (GC_push_stack_for): Declare i local variable (set
to 0).
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_push_stack_for):
Replace pcontext and context with word *regs; set sp from
thread->context_sp; remove undef context.
* win32_threads.c [!RETRY_GET_THREAD_CONTEXT] (GC_push_stack_for):
Declare regs[PUSHED_REGS_COUNT]; call copy_ptr_regs() to initialize
regs[] and sp; limit context scope to GetThreadContext() and
copy_ptr_regs() calls only.
* win32_threads.c (GC_push_stack_for): Call GC_push_one() for each
regs[] element (except for the first 2 ones if
WOW64_THREAD_CONTEXT_WORKAROUND).
* win32_threads.c [WOW64_THREAD_CONTEXT_WORKAROUND]
(GC_push_stack_for): Define ContextFlags, SegFs local variables
(the values are obtained from regs[]); use these variables instead of
context one; do not overwrite sp local variable value so that not to
use context.Esp directly (i.e. not to use context out of its scope).