From 24b29a7e89dc3b25b4d6933b7aaf49acf19c71a4 Mon Sep 17 00:00:00 2001 From: ivmai Date: Wed, 6 Oct 2010 20:09:27 +0000 Subject: 2010-10-06 Ivan Maidanski * darwin_stop_world.c (FindTopOfStack): Change return type to ptr_t (from long); make GC_INNER; add GC_ prefix. * darwin_stop_world.c (GC_push_all_stacks): Add thread_blocked local variable (initialized from the corresponding GC_thread field unless GC_query_task_threads); add assertion that our thread is not blocked; prefix FindTopOfStack with GC_ and remove no longer needed cast to ptr_t of the result; handle thread blocked case (and remove FIXME); use GC_push_all_stack_sections unless GC_query_task_threads (and remove FIXME). * pthread_support.c (GC_FindTopOfStack): Declare (if needed). * pthread_support.c (GC_do_blocking_inner): Call GC_save_regs_in_stack (if needed) before acquiring the lock. * win32_threads.c (GC_do_blocking_inner): Ditto. * pthread_support.c (GC_do_blocking_inner): Set/clear topOfStack field of GC_thread (Darwin only). * include/private/pthread_support.h (GC_thread): Add topOfStack field for Darwin (unless DARWIN_DONT_PARSE_STACK). --- darwin_stop_world.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'darwin_stop_world.c') diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 3874d37b..533ea76e 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -49,9 +49,9 @@ typedef struct StackFrame { unsigned long savedRTOC; } StackFrame; -static unsigned long FindTopOfStack(unsigned long stack_start) +GC_INNER ptr_t GC_FindTopOfStack(unsigned long stack_start) { - StackFrame *frame; + StackFrame *frame; if (stack_start == 0) { # ifdef POWERPC @@ -82,7 +82,7 @@ static unsigned long FindTopOfStack(unsigned long stack_start) # ifdef DEBUG_THREADS /* GC_printf("FindTopOfStack finish at sp = %p\n", frame); */ # endif - return (unsigned long)frame; + return (ptr_t)frame; } #endif /* !DARWIN_DONT_PARSE_STACK */ @@ -122,28 +122,36 @@ GC_INNER void GC_push_all_stacks(void) } for (i = 0; i < (int)listcount; i++) { - GC_thread p = GC_query_task_threads ? 0 : GC_threads[i]; + GC_thread p = GC_query_task_threads ? NULL : GC_threads[i]; for (;; p = p->next) { thread_act_t thread; + GC_bool thread_blocked; if (GC_query_task_threads) { thread = act_list[i]; + thread_blocked = FALSE; } else { - if (p == 0) break; + if (p == NULL) break; if (p->flags & FINISHED) continue; thread = p->stop_info.mach_thread; + thread_blocked = (GC_bool)p->thread_blocked; } nthreads++; if (thread == me) { - /* FIXME: check thread not blocked */ + GC_ASSERT(!thread_blocked); lo = GC_approx_sp(); # ifndef DARWIN_DONT_PARSE_STACK - hi = (ptr_t)FindTopOfStack(0); + hi = GC_FindTopOfStack(0); # endif found_me = TRUE; - } else { - /* FIXME: if blocked then use stop_info.stack_ptr for lo */ + } else if (thread_blocked) { + lo = p->stop_info.stack_ptr; +# ifndef DARWIN_DONT_PARSE_STACK + hi = p->topOfStack; +# endif + + } else { /* MACHINE_THREAD_STATE_COUNT does not seem to be defined */ /* everywhere. Hence we use our own version. Alternatively, */ /* we could use THREAD_STATE_MAX (but seems to be not optimal). */ @@ -162,7 +170,7 @@ GC_INNER void GC_push_all_stacks(void) # if defined(I386) lo = (void *)state.THREAD_FLD(esp); # ifndef DARWIN_DONT_PARSE_STACK - hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(esp)); + hi = GC_FindTopOfStack(state.THREAD_FLD(esp)); # endif GC_push_one(state.THREAD_FLD(eax)); GC_push_one(state.THREAD_FLD(ebx)); @@ -175,7 +183,7 @@ GC_INNER void GC_push_all_stacks(void) # elif defined(X86_64) lo = (void *)state.THREAD_FLD(rsp); # ifndef DARWIN_DONT_PARSE_STACK - hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(rsp)); + hi = GC_FindTopOfStack(state.THREAD_FLD(rsp)); # endif GC_push_one(state.THREAD_FLD(rax)); GC_push_one(state.THREAD_FLD(rbx)); @@ -197,7 +205,7 @@ GC_INNER void GC_push_all_stacks(void) # elif defined(POWERPC) lo = (void *)(state.THREAD_FLD(r1) - PPC_RED_ZONE_SIZE); # ifndef DARWIN_DONT_PARSE_STACK - hi = (ptr_t)FindTopOfStack(state.THREAD_FLD(r1)); + hi = GC_FindTopOfStack(state.THREAD_FLD(r1)); # endif GC_push_one(state.THREAD_FLD(r0)); GC_push_one(state.THREAD_FLD(r2)); @@ -234,7 +242,7 @@ GC_INNER void GC_push_all_stacks(void) # elif defined(ARM32) lo = (void *)state.__sp; # ifndef DARWIN_DONT_PARSE_STACK - hi = (ptr_t)FindTopOfStack(state.__sp); + hi = GC_FindTopOfStack(state.__sp); # endif GC_push_one(state.__r[0]); GC_push_one(state.__r[1]); @@ -258,20 +266,22 @@ GC_INNER void GC_push_all_stacks(void) # error FIXME for non-x86 || ppc || arm architectures # endif } /* thread != me */ + # ifdef DARWIN_DONT_PARSE_STACK + /* p is non-NULL since GC_query_task_threads is FALSE */ hi = (p->flags & MAIN_THREAD) != 0 ? GC_stackbottom : p->stack_end; # endif # ifdef DEBUG_THREADS GC_printf("Darwin: Stack for thread 0x%lx = [%p,%p)\n", (unsigned long) thread, lo, hi); # endif - /* FIXME: use GC_push_all_stack_sections */ - GC_push_all_stack(lo, hi); total_size += hi - lo; /* lo <= hi */ if (GC_query_task_threads) { + GC_push_all_stack(lo, hi); mach_port_deallocate(my_task, thread); break; } + GC_push_all_stack_sections(lo, hi, p->traced_stack_sect); } /* for (p) */ } /* for (i=0; ...) */ -- cgit v1.2.1