From e5321a993a768ba78edc2fd39387edb360480c83 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 10 Sep 2019 11:09:42 +0300 Subject: [PATCH] Replace push_one calls with push_many_regs one for Win32 thread context (code refactoring) Also, do not define GC_push_one except for Darwin (and some ancient targets that use the function). * include/private/gc_priv.h [MSWIN32 || MSWINCE] (GC_push_one): Do not declare. * include/private/gc_priv.h [!MSWIN32 && !MSWINCE] (GC_push_one): Declare only if AMIGA or MACOS or GC_DARWIN_THREADS. * include/private/gc_priv.h [GC_WIN32_THREADS] (GC_push_many_regs): Declare function; add comment. * mark.c (GC_push_one): Define only if AMIGA or MACOS or GC_DARWIN_THREADS. * mark.c [GC_WIN32_THREADS] (GC_push_many_regs): New GC_INNER function. * win32_threads.c (GC_push_stack_for): Remove i local variable; call GC_push_many_regs() instead of a loop with GC_push_one() calls (ignore 2 first registers if WOW64_THREAD_CONTEXT_WORKAROUND). --- include/private/gc_priv.h | 11 +++++++---- mark.c | 19 +++++++++++++------ win32_threads.c | 12 +++++------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 1124a80..ef81ae6 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1766,11 +1766,9 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), /* pointer to the top of the corresponding memory stack. */ ptr_t GC_save_regs_in_stack(void); #endif - /* Push register contents onto mark stack. */ -#if defined(MSWIN32) || defined(MSWINCE) - void __cdecl GC_push_one(word p); -#else + /* Push register contents onto mark stack. */ +#if defined(AMIGA) || defined(MACOS) || defined(GC_DARWIN_THREADS) void GC_push_one(word p); /* If p points to an object, mark it */ /* and push contents on the mark stack */ @@ -1780,6 +1778,11 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), /* stack. */ #endif +#ifdef GC_WIN32_THREADS + /* Same as GC_push_one but for a sequence of registers. */ + GC_INNER void GC_push_many_regs(const word *regs, unsigned count); +#endif + #if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) GC_INNER void GC_mark_and_push_stack(ptr_t p, ptr_t source); /* Ditto, omits plausibility test */ diff --git a/mark.c b/mark.c index 8cd13f5..4d702a9 100644 --- a/mark.c +++ b/mark.c @@ -1428,14 +1428,21 @@ GC_API void GC_CALL GC_push_all(void *bottom, void *top) } #endif /* GC_DISABLE_INCREMENTAL */ -#if defined(MSWIN32) || defined(MSWINCE) - void __cdecl GC_push_one(word p) -#else +#if defined(AMIGA) || defined(MACOS) || defined(GC_DARWIN_THREADS) void GC_push_one(word p) -#endif -{ + { GC_PUSH_ONE_STACK(p, MARKED_FROM_REGISTER); -} + } +#endif + +#ifdef GC_WIN32_THREADS + GC_INNER void GC_push_many_regs(const word *regs, unsigned count) + { + unsigned i; + for (i = 0; i < count; i++) + GC_PUSH_ONE_STACK(regs[i], MARKED_FROM_REGISTER); + } +#endif GC_API struct GC_ms_entry * GC_CALL GC_mark_and_push(void *obj, mse *mark_stack_ptr, diff --git a/win32_threads.c b/win32_threads.c index 10bf651..5a35e70 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -1585,7 +1585,6 @@ STATIC word GC_push_stack_for(GC_thread thread, DWORD me) sp = GC_approx_sp(); } else if ((sp = thread -> thread_blocked_sp) == NULL) { /* Use saved sp value for blocked threads. */ - int i = 0; # ifdef RETRY_GET_THREAD_CONTEXT /* We cache context when suspending the thread since it may */ /* require looping. */ @@ -1605,13 +1604,12 @@ STATIC word GC_push_stack_for(GC_thread thread, DWORD me) } # endif -# ifdef WOW64_THREAD_CONTEXT_WORKAROUND - i += 2; /* skip ContextFlags and SegFs */ -# endif - for (; i < PUSHED_REGS_COUNT; i++) - GC_push_one(regs[i]); +# ifndef WOW64_THREAD_CONTEXT_WORKAROUND + GC_push_many_regs(regs, PUSHED_REGS_COUNT); +# else + GC_push_many_regs(regs + 2, PUSHED_REGS_COUNT - 2); + /* skip ContextFlags and SegFs */ -# ifdef WOW64_THREAD_CONTEXT_WORKAROUND /* WoW64 workaround. */ if (isWow64) { DWORD ContextFlags = (DWORD)regs[0]; -- 2.7.4