Skip to content

Commit

Permalink
Do not use address of a local variable to get approximate stack pointer
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ivmai committed Oct 21, 2024
1 parent 0fb49af commit 6bbe4eb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 19 deletions.
22 changes: 9 additions & 13 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, */
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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
Expand Down
15 changes: 9 additions & 6 deletions pthread_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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();
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 6bbe4eb

Please sign in to comment.