From 6bbe4eb030b40036a75aa952971c84bdd7019112 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Mon, 21 Oct 2024 20:05:51 +0300 Subject: [PATCH] Do not use address of a local variable to get approximate stack pointer Use __builtin_frame_address(0), if available, in GC_call_with_stack_base(), GC_call_with_gc_active() and GC_do_blocking_inner(). * misc.c (GC_call_with_stack_base): Use APPROX_SP() to set base.mem_base. * misc.c [!THREADS] (GC_call_with_gc_active): Use APPROX_SP(&stacksect.saved_stack_ptr) instead of &stacksect; update comment. * pthread_support.c (GC_call_with_gc_active): Likewise. * misc.c [!THREADS] (GC_do_blocking_inner): Remove d local variable. * pthread_support.c (GC_do_blocking_inner): Likewise. * misc.c [!THREADS && !SPARC] (GC_do_blocking_inner): Use GC_approx_sp() instead of &d to set GC_blocked_sp; remove useless comment; do not compare GC_blocked_sp to &d in assertion. * pthread_support.c [GC_PTHREADS && !SN_TARGET_ORBIS && !SN_TARGET_PSP2 && DEBUG_THREADS] (GC_start_rtn_prepare_thread): Use GC_approx_sp() instead of &arg. --- misc.c | 22 +++++++++------------- pthread_support.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/misc.c b/misc.c index 86ec926c1..b859f43a8 100644 --- a/misc.c +++ b/misc.c @@ -2396,7 +2396,7 @@ GC_call_with_stack_base(GC_stack_base_func fn, void *arg) struct GC_stack_base base; void *result; - base.mem_base = &base; + APPROX_SP((volatile ptr_t *)&base.mem_base); #ifdef IA64 base.reg_base = GC_save_regs_in_stack(); /* TODO: Unnecessarily flushes register stack, */ @@ -2437,9 +2437,10 @@ GC_call_with_gc_active(GC_fn_type fn, void *client_data) /* Adjust our stack bottom pointer (this could happen if */ /* GC_get_main_stack_base() is unimplemented or broken for */ - /* the platform). */ - if (HOTTER_THAN(GC_stackbottom, (ptr_t)(&stacksect))) - GC_stackbottom = COVERT_DATAFLOW_P(&stacksect); + /* the platform). Note: stacksect variable is reused here. */ + APPROX_SP((volatile ptr_t *)&stacksect.saved_stack_ptr); + if (HOTTER_THAN(GC_stackbottom, stacksect.saved_stack_ptr)) + GC_stackbottom = stacksect.saved_stack_ptr; if (GC_blocked_sp == NULL) { /* We are not inside GC_do_blocking() - do nothing more. */ @@ -2484,28 +2485,23 @@ GC_call_with_gc_active(GC_fn_type fn, void *client_data) STATIC void GC_do_blocking_inner(ptr_t data, void *context) { - struct blocking_data *d = (struct blocking_data *)data; - UNUSED_ARG(context); GC_ASSERT(GC_is_initialized); GC_ASSERT(GC_blocked_sp == NULL); # ifdef SPARC GC_blocked_sp = GC_save_regs_in_stack(); # else - /* Save the approximate stack pointer. */ - GC_blocked_sp = (ptr_t)&d; + GC_blocked_sp = GC_approx_sp(); # ifdef IA64 GC_blocked_register_sp = GC_save_regs_in_stack(); # endif # endif - d->client_data = d->fn(d->client_data); + ((struct blocking_data *)data)->client_data /* result */ + = ((struct blocking_data *)data) + ->fn(((struct blocking_data *)data)->client_data); -# ifdef SPARC GC_ASSERT(GC_blocked_sp != NULL); -# else - GC_ASSERT(GC_blocked_sp == (ptr_t)(&d)); -# endif # if defined(CPPCHECK) GC_noop1_ptr(GC_blocked_sp); # endif diff --git a/pthread_support.c b/pthread_support.c index 1c31320a8..325f7cf1b 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -2000,7 +2000,6 @@ do_blocking_leave(GC_thread me, GC_bool topOfStackUnset) GC_INNER void GC_do_blocking_inner(ptr_t data, void *context) { - struct blocking_data *d = (struct blocking_data *)data; GC_thread me; GC_bool topOfStackUnset; @@ -2010,7 +2009,9 @@ GC_do_blocking_inner(ptr_t data, void *context) do_blocking_enter(&topOfStackUnset, me); READER_UNLOCK_RELEASE(); - d->client_data = d->fn(d->client_data); + ((struct blocking_data *)data)->client_data /* result */ + = ((struct blocking_data *)data) + ->fn(((struct blocking_data *)data)->client_data); /* This will block if the world is stopped. */ READER_LOCK(); @@ -2162,10 +2163,11 @@ GC_call_with_gc_active(GC_fn_type fn, void *client_data) /* GC_get_stack_base() was used which returned GC_SUCCESS). */ stack_end = crtn->stack_end; /* read of a volatile field */ GC_ASSERT(stack_end != NULL); - if (HOTTER_THAN(stack_end, (ptr_t)(&stacksect))) { - crtn->stack_end = (ptr_t)(&stacksect); + APPROX_SP((volatile ptr_t *)&stacksect.saved_stack_ptr); + if (HOTTER_THAN(stack_end, stacksect.saved_stack_ptr)) { + crtn->stack_end = stacksect.saved_stack_ptr; # if defined(I386) && defined(GC_WIN32_THREADS) - crtn->initial_stack_base = (ptr_t)(&stacksect); + crtn->initial_stack_base = stacksect.saved_stack_ptr; # endif } @@ -2595,7 +2597,8 @@ GC_start_rtn_prepare_thread(void *(**pstart)(void *), void **pstart_arg, # ifdef DEBUG_THREADS GC_log_printf("Starting thread %p, sp= %p\n", - (void *)GC_PTHREAD_PTRVAL(pthread_self()), (void *)&arg); + (void *)GC_PTHREAD_PTRVAL(pthread_self()), + (void *)GC_approx_sp()); # endif /* If a GC occurs before the thread is registered, that GC will */ /* ignore this thread. That's fine, since it will block trying to */