diff options
author | Paolo Molaro <lupus@oddwiz.org> | 2006-01-24 14:37:10 +0300 |
---|---|---|
committer | Paolo Molaro <lupus@oddwiz.org> | 2006-01-24 14:37:10 +0300 |
commit | d58dfa185af1d48fb93efdef1d046762f214f0a7 (patch) | |
tree | f851d10caf20d342811d58d624fcdcbd92fe4151 /libgc/darwin_stop_world.c | |
parent | 3be1eb27881d243559d4ab0baf7b538334c7e1b3 (diff) |
Tue Jan 24 12:34:06 CET 2006 Paolo Molaro <lupus@ximian.com>
* *: update from upstream changes.
svn path=/trunk/mono/; revision=55979
Diffstat (limited to 'libgc/darwin_stop_world.c')
-rw-r--r-- | libgc/darwin_stop_world.c | 124 |
1 files changed, 109 insertions, 15 deletions
diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index 60acd83c6bd..692b18db4db 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -12,23 +12,33 @@ Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then it must set up a stack frame just like routines that call other routines." */ -#define PPC_RED_ZONE_SIZE 224 +#ifdef POWERPC +# if CPP_WORDSZ == 32 +# define PPC_RED_ZONE_SIZE 224 +# elif CPP_WORDSZ == 64 +# define PPC_RED_ZONE_SIZE 320 +# endif +#endif -/* Not 64-bit clean. Wait until Apple defines their 64-bit ABI */ typedef struct StackFrame { - unsigned int savedSP; - unsigned int savedCR; - unsigned int savedLR; - unsigned int reserved[2]; - unsigned int savedRTOC; + unsigned long savedSP; + unsigned long savedCR; + unsigned long savedLR; + unsigned long reserved[2]; + unsigned long savedRTOC; } StackFrame; - -unsigned int FindTopOfStack(unsigned int stack_start) { +unsigned long FindTopOfStack(unsigned int stack_start) { StackFrame *frame; if (stack_start == 0) { - __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# ifdef POWERPC +# if CPP_WORDSZ == 32 + __asm__ volatile("lwz %0,0(r1)" : "=r" (frame)); +# else + __asm__ volatile("ldz %0,0(r1)" : "=r" (frame)); +# endif +# endif } else { frame = (StackFrame *)stack_start; } @@ -37,7 +47,7 @@ unsigned int FindTopOfStack(unsigned int stack_start) { /* GC_printf1("FindTopOfStack start at sp = %p\n", frame); */ # endif do { - if (frame->savedSP == NULL) break; + if (frame->savedSP == 0) break; /* if there are no more stack frames, stop */ frame = (StackFrame*)frame->savedSP; @@ -53,9 +63,88 @@ unsigned int FindTopOfStack(unsigned int stack_start) { /* GC_printf1("FindTopOfStack finish at sp = %p\n", frame); */ # endif - return (unsigned int)frame; + return (unsigned long)frame; } +#ifdef DARWIN_DONT_PARSE_STACK +void GC_push_all_stacks() { + int i; + kern_return_t r; + GC_thread p; + pthread_t me; + ptr_t lo, hi; + ppc_thread_state_t state; + mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT; + + me = pthread_self(); + if (!GC_thr_initialized) GC_thr_init(); + + for(i=0;i<THREAD_TABLE_SZ;i++) { + for(p=GC_threads[i];p!=0;p=p->next) { + if(p -> flags & FINISHED) continue; + if(pthread_equal(p->id,me)) { + lo = GC_approx_sp(); + } else { + /* Get the thread state (registers, etc) */ + r = thread_get_state( + p->stop_info.mach_thread, + MACHINE_THREAD_STATE, + (natural_t*)&state, + &thread_state_count); + if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); + + lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE); + + GC_push_one(state.r0); + GC_push_one(state.r2); + GC_push_one(state.r3); + GC_push_one(state.r4); + GC_push_one(state.r5); + GC_push_one(state.r6); + GC_push_one(state.r7); + GC_push_one(state.r8); + GC_push_one(state.r9); + GC_push_one(state.r10); + GC_push_one(state.r11); + GC_push_one(state.r12); + GC_push_one(state.r13); + GC_push_one(state.r14); + GC_push_one(state.r15); + GC_push_one(state.r16); + GC_push_one(state.r17); + GC_push_one(state.r18); + GC_push_one(state.r19); + GC_push_one(state.r20); + GC_push_one(state.r21); + GC_push_one(state.r22); + GC_push_one(state.r23); + GC_push_one(state.r24); + GC_push_one(state.r25); + GC_push_one(state.r26); + GC_push_one(state.r27); + GC_push_one(state.r28); + GC_push_one(state.r29); + GC_push_one(state.r30); + GC_push_one(state.r31); + } /* p != me */ + if(p->flags & MAIN_THREAD) + hi = GC_stackbottom; + else + hi = p->stack_end; +#if DEBUG_THREADS + GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n", + (unsigned long) p -> id, + (unsigned long) lo, + (unsigned long) hi + ); +#endif + GC_push_all_stack(lo,hi); + } /* for(p=GC_threads[i]...) */ + } /* for(i=0;i<THREAD_TABLE_SZ...) */ +} + +#else /* !DARWIN_DONT_PARSE_STACK; Use FindTopOfStack() */ + void GC_push_all_stacks() { int i; kern_return_t r; @@ -75,8 +164,12 @@ void GC_push_all_stacks() { lo = GC_approx_sp(); hi = (ptr_t)FindTopOfStack(0); } else { -# ifdef POWERPC +# if defined(POWERPC) +# if CPP_WORDSZ == 32 ppc_thread_state_t info; +# else + ppc_thread_state64_t info; +# endif mach_msg_type_number_t outCount = THREAD_STATE_MAX; r = thread_get_state(thread, MACHINE_THREAD_STATE, (natural_t *)&info, &outCount); @@ -156,6 +249,7 @@ void GC_push_all_stacks() { } /* for(p=GC_threads[i]...) */ vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); } +#endif /* !DARWIN_DONT_PARSE_STACK */ static mach_port_t GC_mach_handler_thread; static int GC_use_mach_handler_thread = 0; @@ -326,6 +420,8 @@ void GC_start_world() kern_return_t kern_result; thread_act_array_t act_list; mach_msg_type_number_t listcount; + struct thread_basic_info info; + mach_msg_type_number_t outCount = THREAD_INFO_MAX; # if DEBUG_THREADS GC_printf0("World starting\n"); @@ -352,8 +448,6 @@ void GC_start_world() # endif continue; } - struct thread_basic_info info; - mach_msg_type_number_t outCount = THREAD_INFO_MAX; kern_result = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &outCount); if(kern_result != KERN_SUCCESS) continue; |